Javascript
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();
}
});
};