Built with blockbuilder.org
Created
November 23, 2019 23:55
-
-
Save akulmehta/8e9c039a6ef82bc056fe416111da27c7 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