D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
rohankoid
Full window
Github gist
ktm_mayor_2017
KTM Mayor election 2017
Data source:
reddit
spreadsheet
Code reference:
markmarkoh
https://gist.github.com/ZJONSSON/3918369
<!DOCTYPE html> <meta charset="utf-8"> <style> body { font: 10px sans-serif; margin: 0; } path.line { fill: none; stroke: #666; stroke-width: 1.5px; } path.area { fill: #e7e7e7; } .axis { shape-rendering: crispEdges; } .x.axis line { stroke: #fff; } .x.axis .minor { stroke-opacity: .5; } .x.axis path { display: none; } .y.axis line, .y.axis path { fill: none; stroke: #000; } .legend rect { fill:white; stroke:black; opacity:0.8;} rect { stroke-width: 2; } </style> <body> <svg></svg> <script src="https://d3js.org/d3.v3.min.js"></script> <script> var margin = {top: 80, right: 80, bottom: 80, left: 80}, width = 960 - margin.left - margin.right, height = 500 - margin.top - margin.bottom; // Scales and axes. var x = d3.scale.linear().range([0, width]), y = d3.scale.linear().range([height, 0]), xAxis = d3.svg.axis().scale(x).ticks(28); yAxis = d3.svg.axis().scale(y).ticks(10).orient("right"); // An area generator, for the light fill. var area = d3.svg.area() .interpolate("monotone") .x(function(d) { return x(d.hours); }) .y0(height) .y1(function(d) { return y(d.count); }); // A line generator, for the dark stroke. var line = d3.svg.line() .interpolate("monotone") .x(function(d) { return x(d.hours); }) .y(function(d) { return y(d.count); }); d3.csv("race.csv", type, function(error, data) { var uml = data.filter(function(d) { return d.symbol == "Unified Marxist–Leninist";; }); var cong = data.filter(function(d) { return d.symbol == "Congress"; }); var bnp = data.filter(function(d) { return d.symbol == "Bibeksheel Nepali"; }); var sanjha = data.filter(function(d) { return d.symbol == "Sanjha"; }); var mao = data.filter(function(d) { return d.symbol == "Maoist Centre"; }); // Compute the minimum and maximum date, and the maximum count. x.domain([1, d3.max(uml, function(d) { return d.hours; })]); y.domain([0, d3.max(uml, function(d) { return d.count; })]); // Add an SVG element with the desired dimensions and margin. var svg = d3.select("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")") // Add the clip path. svg.append("clipPath") .attr("id", "clip") .append("rect") .attr("width", width) .attr("height", height); // Add the x-axis. svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis); // Add the y-axis. svg.append("g") .attr("class", "y axis") .attr("transform", "translate(" + width + ",0)") .call(yAxis); svg.append("text") .attr("class", "x label") .attr("text-anchor", "end") .attr("x", width -300) .attr("y", height + 35) .text("Time in hours"); svg.append("text") .attr("class", "y label") .attr("text-anchor", "end") .attr("y", width+60) .attr("x", -100) .attr("dy", ".85em") .attr("transform", "rotate(-90)") .text("Votes"); var colors = d3.scale.category10(); svg.selectAll('.line') .data([uml, cong, bnp, sanjha, mao]) .enter() .append('path') .attr('class', 'line') .style('stroke', function(d) { return colors(Math.random() * 50); }) .attr('clip-path', 'url(#clip)') .attr('d', function(d) { return line(d); }) .attr("data-legend",function(d) { return d[0].symbol}) /* Add 'curtain' rectangle to hide entire graph */ var curtain = svg.append('rect') .attr('x', -1 * width) .attr('y', -1 * height) .attr('height', height) .attr('width', width) .attr('class', 'curtain') .attr('transform', 'rotate(180)') .style('fill', '#ffffff') /* Create a shared transition for anything we're animating */ var t = svg.transition() .delay(1200) .duration(9000) .ease('linear') .each('end', function() { d3.select('line.guide') .transition() .style('opacity', 0) .remove() }); t.select('rect.curtain') .attr('width', 0); t.select('line.guide') .attr('transform', 'translate(' + width + ', 0)') legend = svg.append("g") .attr("class","legend") .attr("transform","translate(50,30)") .style("font-size","13px") .call(d3.legend) }); // Parse dates and numbers. We assume values are sorted by date. function type(d) { d.hours = parseFloat(d.hours); d.count = parseInt(d.count); return d; } (function() { d3.legend = function(g) { g.each(function() { var g= d3.select(this), items = {}, svg = d3.select(g.property("nearestViewportElement")), legendPadding = g.attr("data-style-padding") || 5, lb = g.selectAll(".legend-box").data([true]), li = g.selectAll(".legend-items").data([true]) lb.enter().append("rect").classed("legend-box",true) li.enter().append("g").classed("legend-items",true) svg.selectAll("[data-legend]").each(function() { var self = d3.select(this) items[self.attr("data-legend")] = { pos : self.attr("data-legend-pos") || this.getBBox().y, color : self.attr("data-legend-color") != undefined ? self.attr("data-legend-color") : self.style("fill") != 'none' ? self.style("fill") : self.style("stroke") } }) items = d3.entries(items).sort(function(a,b) { return a.value.pos-b.value.pos}) li.selectAll("text") .data(items,function(d) { return d.key}) .call(function(d) { d.enter().append("text")}) .call(function(d) { d.exit().remove()}) .attr("y",function(d,i) { return i+"em"}) .attr("x","1em") .text(function(d) { ;return d.key}) li.selectAll("circle") .data(items,function(d) { return d.key}) .call(function(d) { d.enter().append("circle")}) .call(function(d) { d.exit().remove()}) .attr("cy",function(d,i) { return i-0.25+"em"}) .attr("cx",0) .attr("r","0.4em") .style("fill",function(d) { console.log(d.value.color);return d.value.color}) // Reposition and resize the box var lbbox = li[0][0].getBBox() lb.attr("x",(lbbox.x-legendPadding)) .attr("y",(lbbox.y-legendPadding)) .attr("height",(lbbox.height+2*legendPadding)) .attr("width",(lbbox.width+2*legendPadding)) }) return g } })() </script>
Modified
http://d3js.org/d3.v3.min.js
to a secure url
https://d3js.org/d3.v3.min.js