Skip to content

Instantly share code, notes, and snippets.

@greaneym
Last active July 10, 2017 22:19
Show Gist options
  • Save greaneym/b4a14400fbbef96464929465ed97b5fc to your computer and use it in GitHub Desktop.
Save greaneym/b4a14400fbbef96464929465ed97b5fc to your computer and use it in GitHub Desktop.
gdp chart using d3.js
//Based on Mike Bostock’s Block 3020685
//and Mike Hadlow’s Block 93b471e569e31af07cd3
// I plan to redo this in future as it not "dry"
var format = d3.time.format("%Y-%m-%d");
var formatYear = d3.time.format("%Y %b");
var margin = {top: 20, right: 30, bottom: 30, left: 40},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x = d3.time.scale()
.range([0, width]);
var y = d3.scale.linear()
.range([height, 0]);
var z = d3.scale.category20c();
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(d3.time.years)
//.ticks(19);
.ticks(22);
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var stack = d3.layout.stack()
.offset("zero")
.values(function(d) {
//console.log("d.values",d.values);
return d.values; })
.x(function(d) {
//console.log("type of d.date", typeof d.date);
return d.date; })
.y(function(d) {
//console.log("stack d.value",d.value);
return d.value; });
var nest = d3.nest()
.key(function(d) {
// console.log("in nest d.key",d.key);
return d.key; });
var area = d3.svg.area()
.interpolate("cardinal")
.x(function(d) {
//console.log("area d",d);console.log("area date",x(d.date));
return x(d.date); })
.y0(function(d) {
//console.log("area y0",y(d.y0));
return y(d.y0); })
.y1(function(d) {
//console.log("area y",y(d.y0 + d.y));
if (y(d.y0 + d.y) === NaN) { return 0; }
else {
return y(d.y0 + d.y); }});
//var svg = d3.select("body").append("svg")
var svg = d3.select("#containerch").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 + ")");
var g = svg.append('g').attr('transform', 'translate(' + margin.left + ', ' + margin.top + ')');
d3.csv("gdp.csv", function(error, data) {
if (error) throw error;
var chdata = [];
data.forEach(function(d,i) {
//console.log("data d,i",d,i);
d.years = formatYear.parse(d.date);
d.date = format.parse(d.date);
//console.log("d.date", d.date, typeof d.date);
d.value = +d.value;
//console.log("each d.key1", d.key1);
chdata.push([d.date,d.value]);
});
//var data = [
// [new Date(2014, 01, 10), 404],
// [new Date(2014, 01, 11), 123],
// [new Date(2014, 01, 12), 666]
//];
//console.log("chdata", chdata);
var layers = stack(nest.entries(data));
//console.log("layers", layers);
x.domain(d3.extent(data, function(d) {
//console.log("XDOMAIN d.date",d.date);
return d.date; }));
var whatx = x.domain(d3.extent(data, function(d) { return d.date; }));
// console.log("xdomain", whatx);
y.domain([0, d3.max(data, function(d) { return d.y0 + d.y; })]);
var whaty = y.domain([0, d3.max(data, function(d) { return d.y0 + d.y; })]);
//console.log("ydomain", whaty);
//var tooltip = d3.select("body").append("div").attr("class", "tooltip");
// Define the div for the tooltip
var div = d3.select("#containerch").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
svg.selectAll(".layer")
.data(layers)
.enter().append("path")
.attr("class", "layer")
.append ("text")
.text(function(d) { return area(d.values); });
svg.select(".layer")
//svg.select("title")
.attr("d", function(d) { console.log( "area d.values", d.values,typeof d.values); return area(d.values); })
.style("fill", function(d, i) { console.log("z fill val", z(i)); return z(i); })
.on("mouseover", function(d,i) {
//drawLineGraph(500, 960, chdata, "GDP in Billions of Dollars", { lineValue: 200, label: "HELP!" });
div.transition(300)
//div
.style("opacity", 1.0);
div .html("GDP:" + d.values[i].value + "Billion" + "<br/>"+ formatYear(d.values[i].date))
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px")
.style("z-index", "99");
});
drawLineGraph(500, 960, chdata, "GDP in Billions of Dollars", { lineValue: 200, label: "HELP!" });
div.on("mouseout", function(d) {
div.transition()
.duration(20)
.style("opacity", 0);
});
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
//drawLineGraph(900, 560, chdata, "Intensity", { lineValue: 200, label: "HELP!" });
//drawLineGraph(500, 960, chdata, "GDP in Billions of Dollars", { lineValue: 200, label: "HELP!" });
//drawLineGraph(900, 560, data, "GDP in Billions of Dollars", null);
//testing adding text
g.selectAll("text").append("text")
.data(chdata, function (d) {
if (d !== undefined) {
console.log("d",d);
}
if (typeof d[0] !== (undefined|null|NaN)) {
console.log("d0",formatYear(d[0]));
//console.log("saw undefined",formatYear(d[0]));
}
if (d[1] !== undefined) {
console.log("d1",d[1]);
}
})
//.data(data)
.enter()
.append("text")
.attr('text-anchor', 'end')
.attr('z-index',' 500')
.attr("x", function(d) {
return x(d[0]);
})
.attr("y", function(d) {
return y(d[0]);
})
.attr("font-family", "sans-serif")
.attr("font-size", "11px")
.attr("fill", "red")
.text(function(d) {
console.log("circletext d",d);
return d[0] + "," + d[1];
});
});
//ch2.js
var drawLineGraph = function(containerHeight, containerWidth, data, yLabel, warnLine) {
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
//var svg = d3.select("body").append("svg")
var svg2 = d3.select("#container").append("svg")
.attr("width", containerWidth)
.attr("height", containerHeight);
var margin = { top: 50, left: 50, right: 50, bottom: 50 };
//var margin = { top: 50, left: 50, right: 10, bottom: 50 };
var height = containerHeight - margin.top - margin.bottom;
var width = containerWidth - margin.left - margin.right;
var format = d3.time.format("%Y-%m-%d");
//var formatYear = d3.time.format("%Y %b");
var formatYear = d3.time.format("%B %Y");
var formatNum = d3.format(",.2f");
var xDomain = d3.extent(data, function(d) { return d[0]; })
var yDomain = d3.extent(data, function(d) { return d[1]; });
var xScale = d3.time.scale().range([0, width]).domain(xDomain);
var yScale = d3.scale.linear().range([height, 0]).domain(yDomain);
var xAxis = d3.svg.axis().scale(xScale).orient('bottom')
.ticks(22);
var yAxis = d3.svg.axis().scale(yScale).orient('left');
var line = d3.svg.line()
.x(function(d) { return xScale(d[0]); })
.y(function(d) { return yScale(d[1]); });
var area = d3.svg.area()
//.attr("fill","steel-blue");
//.attr("d",function (d) { "fill", "steel-blue");
.x(function(d) { return xScale(d[0]); })
.y0(function(d) { return yScale(d[1]); })
.y1(height);
var g = svg2.append('g').attr('transform', 'translate(' + margin.left + ', ' + margin.top + ')');
g.append('path')
.datum(data)
.attr('class', 'area')
.attr('d', area);
g.append('g')
.attr('class', 'x axis')
.attr('transform', 'translate(0, ' + height + ')')
.call(xAxis)//;
.append('text')
.attr('transform', 'rotate(0)')
.attr('x', 460)
.attr('dx', '3.50em')
.attr('transform', 'translate(' + margin.left + ', ' + margin.top + ')')
.attr('text-anchor', 'middle')
.text("Units Billions of Dollars Seasonally Adjusted");
g.append('g')
.attr('class', 'y axis')
.call(yAxis)
.append('text')
.attr('transform', 'rotate(-90)')
.attr('y', 6)
.attr('dy', '.71em')
.attr('text-anchor', 'end')
.text(yLabel);
g.append('path')
.datum(data)
.attr('class', 'line')
.attr('d', line);
g.selectAll('circle').data(data).enter().append('circle')
.attr('cx', function(d) { return xScale(d[0]); })
.attr('cy', function(d) { return yScale(d[1]); })
.attr('r', 0)
.attr('class', 'circle');
g.selectAll('circle').data(data).enter().append('text')
.attr('x', function(d) { return xScale(d[0]); })
.attr('y', function(d) { return yScale(d[1]); })
.attr('font-size', "50px")
.text(function d() { console.log("circletext",d[0],d[1]);
});
// focus tracking
var focus = g.append('g').style('display', 'none');
focus.append('line')
.attr('id', 'focusLineX')
.attr('class', 'focusLine');
focus.append('line')
.attr('id', 'focusLineY')
.attr('class', 'focusLine');
focus.append('circle')
.attr('id', 'focusCircle')
.attr('r', 0)
.attr('class', 'circle focusCircle');
var bisectDate = d3.bisector(function(d) { return d[0]; }).left;
g.append('rect')
.attr('class', 'overlay')
.attr('width', width)
.attr('height', height)
.on('mouseover', function() { focus.style('display', null); })
.on('mouseout', function() { focus.style('display', 'none'); })
.on('mousemove', function() {
var mouse = d3.mouse(this);
var mouseDate = xScale.invert(mouse[0]);
var i = bisectDate(data, mouseDate); // returns the index to the current data item
var d0 = data[i - 1]
var d1 = data[i];
// work out which date value is closest to the mouse
var d = mouseDate - d0[0] > d1[0] - mouseDate ? d1 : d0;
var x = xScale(d[0]);
var y = yScale(d[1]);
focus.select('#focusCircle')
.attr('cx', x)
.attr('cy', y);
focus.select('#focusLineX')
.attr('x1', x).attr('y1', yScale(yDomain[0]))
.attr('x2', x).attr('y2', yScale(yDomain[1]));
focus.select('#focusLineY')
.attr('x1', xScale(xDomain[0])).attr('y1', y)
.attr('x2', xScale(xDomain[1])).attr('y2', y);
div.transition(300)
.style("opacity", 1.0);
div .html( "$" + formatNum(d[1]) + " Billion" + "<br/>"+ formatYear(d[0]))
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px")
.style("z-index", "99");
//testing adding text
g.selectAll("circle").append("text")
.data(data, function (d) {
if (d !== undefined) {
console.log("d",d);
}
if (typeof d[0] !== (undefined|null|NaN)) {
console.log("d0",formatYear(d[0]));
//console.log("saw undefined",formatYear(d[0]));
}
if (d[1] !== undefined) {
console.log("d1",d[1]);
}
})
//.data(data)
.enter()
.append("text")
.attr('text-anchor', 'end')
.attr('z-index',' 200')
.attr("x", function(d) {
return xScale(d[0]);
})
.attr("y", function(d) {
return yScale(d[0]);
})
.attr("font-family", "sans-serif")
.attr("font-size", "11px")
.attr("fill", "red")
.text(function(d) {
console.log("circletext d",d);
return d[0] + "," + d[1];
});
// text label for the x axis
//svg2.append("text")
// Add the x Axis
svg2.append("g")
.attr("transform", "translate(0," + height + ")")
//.call(d3.axisBottom(x));
.call(xAxis);
// text label for the x axis
svg2.append("text")
.attr("transform",
"translate(" + (width/2) + " ," +
(height + margin.top + 20) + ")")
.style("text-anchor", "middle")
.text("Some Label Text");
});
// warn line
if(warnLine && yDomain[0] < warnLine.lineValue && yDomain[1] > warnLine.lineValue) {
g.append('line')
.attr('x1', xScale(xDomain[0]))
.attr('y1', yScale(warnLine.lineValue))
.attr('x2', xScale(xDomain[1]))
.attr('y2', yScale(warnLine.lineValue))
.attr('class', 'zeroline');
g.append('text')
.attr('x', xScale(xDomain[1]))
.attr('y', yScale(warnLine.lineValue))
.attr('dy', '1em')
.attr('text-anchor', 'end')
.text(warnLine.label)
.attr('class', 'zerolinetext');
}
};
date value
1947-01-01 243.1
1947-04-01 246.3
1947-07-01 250.1
1947-10-01 260.3
1948-01-01 266.2
1948-04-01 272.9
1948-07-01 279.5
1948-10-01 280.7
1949-01-01 275.4
1949-04-01 271.7
1949-07-01 273.3
1949-10-01 271
1950-01-01 281.2
1950-04-01 290.7
1950-07-01 308.5
1950-10-01 320.3
1951-01-01 336.4
1951-04-01 344.5
1951-07-01 351.8
1951-10-01 356.6
1952-01-01 360.2
1952-04-01 361.4
1952-07-01 368.1
1952-10-01 381.2
1953-01-01 388.5
1953-04-01 392.3
1953-07-01 391.7
1953-10-01 386.5
1954-01-01 385.9
1954-04-01 386.7
1954-07-01 391.6
1954-10-01 400.3
1955-01-01 413.8
1955-04-01 422.2
1955-07-01 430.9
1955-10-01 437.8
1956-01-01 440.5
1956-04-01 446.8
1956-07-01 452
1956-10-01 461.3
1957-01-01 470.6
1957-04-01 472.8
1957-07-01 480.3
1957-10-01 475.7
1958-01-01 468.4
1958-04-01 472.8
1958-07-01 486.7
1958-10-01 500.4
1959-01-01 511.1
1959-04-01 524.2
1959-07-01 525.2
1959-10-01 529.3
1960-01-01 543.3
1960-04-01 542.7
1960-07-01 546
1960-10-01 541.1
1961-01-01 545.9
1961-04-01 557.4
1961-07-01 568.2
1961-10-01 581.6
1962-01-01 595.2
1962-04-01 602.6
1962-07-01 609.6
1962-10-01 613.1
1963-01-01 622.7
1963-04-01 631.8
1963-07-01 645
1963-10-01 654.8
1964-01-01 671.1
1964-04-01 680.8
1964-07-01 692.8
1964-10-01 698.4
1965-01-01 719.2
1965-04-01 732.4
1965-07-01 750.2
1965-10-01 773.1
1966-01-01 797.3
1966-04-01 807.2
1966-07-01 820.8
1966-10-01 834.9
1967-01-01 846
1967-04-01 851.1
1967-07-01 866.6
1967-10-01 883.2
1968-01-01 911.1
1968-04-01 936.3
1968-07-01 952.3
1968-10-01 970.1
1969-01-01 995.4
1969-04-01 1011.4
1969-07-01 1032
1969-10-01 1040.7
1970-01-01 1053.5
1970-04-01 1070.1
1970-07-01 1088.5
1970-10-01 1091.5
1971-01-01 1137.8
1971-04-01 1159.4
1971-07-01 1180.3
1971-10-01 1193.6
1972-01-01 1233.8
1972-04-01 1270.1
1972-07-01 1293.8
1972-10-01 1332
1973-01-01 1380.7
1973-04-01 1417.6
1973-07-01 1436.8
1973-10-01 1479.1
1974-01-01 1494.7
1974-04-01 1534.2
1974-07-01 1563.4
1974-10-01 1603
1975-01-01 1619.6
1975-04-01 1656.4
1975-07-01 1713.8
1975-10-01 1765.9
1976-01-01 1824.5
1976-04-01 1856.9
1976-07-01 1890.5
1976-10-01 1938.4
1977-01-01 1992.5
1977-04-01 2060.2
1977-07-01 2122.4
1977-10-01 2168.7
1978-01-01 2208.7
1978-04-01 2336.6
1978-07-01 2398.9
1978-10-01 2482.2
1979-01-01 2531.6
1979-04-01 2595.9
1979-07-01 2670.4
1979-10-01 2730.7
1980-01-01 2796.5
1980-04-01 2799.9
1980-07-01 2860
1980-10-01 2993.5
1981-01-01 3131.8
1981-04-01 3167.3
1981-07-01 3261.2
1981-10-01 3283.5
1982-01-01 3273.8
1982-04-01 3331.3
1982-07-01 3367.1
1982-10-01 3407.8
1983-01-01 3480.3
1983-04-01 3583.8
1983-07-01 3692.3
1983-10-01 3796.1
1984-01-01 3912.8
1984-04-01 4015
1984-07-01 4087.4
1984-10-01 4147.6
1985-01-01 4237
1985-04-01 4302.3
1985-07-01 4394.6
1985-10-01 4453.1
1986-01-01 4516.3
1986-04-01 4555.2
1986-07-01 4619.6
1986-10-01 4669.4
1987-01-01 4736.2
1987-04-01 4821.5
1987-07-01 4900.5
1987-10-01 5022.7
1988-01-01 5090.6
1988-04-01 5207.7
1988-07-01 5299.5
1988-10-01 5412.7
1989-01-01 5527.4
1989-04-01 5628.4
1989-07-01 5711.6
1989-10-01 5763.4
1990-01-01 5890.8
1990-04-01 5974.7
1990-07-01 6029.5
1990-10-01 6023.3
1991-01-01 6054.9
1991-04-01 6143.6
1991-07-01 6218.4
1991-10-01 6279.3
1992-01-01 6380.8
1992-04-01 6492.3
1992-07-01 6586.5
1992-10-01 6697.6
1993-01-01 6748.2
1993-04-01 6829.6
1993-07-01 6904.2
1993-10-01 7032.8
1994-01-01 7136.3
1994-04-01 7269.8
1994-07-01 7352.3
1994-10-01 7476.7
1995-01-01 7545.3
1995-04-01 7604.9
1995-07-01 7706.5
1995-10-01 7799.5
1996-01-01 7893.1
1996-04-01 8061.5
1996-07-01 8159
1996-10-01 8287.1
1997-01-01 8402.1
1997-04-01 8551.9
1997-07-01 8691.8
1997-10-01 8788.3
1998-01-01 8889.7
1998-04-01 8994.7
1998-07-01 9146.5
1998-10-01 9325.7
1999-01-01 9447.1
1999-04-01 9557
1999-07-01 9712.3
1999-10-01 9926.1
2000-01-01 10031
2000-04-01 10278.3
2000-07-01 10357.4
2000-10-01 10472.3
2001-01-01 10508.1
2001-04-01 10638.4
2001-07-01 10639.5
2001-10-01 10701.3
2002-01-01 10834.4
2002-04-01 10934.8
2002-07-01 11037.1
2002-10-01 11103.8
2003-01-01 11230.1
2003-04-01 11370.7
2003-07-01 11625.1
2003-10-01 11816.8
2004-01-01 11988.4
2004-04-01 12181.4
2004-07-01 12367.7
2004-10-01 12562.2
2005-01-01 12813.7
2005-04-01 12974.1
2005-07-01 13205.4
2005-10-01 13381.6
2006-01-01 13648.9
2006-04-01 13799.8
2006-07-01 13908.5
2006-10-01 14066.4
2007-01-01 14233.2
2007-04-01 14422.3
2007-07-01 14569.7
2007-10-01 14685.3
2008-01-01 14668.4
2008-04-01 14813
2008-07-01 14843
2008-10-01 14549.9
2009-01-01 14383.9
2009-04-01 14340.4
2009-07-01 14384.1
2009-10-01 14566.5
2010-01-01 14681.1
2010-04-01 14888.6
2010-07-01 15057.7
2010-10-01 15230.2
2011-01-01 15238.4
2011-04-01 15460.9
2011-07-01 15587.1
2011-10-01 15785.3
2012-01-01 15973.9
2012-04-01 16121.9
2012-07-01 16227.9
2012-10-01 16297.3
2013-01-01 16440.7
2013-04-01 16526.8
2013-07-01 16727.5
2013-10-01 16957.6
2014-01-01 16984.3
2014-04-01 17270
2014-07-01 17522.1
2014-10-01 17615.9
2015-01-01 17649.3
2015-04-01 17913.7
2015-07-01 18064.7
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font: 10px sans-serif;
}
.containerch {
position:absolute;
left:50%;
top:-500;
height:-500px;
width:960px;
border-style:solid;
border-width:20px;
border-color:red;
z-index:500;
}
.container {
position: absolute;
left:50%;
top:0;
height:500px;
width:960px;
border-style:solid;
border-width:20px;
border-color:green;
z-index:10;
display: none;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
area:hover {
fill: steel-blue;
}
div.tooltip {
position: absolute;
text-align: center;
width: 200px;
height: 60px;
padding: 2px;
font: 20px sans-serif;
font-style: bold;
background: white;
border: 3px;
border-radius: 8px;
border-color: "steel-blue"; /* #3182bd; */
z-index: 200;
}
.x.axis path {
display: none;
}
.line {
fill: none;
stroke: steelblue;
stroke-width: 2px;
}
.circle {
fill: white;
stroke: steelblue;
stroke-width: 2px;
}
.area {
fill: steelblue;
stroke: none;
opacity: 0.7;
}
.zeroline {
fill: none;
stroke: red;
stroke-width: 0.5px;
stroke-dasharray: 5 5;
}
.zerolinetext {
fill: red;
}
.overlay {
fill: none;
stroke: none;
pointer-events: all;
}
.focusLine {
fill: none;
stroke: steelblue;
stroke-width: 0.5px;
}
.focusCircle {
fill: red;
}
.hidden {
display: none;
}
</style>
<body>
<div id="container" ></div>
<div id="containerch" class="hidden">
<div id="tooltip" class="hidden">
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
<script src="chart.js"></script>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment