This is a derivative of the simple d3.js graph in v4 used as an example in the book D3 Tips and Tricks v4. The stock data was sourced from Mike Bostock's small multiples example.
It is the first graph in a series that is building a multi-line graph that incorperates an automatically developed legend and a system that can toggle the lines off and on as desired.
This version is demonstrating the use of the d3.nest
function to group the data to allow the different lines to be drawn.
The graph should be taken in context with the text of the book which can be downloaded for free from Leanpub.
forked from d3noob's block: Multi-line graph 1 with v4: Lines
xxxxxxxxxx
<meta charset="utf-8">
<style> /* set the CSS */
body { font: 12px Arial;}
path {
stroke: steelblue;
stroke-width: .75;
fill: none;
}
.axis path,
.axis line {
fill: none;
stroke: grey;
stroke-width: 1;
shape-rendering: crispEdges;
}
.team-table table {
table-layout: fixed;
}
.team-table table tr td:nth-of-type(2) {width:90px; text-align:left}
.team-table table td {text-align:right}
</style>
<body>
<!-- load the d3.js library -->
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var teamColors = {
"Colorado": "#330072",
"LA Dodgers": "#002F6C",
"Arizona": "#A71930",
"San Diego": "#041E42",
"San Francisco": "#FA4616"
}
// Set the dimensions of the canvas / graph
var margin = { top: 30, right: 400, bottom: 30, left: 50 },
width = 400,
height = 220 - margin.top - margin.bottom;
// Get the data
d3.csv("2018-nl-west-cumulative-season-standings.csv", function (error, data) {
data.forEach(function (d) {
d.games_played = +d.games_played;
d.wins = +d.wins;
d.losses = +d.losses;
d.y_pt = d.wins - d.losses;
});
var xExtent = d3.extent(data, function (d) { return d.games_played; });
var xScale = d3.scaleLinear().domain(xExtent).range([0, width]);
var yExtent = d3.extent([d3.min(data, function (d) { return d.y_pt; }), d3.max(data, function (d) { return d.y_pt; })]);
var yScale = d3.scaleLinear().domain(yExtent).range([height, 0]);
// Adds the svg canvas
var svg = d3.select("body")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
// Define the line
var priceline = d3.line()
.x(function (d) { return xScale(d.games_played); })
.y(function (d) { return yScale(d.y_pt); });
// Nest the entries by symbol
var dataNest = d3.nest()
.key(function (d) { return d.team_short_name; })
.entries(data);
// Loop through each symbol / key
dataNest.forEach(function (d) {
svg.append("path")
.attr("class", "line")
.style("stroke", teamColors[d.key])
.attr("d", priceline(d.values));
});
// Get the last five rows, which are the final records for the division
var finalRecords = data.slice(Math.max(data.length - 5, 1)).sort(compare);
function compare(a, b) {
const winsA = a.wins;
const winsB = b.wins;
let comparison = 0;
if (winsA > winsB) {
comparison = -1;
} else if (winsA < winsB) {
comparison = 1;
}
return comparison;
}
// var finalRecordsSorted = finalRecords.sort(compare);
finalRecords.forEach(function (d, i) {
var columns = [' ',' ',' ', 'home', 'road', 'pct']
// var table = d3.select('body').append('table')
var thead = table.append('thead')
var tbody = table.append('tbody');
// append the header row
thead.append('tr')
.selectAll('th')
.data(columns).enter()
.append('th')
.text(function (column) { return column; });
var table = svg.append("foreignObject")
.attr("width", 500)
.attr("class", "team-table")
.style("color", teamColors[d.team_short_name])
.attr("x", xScale(d.games_played) + 5).attr("y", yScale(d.y_pt) - 13)
.append("xhtml:table");
if (i ===0 ){
var tr = table.selectAll('tr')
.data([columnHeaders]).enter()
.append('tr')
console.log(columnHeaders);
columnHeaders.columns.forEach(function(col) {
tr.append('th').html(col)
})
}
// var tbodyelement = document.createElement("tbody")
console.log(table)
// var tbody = table.appendChild("tbody");
var tr = tbody.selectAll('tr')
.data([d]).enter()
.append('tr')
tr.append('td').html(function (d) { return (d.wins-81)*2 });
tr.append('td').html(function (d) { return d.team_short_name });
tr.append('td').html(function (d) { return d.wins + "-" + d.losses });
tr.append('td').html(function (d) { return d.home })
tr.append('td').html(function (d) { return d.road })
tr.append('td').html(function (d) { return d.pct })
})
});
</script>
</body>
https://d3js.org/d3.v4.min.js