Based on this block by Mike Bostock which uses an invisible Voronoi tessellation to handle mouseover.
| Year | type | number | |
|---|---|---|---|
| 1990 | corn | 4 | |
| 1990 | apples | 242 | |
| 1990 | wheat | 45 | |
| 1991 | corn | 211 | |
| 1991 | apples | 6 | |
| 1991 | wheat | 7 | |
| 1992 | corn | 8 | |
| 1992 | apples | 9 | |
| 1992 | wheat | 10 | |
| 1993 | corn | 11 | |
| 1993 | apples | 223 | |
| 1993 | wheat | 124 | |
| 1994 | corn | 14 | |
| 1994 | apples | 15 | |
| 1994 | wheat | 16 | |
| 1995 | corn | 17 | |
| 1995 | apples | 18 | |
| 1995 | wheat | 19 | |
| 1996 | corn | 20 | |
| 1996 | apples | 220 | |
| 1996 | wheat | 22 | |
| 1997 | corn | 152 | |
| 1997 | apples | 24 | |
| 1997 | wheat | 25 | |
| 1998 | corn | 206 | |
| 1998 | apples | 12 | |
| 1998 | wheat | 28 | |
| 1999 | corn | 128 | |
| 1999 | apples | 30 | |
| 1999 | wheat | 31 | |
| 2000 | corn | 32 | |
| 2000 | apples | 33 | |
| 2000 | wheat | 34 |
| <!DOCTYPE html> | |
| <head> | |
| <meta charset="utf-8"> | |
| <style> | |
| #graph{ | |
| width:80%; | |
| height:200px; | |
| } | |
| g.crop{ | |
| width:900px; | |
| height:200px; | |
| } | |
| #graph .axis path { | |
| fill: none; | |
| stroke: #ccc; | |
| shape-rendering: crispEdges; | |
| } | |
| #graph .axis text { | |
| font-family: Helvetica, Arial, sans-serif; | |
| font-size: 13px; | |
| fill:#333; | |
| } | |
| .axis path, | |
| .axis line { | |
| fill: #888888; | |
| stroke: #000; | |
| shape-rendering: crispEdges; | |
| } | |
| .corn{ | |
| stroke:#ff3300; | |
| } | |
| .apples{ | |
| stroke:#7ac000; | |
| } | |
| .wheat{ | |
| stroke:#0088c0; | |
| } | |
| .focus text { | |
| text-anchor: middle; | |
| text-shadow: 0 1px 0 #fff, 1px 0 0 #fff, 0 -1px 0 #fff, -1px 0 0 #fff; | |
| } | |
| .voronoi path { | |
| fill: none; | |
| pointer-events: all; | |
| } | |
| .voronoi--show path { | |
| stroke: red; | |
| stroke-opacity: .2; | |
| } | |
| .line-hover { | |
| stroke: #000; | |
| stroke-width:3; | |
| } | |
| </style> | |
| <title>Graph, Voronoi</title> | |
| </head> | |
| <body> | |
| <label id="form" for="show-voronoi"> | |
| Show Voronoi | |
| <input type="checkbox" id="show-voronoi" disabled> | |
| </label> | |
| <svg id="graph"></svg> | |
| <script src="http://d3js.org/d3.v3.min.js"></script> | |
| <script> | |
| d3.csv("data.csv", function(error, data) { | |
| data.forEach(function(d) { | |
| d.Year = +d.Year; | |
| d.number = +d.number; | |
| }); | |
| var graph = d3.select("#graph") | |
| xScale = d3.scale.linear().range([100, 980]).domain([1990,2000]), | |
| yScale = d3.scale.linear().range([180, 20]).domain([0,225]), | |
| xAxis = d3.svg.axis().scale(xScale).tickFormat(d3.format('0f')), | |
| yAxis = d3.svg.axis().scale(yScale).orient("left"); | |
| graph.append("svg:g") | |
| .attr("transform", "translate(0,180)") | |
| .attr("class", "axis") | |
| .call(xAxis); | |
| graph.append("svg:g") | |
| .attr("transform", "translate(100,0)") | |
| .attr("class", "axis") | |
| .call(yAxis); | |
| var kind = d3.nest() | |
| .key(function(d) { return d.type; }) | |
| .entries(data); | |
| var vor = d3.nest() | |
| .key(function(d) { return xScale(d.Year) + "," + yScale(d.number); }) | |
| .rollup(function(v) { return v[0]; }) | |
| .entries(d3.merge(kind.map(function(d) { return d.values; }))) | |
| .map(function(d) { return d.values; }); | |
| console.log(vor); | |
| var voronoi = d3.geom.voronoi() | |
| .x(function(d) { return xScale(d.Year); }) | |
| .y(function(d) { return yScale(d.number); }) | |
| .clipExtent([[100,0], [1000,200]]); | |
| var line = d3.svg.line() | |
| .x(function(d){return xScale(d.Year);}) | |
| .y(function(d){return yScale(d.number);}); | |
| graph.append("g") | |
| .attr("class", "crops") | |
| .selectAll("path") | |
| .data(kind) | |
| .enter().append("path") | |
| .attr("class", function(d){return "crop " + d.key; }) | |
| .attr("fill", "none") | |
| .attr("d", function(d){ d.line = this; return line(d.values); }); | |
| var focus = graph.append("g") | |
| .attr("transform", "translate(-100,-100)") | |
| .attr("class", "focus"); | |
| focus.append("circle") | |
| .attr("r", 3.5); | |
| focus.append("text") | |
| .attr("y", -10); | |
| var voronoiGroup = graph.append("g") | |
| .attr("class", "voronoi"); | |
| voronoiGroup.selectAll("path") | |
| .data(voronoi(vor)) | |
| .enter().append("path") | |
| .attr("d", function(d) { return "M" + d.join("L") + "Z"; }) | |
| .datum(function(d) { return d.value; }) | |
| .on("mouseover", mouseover) | |
| .on("mouseout", mouseout); | |
| d3.select("#show-voronoi") | |
| .property("disabled", false) | |
| .on("change", function() { voronoiGroup.classed("voronoi--show", this.checked); }); | |
| function mouseover(d) { | |
| d3.select('.crop').classed("line-hover", true); | |
| focus.attr("transform", "translate(" + xScale(d.Year) + "," + yScale(d.number) + ")"); | |
| focus.select("text").text(d.number); | |
| } | |
| function mouseout(d) { | |
| d3.select('.crop').classed("line-hover", false); | |
| focus.attr("transform", "translate(-100,-100)"); | |
| } | |
| }); | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment