greendev
Loading

D3 Javascript Debt Dashboard

Scenario: Customer does not want to open Excel on a laptop in order to see daily metrics regarding debt. Current setup required an analyst to run a sql code, refresh an Excel workbook and upload to SharePoint. Solution: I built a Javascript Dashboard. Everyday a csv was uploaded to a folder in which the D3 plugin for Javascript where a series of functions affect the asynchronous load of the CSV to display the data in their relevant pots with relevant colouring etc. Result: Customers using a mobile phone or tablet in meetings could view metrics on a specific intranet page.

var title = window.document.querySelectorAll('.metric_title');
var current_week_metric = window.document.querySelectorAll('.main_metric');
var target = window.document.querySelectorAll('.target_metric');
var lw_metric = window.document.querySelectorAll('.last_week_metric');
var colour_tag = window.document.querySelectorAll('#mainrect');
var tile_color = window.document.querySelectorAll('.tile')
var x = 0


d3.csv('data/debt_res_dashboard_data.csv', function(rows) {
    doSomethingWithRows(rows);

});

function doSomethingWithRows(rows) {

    title[x].textContent = rows.MEASURE;

    d3.select(title[x]).call(wrap);

    if (rows.TYPE == 'Value') {

        current_week_metric[x].textContent = rows.LATEST;
        target[x].textContent = rows.TARGET;
        lw_metric[x].textContent = rows.PREV;

    } else if (rows.TYPE == 'Percentage') {

        current_week_metric[x].textContent = Math.round((Number(rows.LATEST) * 100) * 10) / 10 + '%';
        target[x].textContent = Math.round((Number(rows.TARGET) * 100) * 10) / 10 + '%';
        lw_metric[x].textContent = Math.round((Number(rows.PREV) * 100) * 10) / 10 + '%';


    } else {

        current_week_metric[x].textContent = '£' + Math.round(Number(rows.LATEST)).toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,').replace(/\.00$/, '');
        target[x].textContent = '£' + Math.round(Number(rows.TARGET)).toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,').replace(/\.00$/, '');
        lw_metric[x].textContent = '£' + Math.round(Number(rows.PREV)).toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,').replace(/\.00$/, '');

    }




    //add colour tags

    // console.log(colour_tag[x])
    if (rows.FRAMEWORK_GROUP == 1) {

        colour_tag[x].classList.add('debt_per'); //className += "debt_per";
        tile_color[x + 1].style.backgroundColor = '#3acde1';


    } else if (rows.FRAMEWORK_GROUP == 2) {

        colour_tag[x].classList.add('cust_sat'); //.className += 'cust_sat';
        tile_color[x + 1].style.backgroundColor = '#3497fc';

    } else if (rows.FRAMEWORK_GROUP == 3) {

        colour_tag[x].classList.add('serv_ex'); //.className += 'serv_ex';
        tile_color[x + 1].style.backgroundColor = '#f74a85';

    } else {
        colour_tag[x].classList.add('work_stat'); //.className += 'work_stat';
        tile_color[x + 1].style.backgroundColor = '#fcc440';
    }



    //  console.log(rows);

    x = x + 1;

}



function wrap(text) {
    text.each(function() {
        var text = d3.select(this);
        var words = text.text().split(/\s+/).reverse();

        var lineHeight = 20;
        var width = parseFloat(text.attr('width'));
        var y = parseFloat(text.attr('y'));
        var x = text.attr('x');
        var anchor = text.attr('text-anchor');

        var tspan = text.text(null).append('tspan').attr('x', x).attr('y', y).attr('text-anchor', anchor);
        var lineNumber = 0;
        var line = [];
        var word = words.pop();


        while (word) {
            line.push(word);
            tspan.text(line.join(' '));
            if (tspan.node().getComputedTextLength() > width) {
                lineNumber += 1;
                line.pop();
                tspan.text(line.join(' '));

                line = [word];
                tspan = text.append('tspan').attr('x', x).attr('y', y + lineNumber * lineHeight).attr('anchor', anchor).text(word);

            }
            word = words.pop();
        }
    });
};