Integrating d3 with meteor? Trying to draw pie charts - d3.js
I'm trying to draw pie charts in Meteor, but I'm very new to both d3 and Meteor and am not really understanding what is going on.
The following d3 code to draw pie charts from a csv file works for me outside of Meteor:
<!DOCTYPE html>
<meta charset="utf-8">
<link href='http://fonts.googleapis.com/css?family=Montserrat:400,700' rel='stylesheet' type='text/css'>
<style>
body {
font: 30px "Montserrat";
text-transform:uppercase;
}
svg {
padding: 10px 0 0 10px;
}
.arc {
stroke: #fff;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var radius = 150,
padding = 10;
var color = d3.scale.ordinal()
.range(["#f65c55","#c8e7ec"]);
var arc = d3.svg.arc()
.outerRadius(radius)
.innerRadius(radius - 40);
var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d.population; });
d3.csv("data.csv", function(error, data) {
color.domain(d3.keys(data[0]).filter(function(key) { return key !== "Criteria"; }));
data.forEach(function(d) {
d.ages = color.domain().map(function(name) {
return {name: name, population: +d[name]};
});
});
var legend = d3.select("body").append("svg")
.attr("class", "legend")
.attr("width", radius * 2)
.attr("height", radius * 2)
.selectAll("g")
.data(color.domain().slice().reverse())
.enter().append("g")
.attr("transform", function(d, i) { return "translate(0," + i * 50 + ")"; });
legend.append("rect")
.attr("width", 40)
.attr("height", 40)
.style("fill", color);
legend.append("text")
.attr("x", 50)
.attr("y", 20)
.attr("dy", ".35em")
.attr("font-size","20px")
.text(function(d) { return d; });
var svg = d3.select("body").selectAll(".pie")
.data(data)
.enter().append("svg")
.attr("class", "pie")
.attr("width", radius * 2)
.attr("height", radius * 2)
.append("g")
.attr("transform", "translate(" + radius + "," + radius + ")");
svg.selectAll(".arc")
.data(function(d) { return pie(d.ages); })
.enter().append("path")
.attr("class", "arc")
.attr("d", arc)
.style("fill", function(d) { return color(d.data.name); });
svg.append("text")
.attr("dy", ".35em")
.style("text-anchor", "middle")
.text(function(d) { return d.Criteria; });
});
</script>
I also have a Meteor template as follows that I want to draw these charts in:
<div class="tab-pane active" id="playback">
{{> playback}}
</div>
However, when I try and follow web tutorials to integrate the two, the graphs don't get drawn. Can anyone help me understand why? Thanks in advance!
EDIT: forgot to mention, data.csv looks like this:
Criteria,Disapproval, Approval
Too Fast,1,2
Too Slow,5,6
Clarity,2,3
Legibility,202070,343207
The first line is for the legend, and the rest are for 4 separate graphs.
You have to make sure that the template is rendered before you access the DOM elements by code. So put your D3 code inside a template rendered method, like this:
Template.playback.rendered = function() {
// your D3 code
}
or on the body tag e.g.:
UI.body.rendered = function() {
// your D3 code
}
Template.chart.rendered = function(){
Deps.autorun(function () {
//d3 codeing here!!
}
}
It's working for me. If you're coding without Deps.autorun() it's will not render.
Oh!! one morething at html page in you case maybe .
However for my case I using nvd3.org http://nvd3.org/livecode/index.html#codemirrorNav. And this I hope you will clearify.
Related
d3-zoom mouseup event workaround
I'm aware that starting with v4 d3-zoom swallows up certain events for some reasons I don't fully understand. I've read some discussions about this, and I know that if I stopPropagation() on mousedown, then the zoom behavior won't get a chance to consume the event, and mouseup will consequently fire. The problem with that is that then the zoom doesnt work. I haven't found a workaround for the case of needing to handle the mouseup event AND still have the zoom work. I'm particularly interested in the dragging case only. When the user does mousedown and starts to drag the canvas, I want to change the cursor to a clenched-hand, and when the user stops dragging and lets go of the mouse I want to change the cursor back. How is this possible to do with the new d3-zoom behavior without resorting to a timeout? 'click' event is also not an option since that doesn't fire if there's a mousemove event in between.
I am concluding from your question that you are not able to track mouseup event after dragging the canvas. If that is the case then we can use events provided by "zoom" functionality - zoomstart and zoomend. We can simply add that to zoom behavior and track when the user starts zoom and ends zoom. And in this way we can easily change cursor property. Please find below code snippet and working code as well. Please let me know if i am missing anything. var margin = { top: -5, right: -5, bottom: -5, left: -5 }, width = 460 - margin.left - margin.right, height = 300 - margin.top - margin.bottom; var zoom = d3.zoom() .scaleExtent([1, 10]) .on("zoom", zoomed) .on("start", function() { document.getElementsByTagName("svg")[0].style.cursor = "grab"; }) .on("end", function() { document.getElementsByTagName("svg")[0].style.cursor = "default"; }) console.log(zoom.scaleExtent()[0], zoom.scaleExtent()[1]); var drag = d3.drag() .subject(function(d) { return d; }) .on("start", dragstarted) .on("drag", dragged) .on("end", dragended); var slider = d3.select("body").append("p").append("input") .datum({}) .attr("type", "range") .attr("value", zoom.scaleExtent()[0]) .attr("min", zoom.scaleExtent()[0]) .attr("max", zoom.scaleExtent()[1]) .attr("step", (zoom.scaleExtent()[1] - zoom.scaleExtent()[0]) / 100) .on("input", slided); var svg = d3.select("body").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.right + ")") .call(zoom); var rect = svg.append("rect") .attr("width", width) .attr("height", height) .style("fill", "none") .style("pointer-events", "all"); var container = svg.append("g"); container.append("g") .attr("class", "x axis") .selectAll("line") .data(d3.range(0, width, 10)) .enter().append("line") .attr("x1", function(d) { return d; }) .attr("y1", 0) .attr("x2", function(d) { return d; }) .attr("y2", height); container.append("g") .attr("class", "y axis") .selectAll("line") .data(d3.range(0, height, 10)) .enter().append("line") .attr("x1", 0) .attr("y1", function(d) { return d; }) .attr("x2", width) .attr("y2", function(d) { return d; }); dots = [{ x: 100, y: 100, }] dot = container.append("g") .attr("class", "dot") .selectAll("circle") .data(dots) .enter().append("circle") .attr("r", 5) .attr("cx", function(d) { return d.x; }) .attr("cy", function(d) { return d.y; }) .call(drag); function dottype(d) { d.x = +d.x; d.y = +d.y; return d; } function zoomed(event) { const currentTransform = d3.event.transform; container.attr("transform", currentTransform); slider.property("value", currentTransform.k); } function dragstarted(d) { d3.event.sourceEvent.stopPropagation(); d3.select(this).classed("dragging", true); } function dragged(d) { d3.select(this).attr("cx", d.x = d3.event.x).attr("cy", d.y = d3.event.y); } function dragended(d) { d3.select(this).classed("dragging", false); } function slided(d) { zoom.scaleTo(svg, d3.select(this).property("value")); } .dot circle { fill: lightsteelblue; stroke: steelblue; stroke-width: 1.5px; } .dot circle.dragging { fill: red; stroke: brown; } .axis line { fill: none; stroke: #ddd; shape-rendering: crispEdges; } <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <style> </style> <title></title> </head> <body> <script src="https://d3js.org/d3.v4.min.js"></script> </body> </html> var zoom = d3.zoom() .scaleExtent([1, 10]) .on("zoom", zoomed) .on("start", function() { document.getElementsByTagName("svg")[0].style.cursor = "grab"; }) .on("end", function() { document.getElementsByTagName("svg")[0].style.cursor = "default"; })
D3Js.v5: ...selectAll(...).data(...).enter is not a function
I'm learning D3 JS, and I'm trying to replicate the D3 bar chart tutorial here. It works as is using d3.v3, but the moment I change the src to d3.d5 by changing: <!DOCTYPE html> <meta charset="utf-8"> <style> //Irrelevant CSS... </style> <svg class="chart"></svg> <script src="https://d3js.org/d3.v5.min.js"></script> //Changed to d3.v5 <script> var width = 420, barHeight = 20; var x = d3.scale.linear() .range([0, width]); var chart = d3.select(".chart") .attr("width", width); d3.tsv("data.tsv", type, function(error, data) { x.domain([0, d3.max(data, function(d) { return d.value; })]); chart.attr("height", barHeight * data.length); var bar = chart.selectAll("g") .data(data) .enter().append("g") .attr("transform", function(d, i) { return "translate(0," + i * barHeight + ")"; }); bar.append("rect") .attr("width", function(d) { return x(d.value); }) .attr("height", barHeight - 1); bar.append("text") .attr("x", function(d) { return x(d.value) - 3; }) .attr("y", barHeight / 2) .attr("dy", ".35em") .text(function(d) { return d.value; }); }); function type(d) { d.value = +d.value; // coerce to number return d; } </script> I get an error: Uncaught (in promise) TypeError: chart.selectAll(...).data(...).enter is not a function I'd rather learn the latest and greatest, which I assume is D3.v5, instead of D3.v3, unless the latter really is the latest stable build. Was there a syntax change in this method chain? because I thought .selectAll(...).data(...).enter would be a pretty "standard" method chain. This has been surprisingly resistant to googling, unfortunately; similar problems are much more complex use-cases with many more degrees of freedom, whereas my question simply involves changing the D3 version.
I see 2 problems with your solution: Change d3.scale.linear() to d3.scaleLinear() Change d3.tsv("data.tsv", type, function(error, data) { to d3.tsv("data.tsv").then(function(data) { Explanation for 2: d3.tsv function returns a promise which needs to be resolved before you can use the data
d3 line graph using csv
I have a data in csv like this: date,partner,units 2012-05-01,team1,34.12 2012-04-30,team1,45.56 2012-04-27,team2,67.89 2012-04-26,team1,78.54 2012-04-25,team2,89.23 2012-04-24,team2,99.23 2012-04-23,team2,101.34 I want to plot two lines (one for team1, one for team2 using this data), but I am just getting a scatterplot using the following complete d3 code, is my filtering wrong? <!DOCTYPE html> <meta charset="utf-8"> <style> /* set the CSS */ #line1 { fill: none; stroke: steelblue; stroke-width: 2px; } #line2 { fill: none; stroke: red; stroke-width: 2px; } </style> <input type="button" onclick="hideLine()"> <input type="button" onclick="showLine()"> <!-- load the d3.js library --> <script src="https://d3js.org/d3.v4.min.js"></script> <script> // set the dimensions and margins of the graph var margin = {top: 20, right: 20, bottom: 30, left: 50}, width = 960 - margin.left - margin.right, height = 500 - margin.top - margin.bottom; // parse the date / time var parseTime = d3.timeParse("%Y-%m-%d"); // set the ranges var x = d3.scaleTime().range([0, width]); var y = d3.scaleLinear().range([height, 0]); // define the 1st line var valueline = d3.line() .x(function(d) { return x(d.date); }) .y(function(d) { return y(d.units); }); // define the 2nd line var valueline2 = d3.line() .x(function(d) { return x(d.date); }) .y(function(d) { return y(d.units); }); var svg = d3.select("body").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 + ")"); // Get the data d3.csv("data1.csv", function(error, data) { if (error) throw error; // format the data data.forEach(function(d) { d.date = parseTime(d.date); d.units = +d.units; }); // Scale the range of the data x.domain(d3.extent(data, function(d) { return d.date; })); m = d3.max(data, function(d) { var m = d.units; return m; }); console.log("Max:", m); y.domain([0,m]); // Add the valueline path. svg.append("path") .data([data]) .filter(function(d) { return d.partner == 'team1'; }) .attr("id", "line1") .attr("d", valueline); console.log("DATA", data) svg.selectAll(".point") .data(data) .enter() .append("circle") .attr("class", "point") .attr("cx", function (d, i) { return x(d.date); }) .attr("cy", function(d) { return y(d.units); }) .attr("r", 4) .on("mouseover", function(d) { console.log(d.units) }); // Add the valueline2 path. svg.append("path") .data([data]) .filter(function(d) { return d.partner == 'team2'; }) .attr("id", "line2") .style("stroke", "red") .attr("d", valueline2) .on("mouseover", function(d) {console.log(d)}); // Add the X Axis svg.append("g") .attr("transform", "translate(0," + height + ")") .call(d3.axisBottom(x)); // Add the Y Axis svg.append("g") .call(d3.axisLeft(y)); }); function hideLine() { console.log("Hideline"); d3.select("#line2").attr("style", "opacity:0"); } function showLine() { console.log("ShowLine"); d3.select("#line2").attr("style", "opacity:1"); } </script> </body>
Yes, your filter is wrong. You are wrapping your data in another [] which means the filter is only operating on the outer array. Do this instead: svg.append("path") .datum(data.filter(function(d) { return d.partner == 'team1'; })) .attr("id", "line1") .attr("d", valueline); Working example here.
D3.js How to hide/show line when click select options?
I tried to use D3.js to draw lines when you click on different checkbox. It will get data of that option. Here is an example I used D3 multi-series line chart with tooltips and legend. I have got the specific data object that is corresponding the checkbox I choose. Howevery, I don't know how to draw it on svg. Please help me and I will appreciate you so much. I also find a website "www.cotrino.com/starpaths/" that shows the final effect I want to implement. My D3 effect <!DOCTYPE html> <meta charset="utf-8"> <style> .axis--x path { display: none; } .line { fill: none; stroke: steelblue; stroke-width: 1.5px; } </style> <script src="http://d3js.org/d3.v4.js"></script> <body> <svg width="1000" height="500"></svg> <div id="disease_list"></div> </body> <script> var svg = d3.select("svg"), margin = {top: 20, right: 80, bottom: 30, left: 50}, width = svg.attr("width") - margin.left - margin.right, height = svg.attr("height") - margin.top - margin.bottom, g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")"); //make a clip path for the graph var clip = svg.append("svg:clipPath") .attr("id", "clip") .append("svg:rect") .attr("x", 0) .attr("y", 0) .attr("width", width) .attr("height", height); var parseTime = d3.timeParse("%Y-%m"); var x = d3.scaleTime().range([0, width]), y = d3.scaleLinear().range([height, 0]); var line = d3.line() .curve(d3.curveBasis) .x(function(d) { console.log(d.date); return x(d.date); }) .y(function(d) { console.log(d.date); return y(d.count); }); var color = d3.scaleOrdinal(d3.schemeCategory20); d3.csv("./top10highestNormalize.csv", type, function(error, data) { if (error) throw error; var diseases = data.columns.slice(1).map(function(id) { return { id: id, values: data.map(function(d) { return {date: d.date, count: d[id]}; }) }; }); console.log(diseases); x.domain(d3.extent(data, function(d) { return d.date; })); y.domain([ d3.min(diseases, function(c) { return d3.min(c.values, function(d) { return d.count; }); }), d3.max(diseases, function(c) { return d3.max(c.values, function(d) { return d.count; }); }) ]); g.append("g") .attr("class", "axis axis--x") .attr("transform", "translate(0," + height + ")") .call(d3.axisBottom(x)); g.append("g") .attr("class", "axis axis--y") .call(d3.axisLeft(y)) .append("text") .attr("transform", "rotate(-90)") .attr("y", 6) .attr("dy", "0.71em") .attr("fill", "#000") .text("Count"); /* var disease = g.selectAll(".disease") .data(diseases) .enter().append("g") .attr("class", "disease"); */ // Create the shape selectors var selector = d3.select("#disease_list").append("select"); labels = selector.selectAll("option") .data(diseases) .enter() .append("option") .attr("value",function(d,i) {return i;}) .text(function(d) {return d.id;}); var menu = d3.select("#disease_list select") .on("change", redraw); // var series = menu.property("value"); //console.log(series); // all the meat goes in the redraw function function redraw() { console.log("redraw start"); // get value from menu selection // the option values are set in HTML and correspond //to the [type] value we used to nest the data var series = menu.property("value"); console.log(series); // only retrieve data from the selected series, using the nest we just created var adata = diseases[series]; console.log(adata); } }); function type(d, _, columns) { d.date = parseTime(d.date); for (var i = 1, n = columns.length, c; i < n; ++i) d[c = columns[i]] = +d[c]; return d; } </script> top10highestNormalize.csv date,disseminated sclerosis,sclerosis,gestural tics,venereal disease,bite,cot death,venereal disease,cardiovascular disease,diseases vascular,pruritis,pus,cystic fibrosis,fibroses 2010-04,0,0,0,0,0,0,0,0,0,0,0,0,0 2010-05,0,0,0.06898023,0.068783069,0.085790885,0.065761258,0.068783069,0,0,0.001204094,0.023051592,0,0 2010-06,0.076923077,0.076923077,0.190584554,0.199972867,0.201072386,0.171789373,0.199972867,0.071428571,0.071428571,0.004816376,0.031284303,0.2,0.2 2010-07,0.230769231,0.230769231,0.221590101,0.224664225,0.225201072,0.235167977,0.224664225,0.214285714,0.285714286,0.00602047,0.038419319,0,0 2010-08,0.538461538,0.538461538,0.174797326,0.182471849,0.174262735,0.192041935,0.182471849,0.071428571,0.071428571,0.003612282,0.023051592,0,0 2010-09,0.230769231,0.230769231,0.287725786,0.277845611,0.252010724,0.259471051,0.277845611,0,0,0.004214329,0.046652031,0,0 2010-10,0.076923077,0.076923077,0.295406059,0.299416633,0.285969616,0.265665952,0.299416633,0,0.071428571,0.007224564,0.03402854,0.066666667,0.066666667 2010-11,0.153846154,0.153846154,0.284027877,0.279337946,0.261840929,0.276149631,0.279337946,0,0,0.006622517,0.050493963,0,0 2010-12,0.153846154,0.153846154,0.271511876,0.237552571,0.213583557,0.237312366,0.237552571,0.142857143,0.142857143,0.004214329,0.035126235,0,0 2011-01,0.076923077,0.076923077,0.306642014,0.312440646,0.28150134,0.305694544,0.312440646,0.142857143,0.142857143,0.006622517,0.046103183,0,0.066666667 2011-02,0.076923077,0.076923077,0.288721377,0.262243929,0.219839142,0.25899452,0.262243929,0.142857143,0.142857143,0.007224564,0.038968167,0,0.066666667 2011-03,0.076923077,0.076923077,0.271654103,0.255324922,0.253798034,0.266857279,0.255324922,0.071428571,0.071428571,0.007224564,0.051591658,0,0 2011-04,0.461538462,0.461538462,0.291423695,0.252068919,0.235031278,0.284250655,0.252068919,0,0,0.009030704,0.045005488,0,0 2011-05,0.153846154,0.153846154,0.448158157,0.380681047,0.351206434,0.439123183,0.380681047,0,0,0.011438892,0.079582876,0.333333333,0.4 2011-06,0.153846154,0.153846154,0.498079932,0.437661104,0.391420912,0.424827258,0.437661104,0.142857143,0.142857143,0.009632751,0.063117453,0,0.066666667 2011-07,0,0,0.410467928,0.424094424,0.419124218,0.379080295,0.424094424,0,0.071428571,0.009030704,0.061470911,1,1 2011-08,0.076923077,0.076923077,0.268382876,0.262922263,0.238605898,0.267810341,0.262922263,0.214285714,0.214285714,0.002408188,0.038968167,0,0 2011-09,0.230769231,0.230769231,0.510027023,0.469949803,0.470956211,0.444841553,0.469949803,0,0,0.014449127,0.075740944,0.133333333,0.2 2011-10,0.076923077,0.076923077,0.462380885,0.434540768,0.431635389,0.417679295,0.434540768,0.142857143,0.142857143,0.006622517,0.073545554,0,0.066666667 2011-11,0.153846154,0.153846154,0.519698478,0.457061457,0.415549598,0.443888492,0.457061457,0.142857143,0.142857143,0.01384708,0.06805708,0.2,0.2 2011-12,1,1,0.382449154,0.35002035,0.319928508,0.315701692,0.35002035,0,0,0.002408188,0.060373216,0,0 2012-01,0.461538462,0.461538462,0.492390841,0.45312712,0.409294013,0.45389564,0.45312712,0.571428571,0.571428571,0.007224564,0.060373216,0,0 2012-02,0.076923077,0.076923077,0.382875836,0.375932709,0.350312779,0.369073147,0.375932709,0.071428571,0.071428571,0.003612282,0.049945115,0.066666667,0.066666667 2012-03,0.923076923,1,1,0.922127255,1,0.871098404,0.922127255,0.5,0.5,0.01384708,0.171789243,0,0.066666667 2012-04,0.230769231,0.307692308,0.699331532,0.676977344,0.63360143,0.645699309,0.676977344,0.142857143,0.142857143,0.012040939,0.092206367,0.133333333,0.133333333 2012-05,0.846153846,0.846153846,0.801735173,0.752408086,0.776586238,0.7436264,0.752408086,0.785714286,0.785714286,0.016857315,0.131723381,0.466666667,0.466666667 2012-06,0.384615385,0.461538462,0.730479306,0.732193732,0.625558534,0.657850846,0.732193732,0,0,0.011438892,0.118002195,0.6,0.666666667 2012-07,0.384615385,0.384615385,0.751386716,0.738434405,0.71849866,0.714081487,0.738434405,0.285714286,0.285714286,0.009030704,0.126783754,0.2,0.2 2012-08,0.384615385,0.461538462,0.700327123,0.643467643,0.619302949,0.646890636,0.643467643,0.285714286,0.285714286,0.012642986,0.150933041,0.2,0.266666667 2012-09,0.076923077,0.230769231,0.72137676,0.701804368,0.63538874,0.70455087,0.701804368,0.214285714,0.214285714,0.011438892,0.130076839,0.066666667,0.066666667 2012-10,0.230769231,0.230769231,0.846252311,0.863112196,0.796246649,0.825827972,0.863112196,0.071428571,0.071428571,0.036724865,0.127881449,0.333333333,0.333333333 2012-11,0.692307692,0.692307692,0.895605177,1,0.798927614,0.909935668,1,0.214285714,0.357142857,0.012642986,0.143798024,0,0.133333333 2012-12,0.923076923,1,0.795903854,0.803283137,0.683646113,0.827257565,0.803283137,0.142857143,0.142857143,0.008428657,0.104829857,0.6,0.6 2013-01,0.230769231,0.384615385,0.92106386,0.964862298,0.848078642,0.944007624,0.964862298,0.285714286,0.357142857,0.015653221,0.146542261,0.533333333,0.733333333 2013-02,0.153846154,0.307692308,0.830322856,0.872880206,0.798927614,0.755777937,0.872880206,0.142857143,0.142857143,0.010234798,0.110318332,0,0.066666667 2013-03,0.230769231,0.230769231,0.927037406,0.944105277,0.885612154,0.953061711,0.944105277,0.142857143,0.142857143,0.009632751,0.131174533,0,0.133333333 2013-04,0.384615385,0.384615385,0.796046082,0.775471442,0.671134942,0.715749345,0.775471442,0,0,0.012040939,0.12349067,0.133333333,0.133333333 2013-05,0.923076923,1,0.824633765,0.844254511,0.742627346,0.843697879,0.844254511,0.142857143,0.142857143,0.015653221,0.149286498,0,0 2013-06,0.307692308,0.307692308,0.884369222,0.949667616,0.865951743,1,0.949667616,0.071428571,0.071428571,0.020469597,0.135016465,0.466666667,0.466666667 2013-07,0.461538462,0.461538462,0.864172948,0.935829602,0.843610366,0.939480581,0.935829602,0.071428571,0.071428571,0.015051174,0.128979144,0.066666667,0.2 2013-08,0.153846154,0.153846154,0.670886076,0.738163071,0.753351206,0.821300929,0.738163071,0.071428571,0.214285714,0.012642986,0.098243688,0,0 2013-09,0.230769231,0.230769231,0.876262267,0.861484195,0.744414656,0.996426019,0.861484195,0,0,0.024081878,0.144895719,0.066666667,0.066666667 2013-10,0.615384615,0.615384615,0.917508178,0.885361552,0.806970509,0.841315225,0.885361552,0.642857143,0.642857143,0.030704395,0.115806806,0.2,0.4 2013-11,0,0.076923077,0.857061584,0.903540904,0.791778374,0.845127472,0.903540904,0.5,0.5,0.012642986,0.093852909,0,0 2013-12,0.230769231,0.230769231,0.704878396,0.719169719,0.584450402,0.81915654,0.719169719,0.285714286,0.5,0.015653221,0.108122942,0,0 2014-01,0.461538462,0.461538462,0.900014223,0.856328856,0.717605004,0.98903979,0.856328856,0.357142857,0.5,0.030102348,0.137211855,0,0.066666667 2014-02,0,0,0.707865169,0.703296703,0.63717605,0.796997856,0.703296703,1,1,0.012642986,0.097145993,0,0 2014-03,0.230769231,0.230769231,0.815531219,0.800434134,0.7256479,0.786275911,0.800434134,0.714285714,0.714285714,0.009632751,0.099341383,0.533333333,0.6 2014-04,0.153846154,0.153846154,0.756506898,0.790259124,0.615728329,0.778174887,0.790259124,0,0,0.011438892,0.12349067,0,0 2014-05,0.461538462,0.461538462,0.85990613,0.767331434,0.705987489,0.78008101,0.767331434,0.142857143,0.285714286,0.014449127,0.13611416,0.066666667,0.133333333 2014-06,0.076923077,0.153846154,0.670886076,0.713064713,0.615728329,0.735763641,0.713064713,0.285714286,0.285714286,0.010836845,0.102634468,0,0 2014-07,0.076923077,0.076923077,0.672592803,0.801655135,0.621090259,0.680009531,0.801655135,0.071428571,0.071428571,0.007224564,0.103183315,0,0 2014-08,0.384615385,0.461538462,0.487270659,0.58377425,0.486148347,0.575887539,0.58377425,0.071428571,0.071428571,0.005418423,0.079582876,0,0.133333333 2014-09,0,0.076923077,0.715545442,0.678062678,0.669347632,0.705980462,0.678062678,0,0,0.01384708,0.103183315,0,0.066666667 2014-10,0.230769231,0.307692308,0.742995306,0.723511057,0.630920465,0.679294734,0.723511057,0,0,0.016857315,0.1064764,0,0 2014-11,0,0,0.672735031,0.623388957,0.583556747,0.64927329,0.623388957,0,0,0.004816376,0.115806806,0.066666667,0.066666667 2014-12,0.307692308,0.384615385,0.591096572,0.55704789,0.478999106,0.491303312,0.55704789,0.285714286,0.428571429,0.003010235,0.074643249,0,0 2015-01,0.076923077,0.153846154,0.659223439,0.561117894,0.531724754,0.605432452,0.561117894,0.071428571,0.071428571,0.007224564,0.094401756,0.133333333,0.133333333 2015-02,0.230769231,0.307692308,0.61840421,0.564780898,0.512064343,0.585656421,0.564780898,0.071428571,0.071428571,0.007224564,0.096597146,0,0 2015-03,0,0,0.770302944,0.677927011,0.599642538,0.675482487,0.677927011,0.071428571,0.071428571,0.009632751,0.111964874,0.066666667,0.2 2015-04,0.076923077,0.076923077,0.706016214,0.61687695,0.731903485,0.563497736,0.61687695,0.071428571,0.071428571,0.008428657,0.097145993,0,0 2015-05,0,0.076923077,0.655383303,0.614027947,0.55406613,0.6154396,0.614027947,0.071428571,0.071428571,0.012642986,0.099341383,0,0 2015-06,0,0.076923077,0.564357844,0.540632207,0.527256479,0.598284489,0.540632207,0.142857143,0.142857143,0.00602047,0.091657519,0,0 2015-07,0.076923077,0.076923077,0.486417295,0.525301859,0.511170688,0.566356922,0.525301859,0,0,0.015653221,0.08726674,0.066666667,0.066666667 2015-08,0.230769231,0.230769231,0.408476746,0.386379053,0.320822163,0.465094115,0.386379053,0,0,0.003010235,0.056531284,0,0 2015-09,0.538461538,0.538461538,0.870999858,0.792701126,0.747095621,0.883964737,0.792701126,0,0,0.013245033,0.156421515,0,0 2015-10,0.153846154,0.153846154,0.469492249,0.435490435,0.320822163,0.51227067,0.435490435,0,0,0.174593618,0.221734358,0,0 2015-11,0.153846154,0.153846154,0.322998151,0.309455976,0.273458445,0.346676197,0.309455976,0,0,0.462974112,0.481888035,0.133333333,0.133333333 2015-12,0.076923077,0.076923077,0.342767743,0.309320309,0.27971403,0.384798666,0.309320309,0,0,0.464780253,0.482436883,0.066666667,0.066666667 2016-01,0.307692308,0.384615385,0.415872564,0.349477683,0.358355675,0.442458899,0.349477683,0,0,0.559903672,0.581229418,0.066666667,0.066666667 2016-02,0,0,0.445455838,0.403744404,0.316353887,0.457469621,0.403744404,0,0,0.54846478,0.568605928,0.066666667,0.066666667 2016-03,0,0,0.471198976,0.400352734,0.317247542,0.508220157,0.400352734,0.142857143,0.142857143,0.604455148,0.628430296,0,0 2016-04,0,0,0.582989617,0.570343237,0.575513852,0.603764594,0.570343237,0.214285714,0.214285714,1,1,0,0
You need to create your line variable: var myLine = svg.append("path"); And then, inside redraw(), changing it according to the option selected: myLine.datum(adata.values) .attr("d", line); Here is a demo plunker: https://plnkr.co/edit/YjGO9TLDBXj13JQuO5bm?p=preview PS: I changed your x-scale range: var x = d3.scaleTime().range([margin.left, width]); And also added a call to redraw() when the code runs for the first time.
d3.js: map with concentric circles emanating from dots
Been away from d3.js for a few months... and I've inherited a simple US map with features that someone else started. The features are represented by simple dots of varying sizes. I want to add emanating concentric circles to each dot, similar to the classic Onion example by Mike Bostock: http://bl.ocks.org/mbostock/4503672 (maybe not so ominous looking though) I've got a block set up here: http://bl.ocks.org/mbostock/4503672 (Not sure why the states aren't rendering correctly in the block, but it probably doesn't matter for this.) In Mike's example there is only one dot, so I'm have trouble understanding how to translate what he did to what I've got (many dots). Here's my script: /** * Page initialization */ $(function() { renderMap('#map-container'); }); function renderMap(container) { var width = 960, height = 500, active; var projection = d3.geo.albersUsa() .scale(960) .translate([width / 2, height / 2]); var path = d3.geo.path() .projection(projection); var radius = d3.scale.sqrt() .domain([0, 1e7]) .range([0, 10]); var path2 = d3.geo.path() .projection(projection); // Remove svg, if already exist d3.select(container).select('svg').remove(); var svg = d3.select(container).append("svg") .attr("width", width) .attr("height", height); svg.append("rect") .attr("width", width) .attr("height", height); //.on("click", reset); var g = svg.append("g"); queue() .defer(d3.json, "/mbostock/raw/4090846/us.json") .defer(d3.json, "dots.json") .await(function (error, us, centroid) { g.append("g") .attr("id", "states") .selectAll("path") .data(topojson.feature(us, us.objects.states).features) .enter().append("path") .attr("d", path) .attr("class", "state"); //.on('click', click); g.append('path') .attr("id", "state-borders") .datum(topojson.mesh(us, us.objects.states, function(a, b) { return a !== b; })) .attr("d", path) .attr("class", "mesh"); var dots = g.append("g") .attr("id", "dots") .selectAll("path") .data(centroid.data) .enter().append("path") .attr("class", "dot") .attr("d", path2.pointRadius(function(d) { return radius(d.properties.pool); })); } ); } and the key part of Mike's example for making the rings is: setInterval(function() { svg.append("circle") .attr("class", "ring") .attr("transform", "translate(" + projection([100, -8]) + ")") .attr("r", 6) .style("stroke-width", 3) .style("stroke", "red") .transition() .ease("linear") .duration(6000) .style("stroke-opacity", 1e-6) .style("stroke-width", 1) .style("stroke", "brown") .attr("r", 160) .remove(); }, 750); how do I get the rings positioned on the dots?
Review the differences between the two methods to learn a little bit more about how functional/declarative programming abstracts away the pain of iterative programming. Approach with D3 idioms: fiddle: http://jsfiddle.net/blakedietz/E66eT/1/ update: D3 Way <!DOCTYPE html> <html> <head> <title></title> <style> body { background: #192887; } .graticule { fill: none; stroke: #fff; stroke-width: .5px; } .land { fill: #007421; } .dot { fill: #c7141a; } .ring { fill: none; stroke: #c7141a; } </style> <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script> </head> <body> <script> var width = 960, height = 500; var projection = d3.geo.mercator() .center([113, -3]) .scale(1275) .translate([width / 2, height / 2]) .clipExtent([[0, 0], [width, height]]) .precision(.1); var path = d3.geo.path() .projection(projection); var graticule = d3.geo.graticule() .step([5, 5]); var svg = d3.select("body").append("svg") .attr("width", width) .attr("height", height); svg.append("path") .datum(graticule) .attr("class", "graticule") .attr("d", path); var data = [{x:-8,y:100},{x:-10,y:110},{x: -12,y:120}]; svg.selectAll("circle") .data(data) .enter() .append("circle") .attr("class","dot") .attr("transform",translateCircle) .attr("r",8); function translateCircle(datum, index) { return "translate(" + projection([datum.y, datum.x]) + ")"; }; setInterval(function(){ svg .selectAll("ring") .data(data) .enter() .append("circle") .attr("class", "ring") .attr("transform", translateCircle) .attr("r", 6) .style("stroke-width", 3) .style("stroke", "red") .transition() .ease("linear") .duration(6000) .style("stroke-opacity", 1e-6) .style("stroke-width", 1) .style("stroke", "brown") .attr("r", 160) .remove(); }, 750) d3.select(self.frameElement).style("height", height + "px"); </script> </body> </html> So I didn't create a fully d3 idiomatic approach for this solution, but it will work. If you can get this to work implicitly within a svg.selectAll("circle"/"unique selection"...), etc, that would be even more awesome. I'll work on that in the mean time. Until then there's this more explicitly iterative approach. With Mike's example you're only appending a single element to the D.O.M. in the setInterval call. In order to expedite the binding process, I've created a projection method which operates on a set of coordinates: the translateCircle will operate on a datum within a collection of coordinates allowing access to the internal attributes of each collection element. Within each setInterval call the forEach method iterates over the collection of coordinates and then calls the same internals within the setInterval method that was called by Mike originally. Not So D3 <style> body { background: #192887; } .graticule { fill: none; stroke: #fff; stroke-width: .5px; } .land { fill: #007421; } .dot { fill: #c7141a; } .ring { fill: none; stroke: #c7141a; } </style> <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script> </head> <body> <script> var width = 960, height = 500; var projection = d3.geo.mercator() .center([113, -3]) .scale(1275) .translate([width / 2, height / 2]) .clipExtent([[0, 0], [width, height]]) .precision(.1); var path = d3.geo.path() .projection(projection); var graticule = d3.geo.graticule() .step([5, 5]); var svg = d3.select("body").append("svg") .attr("width", width) .attr("height", height); svg.append("path") .datum(graticule) .attr("class", "graticule") .attr("d", path); var data = [{x:-8,y:100},{x:-10,y:110},{x: -12,y:120}]; svg.selectAll("circle") .data(data) .enter() .append("circle") .attr("class","dot") .attr("transform",translateCircle) .attr("r",8); function translateCircle(datum, index) { return "translate(" + projection([datum.y, datum.x]) + ")"; }; setInterval(function(){ data.forEach(function(datum) { svg .append("circle") .attr("class", "ring") .attr("transform", translateCircle(datum)) .attr("r", 6) .style("stroke-width", 3) .style("stroke", "red") .transition() .ease("linear") .duration(6000) .style("stroke-opacity", 1e-6) .style("stroke-width", 1) .style("stroke", "brown") .attr("r", 160) .remove(); }) }, 750) d3.select(self.frameElement).style("height", height + "px"); </script> </body> </html>