D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
newsroomdev
Full window
Github gist
g3-alpha
Built with
blockbuilder.org
<!DOCTYPE html> <head> <meta charset="utf-8"> <script src="https://d3js.org/d3.v4.min.js"></script> <style> body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; } .axis { font: 10px sans-serif; } .axis path, .axis line { fill: none; stroke: #000; shape-rendering: crispEdges; } .axis--x path, .axis--y path{ display: none; } .axis-title { fill: black; } .contracts path { fill: none; stroke: steelblue; stroke-width: 1.5px; } .voronoi path { fill: none; stroke: rgba(0,0,0,0.1); pointer-events: all; } .focus { text-anchor: middle; } .tooltip { max-width: 55px; width: 100%; font-size: 12px; } .tooltip-top { background: white; border: 0.5px solid #F2F2F2; border-top-left-radius: 1em; border-top-right-radius: 1em; padding: 0.4em 0.5em 0.1em; width: 100%; } .tooltip-bottom { background: #F2F2F2; border: 0.5px solid #F2F2F2; border-bottom-left-radius: 1em; border-bottom-right-radius: 1em; padding: 0.1em 0.5em 0.4em; width: 100%; } .tooltip-arrow { margin: 0 auto; width: 0; height: 0; border-left: 5px solid transparent; border-right: 5px solid transparent; border-top: 5px solid #F2F2F2; } .focus text tspan:first-child{ fill: gray; } .focus text tspan:last-child{ fill: black; } </style> </head> <body> <script src="data.js"></script> <script> // Feel free to change or delete any of the code you see in this editor! var g3 = { opts: {}, dimensions: { width: 0, height: 0 }, data: [], bindTo: "body" }; g3.timeseries = function(opts) { return new Chart(opts); } var Chart = function(opts) { self = Object.assign(this, g3); initialize(opts); function initialize(opts) { self.opts = opts; self.bindTo = self.opts.bindTo || self.bindTo; self.d3DOM = d3.select(self.bindTo); self.dimensions.width = +self.d3DOM.style("width").slice(0, -2); self.dimensions.height = +self.d3DOM.style("height").slice(0, -2); self.d3DOM.on("resize", resize); renderAxis(); } function renderAxis() { var xColumn = self.opts.axis.x.column, yColumn = self.opts.axis.y.column, xFormat = self.opts.axis.x.format, yFormat = self.opts.axis.y.format, margin = self.margin = self.opts.margin, width = self.dimensions.width - margin.left - margin.right, height = self.dimensions.height - margin.top - margin.bottom; var data = self.opts.data.map(function(d) { d[xColumn] = xFormat(d[xColumn]); d[yColumn] = yFormat(d[yColumn]); return d; }); var x = d3.scaleTime() .range([0, width]) .domain(d3.extent(data, function(d) { return d[xColumn]; })); var y = d3.scaleLinear() .range([height, 0]) .domain(d3.extent(data, function(d) { return d[yColumn]; })); var line = d3.line() .x(function(d) { return x(d[xColumn]); }) .y(function(d) { return y(d[yColumn]); }); var voronoi = d3.voronoi() .x(function(d) { return x(d[xColumn]); }) .y(function(d) { return y(d[yColumn]); }) .extent([[-margin.left, -margin.top], [width + margin.right, height + margin.bottom]]); self.x = x; self.y = y; self.xColumn = xColumn; self.yColumn = yColumn; self.line = line; self.voronoi = voronoi; self.data = data; updateDOM(); } function updateDOM() { var d3DOM = self.d3DOM, margin = self.margin, width = self.dimensions.width - margin.left - margin.right, height = self.dimensions.height - margin.top - margin.bottom; data = self.data, line = self.line, voronoi = self.voronoi, x = self.x, y = self.y; var svg = d3DOM.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 + ")"); svg.append("g") .attr("class", "axis axis--x") .attr("transform", "translate(0," + height + ")") .call(d3.axisBottom(x)); svg.append("g") .attr("class", "axis axis--y") .call(d3.axisRight(y)) .append("text") .attr("class", "axis-title") .attr("transform", "rotate(-90)") .attr("y", -16) .attr("dy", ".71em") .style("text-anchor", "end") .text("Dollars obligated ($)"); svg.append("g") .attr("class", "contracts") .append("path") .datum(data) .attr("d", line); var voronoiGroup = svg.append("g") .attr("class", "voronoi"); voronoiGroup.selectAll("path") .data(voronoi.polygons(data)) .enter().append("path") .attr("d", function(d) { return d ? "M" + d.join("L") + "Z" : null; }) .on("mouseover", mouseover) .on("mouseout", mouseout); var focus = svg.append("g") .attr("transform", "translate(-100,-100)") .attr("class", "focus"); var tooltip = d3.select("body") .append("div") .attr("class", "tooltip") .style("position", "absolute") .style("z-index", "10") .style("display", "none"); self.focus = focus; self.tooltip = tooltip; function mouseover(d) { focus = self.focus; tooltip = self.tooltip; focus.attr("transform", "translate(" + self.x(d.data[self.xColumn]) + "," + self.y(d.data[self.yColumn]) + ")"); tooltip.selectAll("div").remove() tooltip.append("div") .attr("class", "tooltip-top") .text(function() { return d3.timeFormat("%x")(d.data[self.xColumn]) }) tooltip.append("div") .attr("class", "tooltip-bottom") .text("$"+d.data[self.yColumn]) tooltip.style("display", "block") .style("top", (self.y(d.data[self.yColumn])-40) + "px") .style("left", (self.x(d.data[self.xColumn])+10) + "px") tooltip.append("div") .attr("class", "tooltip-arrow") } function mouseout(d) { self.tooltip.style("display","none") self.focus.attr("transform", "translate(-100,-100)"); } } function resize() { initialize(this.opts); } } g3.timeseries({ data: data, margin: {top: 20, right: 20, bottom: 30, left: 50}, axis: { x: { column: "date", format: function(d) { return d3.timeParse("%d-%b-%y")(d); } }, y: { column: "close", format: function(d) { return +d; } } } }); </script> </body>
https://d3js.org/d3.v4.min.js