D3JS makes date duplicates - d3.js
I have this d3js code:
var tooltip = tooltipd3();
var svg = d3.select("svg#svg-day"),
margin = {
top: 20,
right: 30,
bottom: 30,
left: 25,
padding: 15
},
width = 700 - margin.left - margin.right,
height = 300 - margin.top - margin.bottom;
// parse the periodo / time
var parseTime = d3.timeParse("%Y-%m-%d");
// set the ranges
var x = d3.scaleTime().range([0, width - margin.padding]);
var y = d3.scaleLinear().range([height, 0]);
// define the area
var area = d3.area()
.x(function(d) {
return x(d.periodo) + (margin.left + margin.padding);
})
.y0(height)
.y1(function(d) {
return y(d.guadagno);
});
// define the line
var valueline = d3.line()
.x(function(d) {
return x(d.periodo) + (margin.left + margin.padding);
})
.y(function(d) {
return y(d.guadagno);
});
var div = d3.select("svg#svg-day")
.append("div") // declare the tooltip div
.attr("class", "tooltip") // apply the 'tooltip' class
.style("opacity", 0);
// get the data
d3.csv(base_url() + 'graph/getStatementsDaily/', function(error, data) {
if (error) throw error;
$('.graph-loading').hide();
// format the data
data.forEach(function(d) {
d.periodo = parseTime(d.periodo)
d.guadagno = +d.guadagno;
});
// scale the range of the data
x.domain(d3.extent(data, function(d) {
return d.periodo;
}));
y.domain([0, d3.max(data, function(d) {
return d.guadagno + ((d.guadagno / 100) * 10); // 10% in più sulla scala numerica
})]);
// add the area
svg.append("path")
.data([data])
.attr("class", "area")
.attr("d", area);
// add the valueline path.
svg.append("path")
.data([data])
.attr("class", "line")
.attr("d", valueline);
// Add the scatterplot
svg.selectAll("dot")
.data(data)
.enter().append("circle")
.attr("class", "dot")
.attr("r", 3)
.attr("cx", function(d) {
return x(d.periodo) + (margin.left + margin.padding);
})
.attr("cy", function(d) {
return y(d.guadagno);
})
.on('mouseover', function(d) {
var html = '<h5>' + d.guadagno + ' €</h5>';
tooltip.mouseover(html); // pass html content
})
.on('mousemove', tooltip.mousemove)
.on('mouseout', tooltip.mouseout);
// add the X Axis
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(" + (margin.left + margin.padding) + "," + (height) + ")")
//HERE IS THE DATES CODE
.call(d3.axisBottom(x).tickFormat(d3.timeFormat("%d/%m")))
// add the Y Axis
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate (" + (margin.left + margin.padding) + " 0)")
.call(d3.axisLeft(y));
});
The dates care coming from a CSV file that has this format:
periodo,guadagno
2017-05-08,0.0
2017-05-09,0.5385
2017-05-10,0.0
2017-05-11,0.0
2017-05-12,0.0
2017-05-13,0.5680
2017-05-14,0.0
2017-05-15,0.0
The result is fine with lots of dates, but with 7 dates I get duplicates as you can see here:
Why is this?? And how do I fix it?
This is something that bothers a lot of people new to D3: the ticks in the axis, specially when using a time scale, are automatically generated. In your case, given the date interval in your domain, it coincidentally ended up creating two ticks for each day. But pay attention to this: those ticks represent different times (hours) in the same day (you can see that if you remove the tickFormat in the axis generator).
Let's see your code generating the x axis:
var svg = d3.select("svg");
var data = d3.csvParse(d3.select("#csv").text());
var parseTime = d3.timeParse("%Y-%m-%d");
data.forEach(function(d) {
d.periodo = parseTime(d.periodo)
});
var x = d3.scaleTime()
.range([20, 480])
.domain(d3.extent(data, function(d) {
return d.periodo;
}));
var axis = d3.axisBottom(x).tickFormat(d3.timeFormat("%d/%m"))(svg.append("g").attr("transform", "translate(0,50)"));
pre {
display: none;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="500"></svg>
<pre id="csv">periodo,guadagno
2017-05-08,0.0
2017-05-09,0.5385
2017-05-10,0.0
2017-05-11,0.0
2017-05-12,0.0
2017-05-13,0.5680
2017-05-14,0.0
2017-05-15,0.0</pre>
As you can see, there are two ticks for each day (remember, for different hours).
Let's show that this is a coincidence: This is the same code, but changing the last date for 2017-05-20:
var svg = d3.select("svg");
var data = d3.csvParse(d3.select("#csv").text());
var parseTime = d3.timeParse("%Y-%m-%d");
data.forEach(function(d) {
d.periodo = parseTime(d.periodo)
});
var x = d3.scaleTime()
.range([20, 480])
.domain(d3.extent(data, function(d) {
return d.periodo;
}));
var axis = d3.axisBottom(x).tickFormat(d3.timeFormat("%d/%m"))(svg.append("g").attr("transform", "translate(0,50)"));
pre {
display: none;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="500"></svg>
<pre id="csv">periodo,guadagno
2017-05-08,0.0
2017-05-09,0.5385
2017-05-10,0.0
2017-05-11,0.0
2017-05-12,0.0
2017-05-13,0.5680
2017-05-14,0.0
2017-05-20,0.0</pre>
Back to your code.
The solution is quite simple: using intervals. Let's set the interval for each tick:
d3.axisBottom(x).ticks(d3.timeDay)
Here is the same code with that change only:
var svg = d3.select("svg");
var data = d3.csvParse(d3.select("#csv").text());
var parseTime = d3.timeParse("%Y-%m-%d");
data.forEach(function(d) {
d.periodo = parseTime(d.periodo)
});
var x = d3.scaleTime()
.range([20, 480])
.domain(d3.extent(data, function(d) {
return d.periodo;
}));
var axis = d3.axisBottom(x).tickFormat(d3.timeFormat("%d/%m")).ticks(d3.timeDay)(svg.append("g").attr("transform", "translate(0,50)"));
pre {
display: none;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="500"></svg>
<pre id="csv">periodo,guadagno
2017-05-08,0.0
2017-05-09,0.5385
2017-05-10,0.0
2017-05-11,0.0
2017-05-12,0.0
2017-05-13,0.5680
2017-05-14,0.0
2017-05-15,0.0</pre>
Related
D3.js line chart continuous but want non continuous
Hey guys I created a time series line chart using publicly available stock data. Where I got to is the following: Looks like what it is doing is connecting the first datapoint with the last datapoint which is why it is creating a line across the entire chart. I looked online and read that to create a non continuous line chart I can add .defined(function(d) { return d; }) I did but it didn't help. My code: //Set dimensions and margins for the graph var margin = {top: 20, right: 20, bottom: 100, left: 70}, width = 960 - margin.left - margin.right, height = 500 - margin.top - margin.bottom; //Create canvas 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 + ")"); //Parse date var parseDate = d3.timeParse("%Y-%m-%d"); //Set the ranges var x = d3.scaleTime() .range([0, width]); var y = d3.scaleLinear() .range([height, 0]); // Define the line var valueLine = d3.line() .defined(function(d) { return d; }) .x(function(d) { return x(d.date); }) .y(function(d) { return y(d.value); }); //Import data from api d3.json("api_all.php", function(error, data) { if (error) throw error; data.forEach(e => { e.date = parseDate(e.date); e.value = +e.close; e.stockName = e.stock_name; e.stockSymbol = e.stock_symbol; }); //Create nest variable var nest = d3.nest() .key(function(d){ return d.stockSymbol; }) .entries(data); console.log(nest); //Scale the range of the data //x axis scale for entire dataset x.domain(d3.extent(data, function(d) { return d.date; })); //y.domain([0, d3.max(data, function(d) { return d.value; })]); //Add the x axis var xaxis = svg.append("g") .attr("transform", "translate(0," + height + ")") .attr("class", "x axis") .call(d3.axisBottom(x)); //Add x axis label svg.append("text") .attr("transform", "translate(" + (width/2) + "," + (height + margin.top + 10) + ")") .attr("dy", "1em") .style("text-anchor", "middle") .text("Date") .attr("class", "x axis label"); //Create dropdown var dropDown = d3.select("#dropDown") dropDown .append("select") .selectAll("option") .data(nest) .enter() .append("option") .attr("value", function(d){ return d.key; }) .text(function(d){ return d.key; }) // Function to create the initial graph var initialGraph = function(stock){ // Filter the data to include only stock of interest var selectStock = nest.filter(function(d){ return d.key == stock; }) console.log(selectStock) //Unnest selectStock for y axis var unnested = function(data, children){ var out = []; data.forEach(function(d, i){ console.log(i, d); d_keys = Object.keys(d); console.log(i, d_keys) values = d[children]; values.forEach(function(v){ d_keys.forEach(function(k){ if (k != children) { v[k] = d[k]} }) out.push(v); }) }) return out; } var selectStockUnnested = unnested(selectStock, "values"); //Scale y axis var selectStockGroups = svg.selectAll(".stockGroups") .data(selectStock, function(d){ return d ? d.key : this.key; }) .enter() .append("g") .attr("class", "stockGroups") .each(function(d){ y.domain([0, d3.max(selectStockUnnested, function(d) { return d.value; })]) console.log(selectStockUnnested); }); var initialPath = selectStockGroups.selectAll(".line") .data(selectStock) .enter() .append("path") initialPath .attr("d", function(d){ return valueLine(d.values) }) .attr("class", "line") //Add the y axis var yaxis = svg.append("g") .attr("class", "y axis") .call(d3.axisLeft(y) .ticks(5) .tickSizeInner(0) .tickPadding(6) .tickSize(0, 0)); //Add y axis label svg.append("text") .attr("transform", "rotate(-90)") .attr("y", 0 - 60) .attr("x", 0 - (height / 2)) .attr("dy", "1em") .style("text-anchor", "middle") .text("Price") .attr("class", "y axis label"); } // Create initial graph initialGraph("1301.T") // Update the data var updateGraph = function(stock){ // Filter the data to include only stock of interest var selectStock = nest.filter(function(d){ return d.key == stock; }) console.log(selectStock); //Unnest selectStock for y axis var unnested = function(data, children){ var out = []; data.forEach(function(d, i){ console.log(i, d); d_keys = Object.keys(d); console.log(i, d_keys) values = d[children]; values.forEach(function(v){ d_keys.forEach(function(k){ if (k != children) { v[k] = d[k]} }) out.push(v); }) }) return out; } var selectStockUnnested = unnested(selectStock, "values"); // Select all of the grouped elements and update the data var selectStockGroups = svg.selectAll(".stockGroups") .data(selectStock) .each(function(d){ y.domain([0, d3.max(selectStockUnnested, function(d) { return d.value; })]) }); // Select all the lines and transition to new positions selectStockGroups.selectAll("path.line") .data(selectStock) .transition() .duration(1000) .attr("d", function(d){ return valueLine(d.values) }) // Update the Y-axis d3.select(".y") .transition() .duration(1500) .call(d3.axisLeft(y) .ticks(5) .tickSizeInner(0) .tickPadding(6) .tickSize(0, 0)); } // Run update function when dropdown selection changes dropDown.on('change', function(){ // Find which stock was selected from the dropdown var selectedStock = d3.select(this) .select("select") .property("value") console.log(selectedStock); // Run update function with the selected stock updateGraph(selectedStock) }); }); </script> </body>
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.
2 completely different d3 charts on same page
I'm trying to get 2 completely different d3 charts (2 line charts but totally different data - one with several lines and negative data, other with one line positive data) on the same page. Right now, I only get the first one to be generated and shown correctly on the HTML page, the second chart doesn't show at all (not even svg container is generated). Here is my code: (function() { // Get the data d3.json("../assets/js/json/temperature.json", function(data) { // Set the dimensions of the canvas / graph var margin = {top: 30, right: 20, bottom: 30, left: 25}, width = 600 - margin.left - margin.right, height = 270 - margin.top - margin.bottom; // Parse the date / time var parseDate = d3.time.format("%Y-%m-%d %H:%M:%S").parse; // Set the ranges var x = d3.time.scale().range([0, width]); var y = d3.scale.linear().range([height, 0]); // Define the axes var xAxis = d3.svg.axis().scale(x) .orient("bottom").ticks(5); var yAxis = d3.svg.axis().scale(y) .orient("left").ticks(5); // Define the line var valueline = d3.svg.line() .x(function(d) { return x(d.temps); }) .y(function(d) { return y(d.temperature); }); // prepare data data.forEach(function(d) { d.temps = parseDate(d.temps); d.temperature = +d.temperature; }); // Adds the svg canvas var svg = d3.select("#graphTemp") .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 + ")"); // Scale the range of the data on domain x.domain(d3.extent(data, function(d) { return d.temps; })); y.domain([0, d3.max(data, function(d) { return d.temperature; })]); // Add the valueline path. svg.append("path") .attr("class", "line") .attr("d", valueline(data)); // 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") .call(yAxis) .append("text") .attr("transform", "rotate(-90)") .attr("y", 6) .attr("dy", ".71em") .style("text-anchor", "end") .text("Temperatures"); }); })(); (function(){ // loads the data and loads it into chart - main function d3.json("../assets/js/json/maitrise.json", function(data) { var m = {top: 20, right: 5, bottom: 30, left: 40}, w = 70 - m.left - m.right, h = 30 - m.top - m.bottom; var x = d3.scale.linear().domain([0, data.length]).range([0 + m.left, w - m.right]); var y = d3.scale.linear() .rangeRound([h, 0]); var line = d3.svg.line() .interpolate("cardinal") .x(function(d,i) { return x(i); }) .y(function (d) { return y(d.value); }); var color = d3.scale.ordinal() .range(["#28c6af","#ffd837","#e6443c","#9c8305","#d3c47c"]); var svg2 = d3.select("#maitrisee").append("svg") .attr("width", w + m.left + m.right) .attr("height", h + m.top + m.bottom) .append("g") .attr("transform", "translate(" + m.left + "," + m.top + ")"); // prep axis variables var xAxis2 = d3.svg.axis() .scale(x) .orient("bottom"); var yAxis2 = d3.svg.axis() .scale(y) .orient("left"); //console.log("Inital Data", data); var labelVar = 'id'; //A var varNames = d3.keys(data[0]) .filter(function (key) { return key !== labelVar;}); //B color.domain(varNames); //C var seriesData = varNames.map(function (name) { //D return { name: name, values: data.map(function (d) { return {name: name, label: d[labelVar], value: +d[name]}; }) }; }); console.log("seriesData", seriesData); y.domain([ d3.min(seriesData, function (c) { return d3.min(c.values, function (d) { return d.value; }); }), d3.max(seriesData, function (c) { return d3.max(c.values, function (d) { return d.value; }); }) ]); var series = svg2.selectAll(".series") .data(seriesData) .enter().append("g") .attr("class", function (d) { return d.name; }); series.append("path") .attr("class", "line") .attr("d", function (d) { return line(d.values); }) .style("stroke", function (d) { return color(d.name); }) .style("stroke-width", "2px") .style("fill", "none"); }); })();
OK, I found where the error was coming from. There was a piece of javascript in the middle of the HTML page that stopped d3 to generate the second graph further down in the page. Thanks for all the help!
D3.js Multiple lines on a chart
The lines of my chart are drawing off my chart. I've tried to replace this code: yE.domain(d3.extent(data, function(E) { return E.close;})); With this: yE.domain([0,d3.max(data, function(E) { return Math.max(E.close, E.Map1, EMap2, E.MapII); })]); Based on the answer from Bill: d3.js: dataset array w/ multiple y-axis values Mine doesn't work. My entire code: var marginE = {top: 30, right: 20, bottom: 30, left: 50}, widthE = 400 - marginE.left - marginE.right, heightE = 270 - marginE.top - marginE.bottom; // Parse the date / time var parseDateTimeE = d3.time.format("%Y-%m-%d%H:%M").parse; // Set the ranges var xE = d3.time.scale().range([0, widthE]); var yE = d3.scale.linear().range([heightE, 0]); // Define the axEs var xAxisE = d3.svg.axis().scale(xE) .orient("bottom").ticks(6); var yAxisE = d3.svg.axis().scale(yE) .orient("left").ticks(6); var areaE = d3.svg.area() .interpolate("bundle") .x(function(e) { return xE(e.date); }) .y0(heightE) .y1(function(e) { return yE(e.close); }); // Adds the svg canvas var svgE = d3.select(".eur") .append("svg") .attr("width", widthE + marginE.left + marginE.right) .attr("height", heightE + marginE.top + marginE.bottom) .attr('id', 'charteur') .attr('viewBox', '0 0 400 270') .attr('perserveAspectRatio', 'xMinYMid') .append("g") .attr("transform",'translate(' + marginE.left + ',' + marginE.top + ')') .attr('width', widthE) .attr('height', heightE) .style("font-size","12px"); // Get the data d3.json("php/downl_EUR.php", function(error, data) { data.forEach(function(E) { E.date = parseDateTimeE(E.date +E.time); E.close = +E.close; E.MaP1 = +E.MaP1; E.MaP2 = +E.MaP2; E.MaPII = +E.MaPII; }); // Define the line var valuelineE = d3.svg.line() .interpolate("bundle") .x(function(E) { return xE(E.date); }) .y(function(E) { return yE(E.close); }); var valuelineE2 = d3.svg.line() .interpolate("bundle") .x(function(E) { return xE(E.date); }) .y(function(E) { return yE(E.MaP1); }); var valuelineE3 = d3.svg.line() .interpolate("bundle") .x(function(E) { return xE(E.date); }) .y(function(E) { return yE(E.MaP2); }); var valuelineE4 = d3.svg.line() .interpolate("bundle") .x(function(E) { return xE(E.date); }) .y(function(E) { return yE(E.MaPII); }); // Scale the range of the data xE.domain(d3.extent(data, function(E) { return E.date; })); yE.domain(d3.extent(data, function(E) { return E.close;})); //**** //yE.domain([0,d3.max(data, function(E) {return Math.max(E.close, E.MapII);})]); **** svgE.append("path") .datum(data) .attr("class", "area") .attr("d", areaE); // Add the valueline path. svgE.append("path") .attr("class", "lineE") .style("stroke", "steelblue") .attr("d", valuelineE(data)); svgE.append("path") .attr("class", "lineE") .style("stroke", "red") .attr("d", valuelineE2(data)); svgE.append("path") .attr("class", "lineE") .style("stroke", "green") .attr("d", valuelineE3(data)); svgE.append("path") .attr("class", "lineE") .style("stroke-dasharray", ("3, 3")) .attr("d", valuelineE4(data)); // Add the X Axis svgE.append("g") .attr("class", "XaxisE") .attr("transform", "translate(0," + heightE + ")") .call(xAxisE); // Add the Y Axis svgE.append("g") .attr("class", "YaxisE") .call(yAxisE); });
I found the solution myself. Instead of MaP1, Map2 & MaPII, use map1, map2 and mapii -> no capital letters !! (also in the php-file) Everything works fine now...
Select a portion of an area element based on a data range
I have some data ranging from 2003 - 2007 plotted as a line graph using the following code: var x = d3.time.scale().range([0, width]), y = d3.scale.linear().range([height, 0]); var area = d3.svg.area() .x(function(d) { return x(d.date); }) .y0(height) .y1(function(d) { return y(d.price); }); and later when I've pulled my data in: x.domain(d3.extent(data.map(function(d) { return d.date; }))); y.domain([0, d3.max(data.map(function(d) { return d.price; }))]); context.append("path") .datum(data) .attr("d", area); I've implemented a brush to filter the data. It works like this one: http://bl.ocks.org/mbostock/4349545 But instead of a scatterplot, I have a line graph. I want to select arbitrary portions of the graph area and recolour it based on the brush selection. Just like the second graph on this yahoo chart: http://uk.finance.yahoo.com/echarts?s=SAN.MC#symbol=san.mc;range=20040915,20131007;compare=;indicator=volume;charttype=area;crosshair=on;ohlcvalues=0;logscale=off;source=undefined; I have a brush function that's fired on brushmove: function brushmove() { var s = brush.extent(); console.log(s); } which logs out the selected range correctly. I'm just not sure how to select a portion of my graph area based on the range coming back from the brushmove function. Full code is here: //specify some margins var margin = {top: 500, right: 10, bottom: 20, left: 40}, width = 960, height = 100; var bigMargin = {top: 20, right: 10, bottom: 20, left: 40}, bigWidth = 960, bigHeight = 400; //parse the date var parseDate = d3.time.format("%b %Y").parse; //create scales var x = d3.time.scale().range([0, width]), y = d3.scale.linear().range([height, 0]); //create scales var bigX = d3.time.scale().range([0, bigWidth]), bigY = d3.scale.linear().range([bigHeight, 0]); //create axis var xAxis = d3.svg.axis().scale(x).orient("bottom"), yAxis = d3.svg.axis().scale(y).orient("left"); var bigXAxis = d3.svg.axis().scale(bigX).orient("bottom"), bigYAxis = d3.svg.axis().scale(bigY).orient("left"); //create a brush area accessor function var brush = d3.svg.brush() .x(x) .on("brush", brushmove); //create an area accessor function var area = d3.svg.area() .x(function(d) { return x(d.date); }) .y0(height) .y1(function(d) { return y(d.price); }); var bigArea = d3.svg.area() .x(function(d) { return bigX(d.date); }) .y0(bigHeight) .y1(function(d) { return bigY(d.price); }); //append the svg container var svg = d3.select("body").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom); svg.append("defs").append("clipPath") .attr("id", "clip") .append("rect") .attr("width", bigWidth) .attr("height", bigHeight); //append a container var context = svg.append("g") .attr('class','container') .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); var bigContext = svg.append("g") .attr('class','bigContainer') .attr("transform", "translate(" + bigMargin.left + "," + bigMargin.top + ")"); //loop over the data d3.csv("data.csv", function(error, data) { //coerce the data a little because values from .CSv are always strings data.forEach(function(d) { d.date = parseDate(d.date); d.price = +d.price; }); //set the scale domains based on the data x.domain(d3.extent(data.map(function(d) { return d.date; }))); y.domain([0, d3.max(data.map(function(d) { return d.price; }))]); bigContext.append("path") .datum(data) .attr("clip-path", "url(#clip)") .attr("fill","red") .attr("d", bigArea); //set the scale domains based on the data bigX.domain(d3.extent(data.map(function(d) { return d.date; }))); bigY.domain([0, d3.max(data.map(function(d) { return d.price; }))]); var t = new Date(2003, 0, 1); //append the graph as an area context.append("path") .datum(data) .attr("d", area). attr("fill",function(d) { //if the data is at a certain range then give it a particular fill return (new Date(d.date) > t ? "orange" : "yellow"); }); //append the x axis context.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis); //append the x axis context.append("g") .attr("class", "y axis") .attr("transform", "translate(0,0)") .call(yAxis); //append the x axis bigContext.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + bigHeight + ")") .call(bigXAxis); //append the x axis bigContext.append("g") .attr("class", "y axis") .attr("transform", "translate(0,0)") .call(bigYAxis); //append the brush context.append("g") .attr("class", "x brush") .call(brush) .selectAll("rect") .attr("y", -6) .attr("height", height + 7) }); function brushstart() { svg.classed("selecting", true); } function brushmove() { bigX.domain(brush.extent()); bigContext.select("path").attr("d", bigArea); bigContext.select(".x.axis").call(bigXAxis); }