D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
shimizu
Full window
Github gist
D3 v4 - SlopeChart
Built with
blockbuilder.org
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge"/> <title>D3 v4 - SlopeChart</title> </head> <style> html, body { width: 100%; height: 100%; } #wrapper { width: 100%; } svg { display: block; width: 50%; height: 900px; background-color: #e2e2e2; margin: auto; } text { font-size: 12px; } .slopeAxis { stroke-dasharray: 3; } .Japan { fill:green; fill-opacity:1; } .valueLine.Japan { stroke:green; } </style> <body> <div id="wrapper"> <svg></svg> </div> <script src="//cdnjs.cloudflare.com/ajax/libs/d3/4.1.1/d3.min.js"></script> <script> function cast(d){ Object.keys(d).forEach(function(key){ if (!isNaN(+d[key])) d[key] = +d[key] }) return d } d3.tsv("gdp.tsv", cast, main) function main(data) { var slopeColumns = ["GDP_2000", "GDP_2015"] var domain = [500, 20000] var margin = {top:60, left:100, bottom:30, right:100} var width,height var plotWidth, plotHeight var svg = d3.select("svg") var plotLayer = svg.append("g").attr("class", "plotLayer") var slopeLeft = plotLayer.append("g").attr("class", "slopeLeft") var slopeRight = plotLayer.append("g").attr("class", "slopeRight") var xScale = d3.scalePoint().domain(slopeColumns) var yScale = d3.scaleLog().domain(domain) setSize() rendring(data) setReSizeEvent() function rendring(data){ renderAxis(data) renderSlope(data) renderLabel(data) } function setSize() { width = svg.node().clientWidth height = svg.node().clientHeight plotWidth = width - (margin.left + margin.right) plotHeight = height - (margin.top + margin.bottom) plotLayer.attr("transform", "translate("+[margin.left, margin.top]+")") .attr("width", plotWidth) .attr("height", plotHeight) xScale.range([0, plotWidth]) yScale.range([plotHeight, 0]) slopeLeft.attr("transform", "translate("+[xScale(slopeColumns[0]), 0]+")") slopeRight.attr("transform", "translate("+[xScale(slopeColumns[1]), 0]+")") } function renderAxis(data) { //draw slopeAxis var selectedSlopeAxis = plotLayer.selectAll(".slopeAxis").data(slopeColumns) var newSlopeAxis = selectedSlopeAxis.enter().append("line") .attr("class", "slopeAxis") var slopeAxis = selectedSlopeAxis.merge(newSlopeAxis) slopeAxis .attr("x1", function(d){ return xScale(d)}) .attr("y1", 0) .attr("x2", function(d){ return xScale(d)}) .attr("y2", plotHeight) .attr("stroke", "black") //draw axisLable var selectedAxisLabel = plotLayer.selectAll(".AxisLabel").data(slopeColumns) var newAxisLabel = selectedAxisLabel.enter().append("text") .attr("class", "AxisLabel") .attr("text-anchor", "middle") .attr("dominant-baseline", "middle") var axisLabel = selectedAxisLabel.merge(newAxisLabel) axisLabel .attr("x", function(d){ return xScale(d)}) .attr("y", "-2em") .text(function(d){ return d }) } function renderSlope(data) { //draw valueLine var selectedValueLine = plotLayer.selectAll(".valueLine").data(data) var newValueLine = selectedValueLine.enter().append("line") .attr("class", function(d){ return "valueLine " + d["Country"]}) var valueLine = selectedValueLine.merge(newValueLine) valueLine .attr("x1", xScale(slopeColumns[0])) .attr("y1", function(d){ return yScale(d[slopeColumns[0]])}) .attr("x2", xScale(slopeColumns[1])) .attr("y2", function(d){ return yScale(d[slopeColumns[1]])}) .attr("stroke", "black") //draw circle var selectedLeftCircle = slopeLeft.selectAll(".leftCircle").data(data) var selectedRightCircle = slopeRight.selectAll(".rightCircle").data(data) var newLeftCircle = selectedLeftCircle.enter().append("circle").attr("class", function(d){ return "leftCircle " + d["Country"]}) var newRigthCircle = selectedRightCircle.enter().append("circle").attr("class", function(d){ return "rightCircle " + d["Country"]}) var leftCircle = selectedLeftCircle.merge(newLeftCircle) var rightCircle = selectedRightCircle.merge(newRigthCircle) leftCircle.attr("cy", function(d){ return yScale(d[slopeColumns[0]]) }).attr("r", 4) rightCircle.attr("cy", function(d){ return yScale(d[slopeColumns[1]]) }).attr("r", 4) } function renderLabel(data) { //draw label var selectedLeftLabel = slopeLeft.selectAll(".leftLabel").data(data) var selectedRightLabel = slopeRight.selectAll(".rightLabel").data(data) var newLeftLabel = selectedLeftLabel.enter().append("text").attr("class", function(d){ return "leftLabel " + d["Country"] }) .attr("text-anchor", "end") .attr("dominant-baseline", "middle") var newRigthLabel = selectedRightLabel.enter().append("text").attr("class", function(d){ return "rightLabel " + d["Country"] }) .attr("text-anchor", "start") .attr("dominant-baseline", "middle") var leftLable = selectedLeftLabel.merge(newLeftLabel) var rightLable = selectedRightLabel.merge(newRigthLabel) leftLable.text(function(d){ return d["Country"] }) .attr("x", "-0.5em") .attr("y", function(d){ var y = yScale(d[slopeColumns[0]]) if (d["Country"] === "China" || d["Country"] === "Mexico") y -= 6 if (d["Country"] === "Italy" || d["Country"] === "Brazil") y += 6 return y}) rightLable.text(function(d){ return d["Country"] }) .attr("x", "0.5em") .attr("y", function(d){ var y = yScale(d[slopeColumns[1]]) if (d["Country"] === "Italy") y -= 6 if (d["Country"] === "Brazil") y += 6 return y}) } function setReSizeEvent() { var resizeTimer; var interval = Math.floor(1000 / 60 * 10); window.addEventListener('resize', function (event) { if (resizeTimer !== false) { clearTimeout(resizeTimer); } resizeTimer = setTimeout(function () { setSize() rendring(data) }, interval); }); } } </script> </body> </html>
https://cdnjs.cloudflare.com/ajax/libs/d3/4.1.1/d3.min.js