Built with blockbuilder.org
xxxxxxxxxx
<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