Built with blockbuilder.org
Created
November 23, 2019 23:55
-
-
Save akulmehta/3b2a3772d8f6f5c50ebf11de84efd71c to your computer and use it in GitHub Desktop.
Updating Line Chart with updates to old data
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
license: mit |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<style> | |
/* set the CSS */ | |
body { | |
font: 12px Arial; | |
} | |
path { | |
stroke: steelblue; | |
stroke-width: 2; | |
fill: none; | |
} | |
.axis path, | |
.axis line { | |
fill: none; | |
stroke: grey; | |
stroke-width: 1; | |
shape-rendering: crispEdges; | |
} | |
</style> | |
<body> | |
<div id="graphDiv"></div> | |
<!-- load the d3.js library --> | |
<script src="https://d3js.org/d3.v5.min.js"></script> | |
<script> | |
var data_set = [{ | |
'Date': '2009-03-23', | |
'Raw': 25, | |
'Raw2': 25, | |
'Asset': 'A' | |
}, | |
{ | |
'Date': '2009-03-24', | |
'Raw': 28, | |
'Raw2': 25.4, | |
'Asset': 'A' | |
}, | |
{ | |
'Date': '2009-03-25', | |
'Raw': 26, | |
'Raw2': 25.37, | |
'Asset': 'B' | |
}, | |
{ | |
'Date': '2009-03-26', | |
'Raw': 22, | |
'Raw2': 25.03, | |
'Asset': 'B' | |
}, | |
{ | |
'Date': '2009-03-27', | |
'Raw': 19, | |
'Raw2': 24.42, | |
'Asset': 'C' | |
}, | |
{ | |
'Date': '2009-03-28', | |
'Raw': 23, | |
'Raw2': 24.28, | |
'Asset': 'D' | |
} | |
] | |
var margin = { | |
top: 30, | |
right: 50, | |
bottom: 30, | |
left: 50 | |
}; | |
var svgWidth = 600; | |
var svgHeight = 500; | |
var graphWidth = svgWidth - margin.left - margin.right; | |
var graphHeight = svgHeight - margin.top - margin.bottom; | |
// var parseDate = d3.timeParse("%d/%m/%Y"); | |
var parseDate = d3.timeParse("%Y-%m-%d"); | |
var x = d3.scaleTime().range([0, graphWidth]); | |
var y = d3.scaleLinear().range([graphHeight, 0]); | |
var z = d3.scaleOrdinal(d3.schemeCategory10); // for colours | |
var xAxis = d3.axisBottom().scale(x).ticks(10); | |
var yAxis = d3.axisLeft().scale(y).ticks(10); | |
// // Need to create the lines manually for each bit of data | |
var line = d3.line() | |
.x(function (d) { | |
// console.log(d.date); | |
return x(d.date); | |
}) | |
.y(function (d) { | |
return y(d.y); | |
}); | |
// Creates the SVG area within the div on the dom | |
// Just doing this once | |
var svg = d3.select("#graphDiv") | |
.append("svg") | |
.attr("width", svgWidth) | |
.attr("height", svgHeight) | |
var g = svg.append("g") | |
.attr("transform", | |
"translate(" + margin.left + "," + margin.top + ")") | |
.call(d3.zoom().on("zoom", function () { | |
svg.attr("transform", d3.event.transform) | |
})); | |
// Add the X Axis | |
g.append("g").attr("class", "x axis") | |
.attr("transform", "translate(0," + graphHeight + ")") | |
.call(xAxis); | |
// Text label for x axis | |
g.append("text") | |
.style("text-anchor", "middle") | |
.text("timeseries dates") | |
.attr("transform", "translate(" + (graphWidth / 2) + " ," + (graphHeight + margin.top) + ")"); | |
// Add the Y Axis | |
g.append("g") | |
.attr("class", "y axis") | |
.call(yAxis); | |
// text label for the y axis | |
g.append("text") | |
.attr("transform", "rotate(-90)") | |
.attr("y", 0 - margin.left) | |
.attr("x", 0 - (graphHeight / 2)) | |
.attr("dy", "1em") | |
.style("text-anchor", "middle") | |
.text("price points"); | |
function drawGraph(data_set) { | |
let pathData = [] | |
//assume 2 paths | |
pathData.push([]) | |
pathData.push([]) | |
// Pass in the data here | |
data_set.forEach(function (d) { | |
let path0 = {} | |
let path1 = {} | |
path0.date = parseDate(d.Date) | |
path1.date = parseDate(d.Date) | |
path0.y = +d.Raw | |
path1.y = +d.Raw2 | |
pathData[0].push(path0) | |
pathData[1].push(path1) | |
}); | |
x.domain(d3.extent(data_set, function (d) { | |
return parseDate(d.Date); | |
})); | |
y.domain([ | |
d3.min(data_set, function (d) { | |
return Math.min(d.Raw, d.Raw2) | |
}), | |
d3.max(data_set, function (d) { | |
return Math.max(d.Raw, d.Raw2) | |
}) | |
]); | |
svg.selectAll('.x.axis').call(xAxis); | |
svg.selectAll('.y.axis').call(yAxis); | |
var lines = g.selectAll(".path") | |
.data(pathData); | |
lines.exit().remove(); | |
var enter = lines.enter() | |
.append("path") | |
.attr("class", "path") | |
.style("stroke", (d, i) => z(i)) | |
var merge = enter.merge(lines) | |
.attr("d", line) | |
} | |
// display initial chart | |
window.onload = drawGraph(data_set) | |
//if newdata also contains updates for old dates and also data for new dates | |
let newdata = [{ | |
'Date': '2009-03-29', | |
'Raw': Math.floor(Math.random() * 50), | |
'Raw2': Math.floor(Math.random() * 25), | |
'Asset': 'A' | |
}, { | |
'Date': '2009-03-30', | |
'Raw': Math.floor(Math.random() * 50), | |
'Raw2': Math.floor(Math.random() * 25), | |
'Asset': 'A' | |
}, { | |
'Date': '2009-03-31', | |
'Raw': Math.floor(Math.random() * 50), | |
'Raw2': Math.floor(Math.random() * 25), | |
'Asset': 'A' | |
}, { | |
'Date': '2009-04-01', | |
'Raw': Math.floor(Math.random() * 50), | |
'Raw2': Math.floor(Math.random() * 25), | |
'Asset': 'A' | |
}, { | |
'Date': '2009-04-02', | |
'Raw': Math.floor(Math.random() * 50), | |
'Raw2': Math.floor(Math.random() * 25), | |
'Asset': 'A' | |
}, { | |
'Date': '2009-04-03', | |
'Raw': Math.floor(Math.random() * 50), | |
'Raw2': Math.floor(Math.random() * 25), | |
'Asset': 'A' | |
}, | |
//some new data for old dates coming in from this point | |
{ | |
'Date': '2009-03-29', | |
'Raw': Math.floor(Math.random() * 50), | |
'Raw2': Math.floor(Math.random() * 25), | |
'Asset': 'A' | |
}, { | |
'Date': '2009-03-30', | |
'Raw': Math.floor(Math.random() * 50), | |
'Raw2': Math.floor(Math.random() * 25), | |
'Asset': 'A' | |
}, { | |
'Date': '2009-03-31', | |
'Raw': Math.floor(Math.random() * 50), | |
'Raw2': Math.floor(Math.random() * 25), | |
'Asset': 'A' | |
}, { | |
'Date': '2009-04-01', | |
'Raw': Math.floor(Math.random() * 50), | |
'Raw2': Math.floor(Math.random() * 25), | |
'Asset': 'A' | |
}, { | |
'Date': '2009-04-02', | |
'Raw': Math.floor(Math.random() * 50), | |
'Raw2': Math.floor(Math.random() * 25), | |
'Asset': 'A' | |
}, { | |
'Date': '2009-04-03', | |
'Raw': Math.floor(Math.random() * 50), | |
'Raw2': Math.floor(Math.random() * 25), | |
'Asset': 'A' | |
} | |
] | |
let counter = 0; | |
//If you do expect new data points to come for old dates | |
//use the code below | |
// Push new data every 5 seconds for a specific date | |
var h = setInterval(function () { | |
let index = data_set.findIndex((f) => f.Date === newdata[counter].Date); | |
if (index === -1) { // if data with same date not found push the new data | |
data_set.push(newdata[counter]); | |
} else { //else if it is found replace the old data | |
data_set[index] = newdata[counter]; | |
} | |
counter++; | |
drawGraph(data_set); | |
}, 3000); | |
</script> | |
</body> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment