nvd3-fork
Version:
FORK! of NVD3, a reusable charting library written in d3.js
178 lines (159 loc) • 5.92 kB
HTML
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width" />
<link href="../build/nv.d3.css" rel="stylesheet" type="text/css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.2/d3.min.js" charset="utf-8"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.19.2/moment.js"></script>
<script src="../build/nv.d3.js?dsf"></script>
<style>
text {
font: 12px sans-serif;
}
svg {
display: block;
}
html, body, svg {
margin: 0px;
padding: 0px;
height: 100%;
width: 100%;
}
</style>
</head>
<body class='with-3d-shadow with-transitions'>
<script>
var expandLegend = function() {
var exp = chart.multiChart.legend.expanded();
chart.multiChart.legend.align(false);
chart.update();
}
</script>
<svg id="chart2"></svg>
<div style="height: 1000px; background-color: red;">
</div>
<script>// Use the browser's built-in functionality to quickly and safely escape
// the string
function escapeHtml(str) {
var div = document.createElement('div');
div.appendChild(document.createTextNode(str));
return div.innerHTML;
}
var chart;
function readTextFile(file) {
return new Promise(function (resolve) {
var rawFile = new XMLHttpRequest();
rawFile.overrideMimeType('application/json');
rawFile.open('GET', file, true);
rawFile.onreadystatechange = function () {
if (rawFile.readyState === 4 && rawFile.status == '200') {
resolve(rawFile.responseText);
}
};
rawFile.send(null);
});
}
var keyForActualLessThanPredicted = 'Savings (kWh)';
var keyForActualGreaterThanPredicted = 'Excess Usage (kWh)';
function loadData() {
return Promise.all([readTextFile('./actual.json'), readTextFile('./predicted.json')]).then(function (jsonResult) {
return new Promise(function (resolve, reject) {
var actualData = JSON.parse(jsonResult[0]);
var predictedData = JSON.parse(jsonResult[1]);
resolve([{
key: 'Actual usage (kWh)',
type: 'actual',
values: actualData[0].values,
color: 'black'
}, {
key: 'Predicted usage (kWh)',
type: 'expected',
values: predictedData.map(function (d) {
return {
recorded_at: d.falling_edge,
value: d.predicted
};
}),
color: 'blue'
}]);
});
});
}
function main() {
var colors = d3.scale.category20();
var lang = d3.locale({
"dateTime": '%H:%M %A %e %B, %Y',
"date": '%Y-%m-%d',
"time": "%H:%M:%S",
"periods": ['am', 'pm'],
"days": ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
"shortDays": ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
"months": ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
"shortMonths": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
});
var tickFormatMaxMin = lang.timeFormat.multi([["%b %d", function (d) {
return true;
}]]);
var tickFormat = lang.timeFormat.multi([[":%L", function (d) {
return d.getMilliseconds();
}], ["%S", function (d) {
return d.getSeconds();
}], ["%H:%M", function (d) {
return d.getMinutes();
}], ["%H:%M", function (d) {
return d.getHours();
}], ["%d/%m", function (d) {
return d.getDay() && d.getDate() != 1;
}], ["%b %d", function (d) {
return d.getDate() != 1;
}], ["%b", function (d) {
return d.getMonth();
}], ["%Y", function () {
return true;
}]]);
loadData().then(function (data) {
nv.addGraph(function () {
chart = nv.models.differenceChart();
chart.keyForXValue('recorded_at').x(function (d) {
return new Date(d.recorded_at);
}).y(function (d) {
return d.value;
}).keyForActualLessThanPredicted(keyForActualLessThanPredicted).keyForActualGreaterThanPredicted(keyForActualGreaterThanPredicted).height(500).showPredictedLine(true).interpolate('step-before').tickFormat(tickFormat).strokeWidth(0.5);
chart.multiChart.interactiveLayer.tooltip.contentGenerator(function (d) {
var header = d.value;
var headerhtml = "<thead><tr><td colspan='3'><strong class='x-value'>" + header + "</strong></td></tr></thead>";
var bodyhtml = "<tbody>";
var series = d.series;
series.forEach(function (c) {
var value = (c.value || 0).toFixed(2);
if (c.key === keyForActualGreaterThanPredicted || c.key === keyForActualLessThanPredicted) {
var diff = Math.abs(c.data.y0 - c.data.y1);
if (diff === 0) {
value = '-';
} else {
value = diff.toFixed(2);
}
}
bodyhtml = bodyhtml + "<tr><td class='legend-color-guide'><div style='background-color: " + escapeHtml(c.color) + ";'></div></td><td class='key'>" + escapeHtml(c.key) + "</td><td class='value'>" + escapeHtml(value) + "</td></tr>";
});
bodyhtml = bodyhtml + "</tbody>";
return "<table>" + headerhtml + '' + bodyhtml + "</table>";
});
chart.xAxis.tickFormatMaxMin(tickFormatMaxMin);
chart.focus.xAxis.tickFormatMaxMin(tickFormatMaxMin);
chart.focus.height(40);
chart.focusMargin({ top: 10 });
chart.margin({ top: 60 });
d3.select('svg#chart2').datum(data).call(chart);
nv.utils.windowResize(chart.update);
return chart;
});
});
}
main();
;
</script>
</body>
</html>