Example of a scatter plot with brush using d3.js v4.
Tutorial at http://www.rajvansia.com/scatterplotbrush-d3-v4.html
Adapted from https://bl.ocks.org/mbostock/34f08d5e11952a80609169b7917d4172
| license: gpl-3.0 |
Example of a scatter plot with brush using d3.js v4.
Tutorial at http://www.rajvansia.com/scatterplotbrush-d3-v4.html
Adapted from https://bl.ocks.org/mbostock/34f08d5e11952a80609169b7917d4172
| <!DOCTYPE html> | |
| <!-- adapted from mbostock v4 area brush http://bl.ocks.org/mbostock/34f08d5e11952a80609169b7917d4172--> | |
| <meta charset="utf-8"> | |
| <body> | |
| <script src="https://d3js.org/d3.v4.min.js"></script> | |
| <script> | |
| // Commented version of | |
| // http://bl.ocks.org/rajvansia/ce6903fad978d20773c41ee34bf6735c | |
| // Variables | |
| // Height - focus | |
| // Height2 - context | |
| var margin = {top: 20, right: 20, bottom: 110, left: 50}, | |
| margin2 = {top: 430, right: 20, bottom: 30, left: 40}, | |
| width = 960 - margin.left - margin.right, | |
| height = 500 - margin.top - margin.bottom, | |
| height2 = 500 - margin2.top - margin2.bottom; | |
| // Date Parser takes in Date string and returns JS Data Object | |
| var parseDate = d3.timeParse("%b %Y"); | |
| // Chart Scales | |
| // x, y -> Focus | |
| // x2, y2 -> Context | |
| var x = d3.scaleTime().range([0, width]), | |
| x2 = d3.scaleTime().range([0, width]), | |
| y = d3.scaleLinear().range([height, 0]), | |
| y2 = d3.scaleLinear().range([height2, 0]); | |
| // Chart Axis | |
| var xAxis = d3.axisBottom(x), | |
| xAxis2 = d3.axisBottom(x2), | |
| yAxis = d3.axisLeft(y); | |
| // Define Brush, extent, and what function to run on "brush" | |
| var brush = d3.brushX() | |
| .extent([[0, 0], [width, height2]]) | |
| .on("brush", brushed); | |
| // Define inner drawing space with D3 Marging Convention | |
| var svg = d3.select("body").append("svg") | |
| .attr("width", width + margin.left + margin.right) | |
| .attr("height", height + margin.top + margin.bottom); | |
| // Define clippath | |
| svg.append("defs").append("clipPath") | |
| .attr("id", "clip") | |
| .append("rect") | |
| .attr("width", width) | |
| .attr("height", height); | |
| // Define focus "g" and where it will live | |
| var focus = svg.append("g") | |
| .attr("class", "focus") | |
| .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
| // Define context "g" and where it will live | |
| var context = svg.append("g") | |
| .attr("class", "context") | |
| .attr("transform", "translate(" + margin2.left + "," + margin2.top + ")"); | |
| // CSV AJAX call to get data | |
| // Run type function to pre-process ingested data | |
| // Call-back function to process data once parsed and pre-processed | |
| d3.csv("sp500.csv", type, function(error, data) { | |
| if (error) throw error; | |
| // Update scale domains, now that we have the data | |
| x.domain(d3.extent(data, function(d) { return d.date; })); | |
| y.domain([0, d3.max(data, function(d) { return d.price; })+200]); | |
| x2.domain(x.domain()); | |
| y2.domain(y.domain()); | |
| // Append scatter plot to Focus chart area | |
| // Make sure to clip the path | |
| // Do a data join | |
| var dots = focus.append("g"); | |
| dots.attr("clip-path", "url(#clip)"); | |
| dots.selectAll("dot") | |
| .data(data) | |
| .enter().append("circle") | |
| .attr('class', 'dot') | |
| .attr("r",5) | |
| .style("opacity", .5) | |
| .attr("cx", function(d) { return x(d.date); }) | |
| .attr("cy", function(d) { return y(d.price); }) | |
| // Create the Focus X Axis | |
| focus.append("g") | |
| .attr("class", "axis axis--x") | |
| .attr("transform", "translate(0," + height + ")") | |
| .call(xAxis); | |
| // Create the Focus Y Axis | |
| focus.append("g") | |
| .attr("class", "axis axis--y") | |
| .call(yAxis); | |
| // Create the Focus Y Axis Text Label | |
| focus.append("text") | |
| .attr("transform", "rotate(-90)") | |
| .attr("y", 0 - margin.left) | |
| .attr("x",0 - (height / 2)) | |
| .attr("dy", "1em") | |
| .style("text-anchor", "middle") | |
| .text("Price"); | |
| // Create the Context X Axis Text Label | |
| svg.append("text") | |
| .attr("transform", | |
| "translate(" + ((width + margin.right + margin.left)/2) + " ," + | |
| (height + margin.top + margin.bottom) + ")") | |
| .style("text-anchor", "middle") | |
| .text("Date"); | |
| // append scatter plot to brush chart area | |
| var dots = context.append("g"); | |
| // Attach the clip-path to the dots in the Focus chart | |
| dots.attr("clip-path", "url(#clip)"); | |
| // Create the dots through the data join in the context chart | |
| dots.selectAll("dot") | |
| .data(data) | |
| .enter().append("circle") | |
| .attr('class', 'dotContext') | |
| .attr("r",3) | |
| .style("opacity", .5) | |
| .attr("cx", function(d) { return x2(d.date); }) | |
| .attr("cy", function(d) { return y2(d.price); }) | |
| // Create the Context X Axis | |
| context.append("g") | |
| .attr("class", "axis axis--x") | |
| .attr("transform", "translate(0," + height2 + ")") | |
| .call(xAxis2); | |
| // ** Note that this example doesn't show a Context Y Axis | |
| // Add the brush functionality to the context graph | |
| // Initialize the initial brush to cover the full context graph rage | |
| context.append("g") | |
| .attr("class", "brush") | |
| .call(brush) | |
| .call(brush.move, x.range()); | |
| }); | |
| //create brush function redraw scatterplot with selection | |
| function brushed() { | |
| var selection = d3.event.selection; | |
| x.domain(selection.map(x2.invert, x2)); | |
| focus.selectAll(".dot") | |
| .attr("cx", function(d) { return x(d.date); }) | |
| .attr("cy", function(d) { return y(d.price); }); | |
| focus.select(".axis--x").call(xAxis); | |
| } | |
| // Function to process the data when it gets ingested by the AJAX call | |
| function type(d) { | |
| d.date = parseDate(d.date); | |
| d.price = +d.price; | |
| return d; | |
| } | |
| </script> |
| date | price | |
|---|---|---|
| Jan 2000 | 1394.46 | |
| Feb 2000 | 1366.42 | |
| Mar 2000 | 1498.58 | |
| Apr 2000 | 1452.43 | |
| May 2000 | 1420.6 | |
| Jun 2000 | 1454.6 | |
| Jul 2000 | 1430.83 | |
| Aug 2000 | 1517.68 | |
| Sep 2000 | 1436.51 | |
| Oct 2000 | 1429.4 | |
| Nov 2000 | 1314.95 | |
| Dec 2000 | 1320.28 | |
| Jan 2001 | 1366.01 | |
| Feb 2001 | 1239.94 | |
| Mar 2001 | 1160.33 | |
| Apr 2001 | 1249.46 | |
| May 2001 | 1255.82 | |
| Jun 2001 | 1224.38 | |
| Jul 2001 | 1211.23 | |
| Aug 2001 | 1133.58 | |
| Sep 2001 | 1040.94 | |
| Oct 2001 | 1059.78 | |
| Nov 2001 | 1139.45 | |
| Dec 2001 | 1148.08 | |
| Jan 2002 | 1130.2 | |
| Feb 2002 | 1106.73 | |
| Mar 2002 | 1147.39 | |
| Apr 2002 | 1076.92 | |
| May 2002 | 1067.14 | |
| Jun 2002 | 989.82 | |
| Jul 2002 | 911.62 | |
| Aug 2002 | 916.07 | |
| Sep 2002 | 815.28 | |
| Oct 2002 | 885.76 | |
| Nov 2002 | 936.31 | |
| Dec 2002 | 879.82 | |
| Jan 2003 | 855.7 | |
| Feb 2003 | 841.15 | |
| Mar 2003 | 848.18 | |
| Apr 2003 | 916.92 | |
| May 2003 | 963.59 | |
| Jun 2003 | 974.5 | |
| Jul 2003 | 990.31 | |
| Aug 2003 | 1008.01 | |
| Sep 2003 | 995.97 | |
| Oct 2003 | 1050.71 | |
| Nov 2003 | 1058.2 | |
| Dec 2003 | 1111.92 | |
| Jan 2004 | 1131.13 | |
| Feb 2004 | 1144.94 | |
| Mar 2004 | 1126.21 | |
| Apr 2004 | 1107.3 | |
| May 2004 | 1120.68 | |
| Jun 2004 | 1140.84 | |
| Jul 2004 | 1101.72 | |
| Aug 2004 | 1104.24 | |
| Sep 2004 | 1114.58 | |
| Oct 2004 | 1130.2 | |
| Nov 2004 | 1173.82 | |
| Dec 2004 | 1211.92 | |
| Jan 2005 | 1181.27 | |
| Feb 2005 | 1203.6 | |
| Mar 2005 | 1180.59 | |
| Apr 2005 | 1156.85 | |
| May 2005 | 1191.5 | |
| Jun 2005 | 1191.33 | |
| Jul 2005 | 1234.18 | |
| Aug 2005 | 1220.33 | |
| Sep 2005 | 1228.81 | |
| Oct 2005 | 1207.01 | |
| Nov 2005 | 1249.48 | |
| Dec 2005 | 1248.29 | |
| Jan 2006 | 1280.08 | |
| Feb 2006 | 1280.66 | |
| Mar 2006 | 1294.87 | |
| Apr 2006 | 1310.61 | |
| May 2006 | 1270.09 | |
| Jun 2006 | 1270.2 | |
| Jul 2006 | 1276.66 | |
| Aug 2006 | 1303.82 | |
| Sep 2006 | 1335.85 | |
| Oct 2006 | 1377.94 | |
| Nov 2006 | 1400.63 | |
| Dec 2006 | 1418.3 | |
| Jan 2007 | 1438.24 | |
| Feb 2007 | 1406.82 | |
| Mar 2007 | 1420.86 | |
| Apr 2007 | 1482.37 | |
| May 2007 | 1530.62 | |
| Jun 2007 | 1503.35 | |
| Jul 2007 | 1455.27 | |
| Aug 2007 | 1473.99 | |
| Sep 2007 | 1526.75 | |
| Oct 2007 | 1549.38 | |
| Nov 2007 | 1481.14 | |
| Dec 2007 | 1468.36 | |
| Jan 2008 | 1378.55 | |
| Feb 2008 | 1330.63 | |
| Mar 2008 | 1322.7 | |
| Apr 2008 | 1385.59 | |
| May 2008 | 1400.38 | |
| Jun 2008 | 1280 | |
| Jul 2008 | 1267.38 | |
| Aug 2008 | 1282.83 | |
| Sep 2008 | 1166.36 | |
| Oct 2008 | 968.75 | |
| Nov 2008 | 896.24 | |
| Dec 2008 | 903.25 | |
| Jan 2009 | 825.88 | |
| Feb 2009 | 735.09 | |
| Mar 2009 | 797.87 | |
| Apr 2009 | 872.81 | |
| May 2009 | 919.14 | |
| Jun 2009 | 919.32 | |
| Jul 2009 | 987.48 | |
| Aug 2009 | 1020.62 | |
| Sep 2009 | 1057.08 | |
| Oct 2009 | 1036.19 | |
| Nov 2009 | 1095.63 | |
| Dec 2009 | 1115.1 | |
| Jan 2010 | 1073.87 | |
| Feb 2010 | 1104.49 | |
| Mar 2010 | 1140.45 |