What am i doing wrong? Add text to bar chart with d3js - javascript
Have the following code to show a bar graph. I am trying to show the value on a text label. The things is that the element is created but is not showing the value.
Here is the code:
var data =[{"Anio":"1998","EJF":"50726","EXP":"0","RDC":"0","Total":"50726"}, {"Anio":"1999","EJF":"6403","EXP":"0","RDC":"0","Total":"6403"},{"Anio":"2000","EJF":"59211","EXP":"417","RDC":"0","Total":"59628"},{"Anio":"2001","EJF":"153053","EXP":"2801","RDC":"0","Total":"155854"},{"Anio":"2002","EJF":"68500","EXP":"2768","RDC":"0","Total":"71268"},{"Anio":"2003","EJF":"85650","EXP":"4658","RDC":"0","Total":"90308"},{"Anio":"2004","EJF":"70980","EXP":"4689","RDC":"0","Total":"75669"},{"Anio":"2005","EJF":"32670","EXP":"5889","RDC":"0","Total":"38559"},{"Anio":"2006","EJF":"78843","EXP":"5822","RDC":"0","Total":"84665"},{"Anio":"2007","EJF":"3771","EXP":"4925","RDC":"322","Total":"8696"},{"Anio":"2008","EJF":"82869","EXP":"5501","RDC":"342","Total":"88370"},{"Anio":"2009","EJF":"55795","EXP":"4148","RDC":"349","Total":"59943"},{"Anio":"2010","EJF":"54755","EXP":"4261","RDC":"341","Total":"59016"},{"Anio":"2011","EJF":"83147","EXP":"4000","RDC":"301","Total":"87147"},{"Anio":"2012","EJF":"27939","EXP":"3251","RDC":"248","Total":"31190"},{"Anio":"2013","EJF":"89643","EXP":"4385","RDC":"240","Total":"94028"},{"Anio":"2014","EJF":"53832","EXP":"3993","RDC":"688","Total":"58513"}];
var margin = {top: 20, right: 30, bottom: 30, left: 40},
width = 860 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var y = d3.scale.linear()
.range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var chart = d3.select(".chart")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
x.domain(arr_data.map(function(d) { return d.name; }));
y.domain([0, d3.max(arr_data, function(d) { return d.value; })]);
chart.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
chart.append("g")
.attr("class", "y axis")
.call(yAxis);
chart.selectAll(".bar")
.data(arr_data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) { return x(d.name); })
.attr("y", function(d) { return y(d.value); })
.attr("height", function(d) { return height - y(d.value); })
.attr("width", x.rangeBand())
.attr("fill","#632423")
.on('mouseover',function(d){
var a = d3.select(this)
.attr("fill","#733A39");
}).on('mouseout',function(d){
var a = d3.select(this)
.attr("fill","#632423"); //old color: #790018
});
chart.selectAll(".bar")
.append("text")
.text(function(d) { return d.value; })
.attr("y", function(d) { return y(d.value)+16; })
.style("stroke", 'white');
I dont know why is that, if someone could show me some light...thanks!!
Thanks in advance!
I add a G (group) element, the code looks like this:
var chart = d3.select(".chart")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
x.domain(arr_data.map(function(d) { return d.name; }));
y.domain([0, d3.max(arr_data, function(d) { return d.value; })]);
chart.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
chart.append("g")
.attr("class", "y axis")
.call(yAxis);
var bar = chart.selectAll(".bar")
.data(arr_data)
.enter().append("g");
bar.append("rect")
.attr("class", "rect")
.attr("x", function(d) { return x(d.name); })
.attr("y", function(d) { return y(d.value); })
.attr("height", function(d) { return height - y(d.value); })
.attr("width", x.rangeBand())
.attr("fill","#632423")
.on('mouseover',function(d){
var a = d3.select(this)
.attr("fill","#733A39");
var a = d3.select("#tooltip")
.style("left","100px")
.style("top","20px")
.select("#value")
.text(d.value);
}).on('mouseout',function(d){
var a = d3.select(this)
.attr("fill","#632423"); //old color: #790018
});
bar.append("text")
.attr("class", "label")
.text(function(d) { return d.value; })
.attr("x", function(d) { return x(d.name)+4; })
.attr("y", function(d) { return y(d.value)+20 ; });
Related
D3.js path goes in different directions in V3 vs V4
I'm attempting to make the same multi-line graph in D3 V3 and V4, but they behave differently for reasons I don't understand. What can I change in my V4 code that will make the paths connect in the correct order (according to the x axis instead of the y axis)? Here's what V3 gives, taken from the jsfiddle I made for it: ...But here's V4: Jsfiddle doesn't support V4 yet, so here's my code: var margin = {top: 20, right: 40, bottom: 100, left: 100}, width = 500 - margin.left - margin.right, height = 400 - margin.top - margin.bottom; var x = d3.scaleLinear().range([0, width]); var y = d3.scaleLinear().range([height, 0]); var xAxis = d3.axisBottom(x); var yAxis = d3.axisLeft(y); var line = d3.line() .x(function(d) { return x(d.depth); }) .y(function(d) { return y(d.carat); }); 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 + ")"); d3.csv("diamonds.csv", function(error, data) { data.forEach(function(d) { d.carat = +d.carat; d.depth = +d.depth; //d.cut = +d.cut; }) data.sort(function(a,b) { return a.x - b.x; }); x.domain(d3.extent(data, function(d) { return d.depth; })).nice(); y.domain(d3.extent(data, function(d) { return d.carat; })).nice(); svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis) .selectAll("text") .attr("y", 6) .attr("x", 5) .attr("dy", ".35em") .attr("transform", "rotate(45)") .style("text-anchor", "start") var dataNest = d3.nest() .key(function(d) {return d.cut;}) .entries(data); svg.append("g") .attr("class", "y axis") .call(yAxis) .append("text") .attr("class", "label") .attr("transform", "rotate(-90)") .attr("y", 6) .attr("dy", ".71em") .style("text-anchor", "end") .text("Price"); var color = d3.scaleOrdinal(d3.schemeCategory10); dataNest.forEach(function(d) { svg.append("path") .attr("class", "line") .style("stroke", function() { // Add the colours dynamically return d.color = color(d.key); }) .attr("d", line(d.values)); }); });
If you look at your code using D3 v3.x, you did this after loading the data: data.forEach(function(d) { d.x = +d.depth; d.carat = +d.carat; }) And using that property x for sorting: data.sort(function(a,b) { return a.x - b.x; }); However, in your v4.x version, you did: data.forEach(function(d) { d.depth = +d.depth; d.carat = +d.carat; }) And used an nonexistent x for sorting (the problem with sorting alone was making the lines different from v3.x). Solution: use depth for sorting: data.sort(function(a,b) { return a.depth - b.depth; }); Here is your code using v4.x version: var margin = { top: 20, right: 40, bottom: 100, left: 100 }, width = 500 - margin.left - margin.right, height = 400 - margin.top - margin.bottom; var x = d3.scaleLinear().range([0, width]); var y = d3.scaleLinear().range([height, 0]); var xAxis = d3.axisBottom(x); var yAxis = d3.axisLeft(y); var line = d3.line() .x(function(d) { return x(d.depth); }) .y(function(d) { return y(d.carat); }); 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 + ")"); var data = d3.csvParse(d3.select("pre#data").text()); data.forEach(function(d) { d.carat = +d.carat; d.depth = +d.depth; //d.cut = +d.cut; }) data.sort(function(a, b) { return a.depth - b.depth; }); x.domain(d3.extent(data, function(d) { return d.depth; })).nice(); y.domain(d3.extent(data, function(d) { return d.carat; })).nice(); svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis) .selectAll("text") .attr("y", 6) .attr("x", 5) .attr("dy", ".35em") .attr("transform", "rotate(45)") .style("text-anchor", "start") var dataNest = d3.nest() .key(function(d) { return d.cut; }) .entries(data); svg.append("g") .attr("class", "y axis") .call(yAxis) .append("text") .attr("class", "label") .attr("transform", "rotate(-90)") .attr("y", 6) .attr("dy", ".71em") .style("text-anchor", "end") .text("Price"); var color = d3.scaleOrdinal(d3.schemeCategory10); dataNest.forEach(function(d) { svg.append("path") .attr("class", "line") .style("stroke", function() { // Add the colours dynamically return d.color = color(d.key); }) .attr("d", line(d.values)); }); pre { display:none; } path { fill: none; stroke: #000; } .line { fill: none; // stroke: green; // stroke-width: 3.5px; } <script src="https://d3js.org/d3.v4.min.js"></script> <pre id="data"> carat,cut,color,clarity,depth,table,price,x,y,z 0.41,Ideal,G,VS1,60.8,56,899,4.79,4.82,2.92 0.3,Ideal,F,VS1,62.1,55,612,4.31,4.35,2.69 1.25,Ideal,H,SI1,62.2,57,6661,6.86,6.9,4.28 0.41,Ideal,G,VS2,61.4,55,1061,4.8,4.75,2.93 0.53,Premium,E,VVS2,62.4,56,2331,5.19,5.17,3.23 1.14,Very Good,G,VS2,63.2,56,6435,6.67,6.63,4.2 0.51,Premium,G,SI1,62,59,1053,5.12,5.1,3.17 1.51,Good,H,VVS2,63.1,59,11826,7.26,7.28,4.59 1.31,Ideal,J,SI1,62.5,56,6337,6.95,7.04,4.37 0.33,Very Good,I,VVS1,61.7,61,608,4.43,4.45,2.74 0.42,Ideal,F,VS1,62.3,55,1103,4.79,4.77,2.98 1.01,Good,E,VS2,60.8,63,6250,6.44,6.46,3.92 1,Premium,F,SI1,62.7,59,5292,6.4,6.36,4 0.51,Ideal,G,VVS1,61.9,53,1919,5.14,5.2,3.2 0.34,Ideal,H,SI1,61.5,55,647,4.53,4.55,2.79 0.23,Premium,F,VVS2,61.3,59,445,3.94,3.99,2.43 0.3,Ideal,F,VS2,62.9,57,776,4.29,4.27,2.69 1.14,Premium,F,SI1,60.4,58,6320,6.82,6.79,4.11 0.33,Ideal,J,VVS1,62.1,54,509,4.45,4.47,2.77 0.41,Premium,H,SI1,60.9,60,683,4.79,4.83,2.93 2.01,Premium,J,SI2,62.8,58,12407,8.09,8,5.05 2.01,Very Good,I,SI1,60.3,59,15126,8.14,8.21,4.93 0.4,Very Good,D,VS2,62.8,58,993,4.66,4.71,2.94 1.09,Premium,D,SI1,61.6,58,5799,6.61,6.57,4.06 0.3,Ideal,F,VS1,61.5,55,612,4.31,4.34,2.66 0.77,Very Good,H,SI2,63.6,58,2129,5.77,5.81,3.68 0.38,Very Good,F,VS1,62.7,57,883,4.71,4.64,2.93 0.54,Premium,E,VS1,60.3,58,1939,5.26,5.32,3.19 0.93,Premium,F,SI1,58.8,60,4010,6.49,6.37,3.78 0.32,Ideal,H,VS1,61.1,56,561,4.44,4.46,2.72 0.78,Premium,F,SI2,62.8,56,2200,5.9,5.86,3.69 0.4,Ideal,E,VS1,61.2,55,1005,4.79,4.76,2.92 0.41,Ideal,D,VS2,62.4,55,1076,4.79,4.76,2.98 0.73,Very Good,E,SI1,61.6,59,2760,5.77,5.78,3.56 2.52,Very Good,G,SI2,63.2,58,17689,8.65,8.61,5.45 1.06,Ideal,D,VVS2,62,56,12053,6.53,6.57,4.06 0.8,Very Good,D,IF,63.3,57,6834,5.85,5.87,3.71 1.5,Premium,H,VS2,62.2,58,10291,7.27,7.36,4.55 2.17,Good,H,SI2,58.9,62,16036,8.48,8.52,5.01 1.58,Ideal,G,SI1,62.2,55,11927,7.44,7.5,4.65 2.03,Premium,H,VS2,62.1,56,18139,8.2,8.12,5.07 0.58,Very Good,D,SI2,62.9,56,1438,5.31,5.35,3.35 0.72,Very Good,D,VS2,62.1,59,3016,5.7,5.73,3.55 0.38,Ideal,D,VVS2,61.5,57,1200,4.63,4.67,2.86 0.5,Premium,E,VS2,61.3,60,1624,5.07,5.11,3.12 0.31,Ideal,F,VS2,61.1,56,640,4.35,4.39,2.67 1.41,Premium,D,SI2,61.1,56,6988,7.19,7.15,4.38 0.7,Good,I,VS1,63.2,55,2274,5.58,5.63,3.54 1.22,Ideal,F,SI2,62,57,4852,6.88,6.83,4.25 1.58,Ideal,H,VS2,61.4,56,12334,7.5,7.56,4.62 1.2,Ideal,G,VS1,62,55,9625,6.81,6.87,4.24 1.03,Premium,H,I1,61.1,60,3172,6.46,6.51,3.96 0.77,Very Good,H,VS1,62.8,58,2961,5.75,5.78,3.62 1.04,Ideal,I,VS2,61.5,57,5105,6.49,6.52,4 1,Good,H,SI1,63.7,60,4788,6.33,6.3,4.02 0.82,Very Good,G,IF,61.9,57,4844,5.96,6,3.7 0.71,Ideal,D,VS1,60.9,57,3518,5.74,5.76,3.5 1.21,Ideal,I,SI2,64.6,56,4879,6.67,6.62,4.29 0.4,Very Good,E,SI1,61.7,60,687,4.68,4.72,2.9 1.11,Premium,H,SI1,61.1,60,5433,6.68,6.62,4.06 1.5,Ideal,F,VS2,60.4,57,14071,7.41,7.43,4.48 1.48,Very Good,H,SI1,62.5,59,8815,7.16,7.23,4.5 0.28,Ideal,F,VVS2,61.5,57,787,4.19,4.24,2.59 0.64,Very Good,E,VS2,63.4,54,2114,5.52,5.49,3.49 1.68,Ideal,I,VS2,62.1,57,10800,7.6,7.54,4.7 0.93,Premium,G,SI2,61.7,60,3802,6.25,6.2,3.84 0.34,Very Good,E,SI1,62.9,56,596,4.45,4.48,2.81 1.57,Premium,G,VS1,59.9,56,14180,7.6,7.55,4.54 1.16,Premium,H,SI2,61.8,58,4872,6.81,6.75,4.19 0.3,Ideal,E,VVS2,61.4,57,1013,4.34,4.32,2.66 1.06,Very Good,F,SI1,63.4,58,5520,6.51,6.42,4.1 1.14,Ideal,H,SI1,61.6,56,7079,6.72,6.74,4.14 1,Premium,J,SI1,58.7,58,3920,6.55,6.51,3.83 2.01,Very Good,F,SI2,63.3,59,11925,7.98,7.89,5.02 1.37,Premium,G,VS1,58.3,60,10412,7.35,7.3,4.27 0.91,Premium,E,SI2,61.6,60,3846,6.14,6.1,3.77 1,Premium,G,VS2,63,58,6048,6.4,6.33,4.01 0.4,Good,G,SI1,63.4,58,655,4.66,4.71,2.97 1.39,Very Good,G,SI2,61.5,62,6628,7.09,7.16,4.38 0.31,Ideal,G,IF,62.7,57,924,4.31,4.34,2.71 1.5,Premium,H,VS2,62.4,59,11092,7.29,7.32,4.56 0.99,Very Good,F,SI1,62.5,58,5112,6.36,6.38,3.98 1.5,Very Good,I,VVS2,64,54,9618,7.19,7.27,4.63 1.04,Very Good,E,VVS2,62.4,58,8748,6.46,6.4,4.01 1.01,Premium,H,SI1,61.8,59,5204,6.38,6.33,3.93 0.71,Fair,D,SI1,55.5,62,2086,6,5.97,3.32 0.26,Ideal,G,VS1,62.1,55,478,4.09,4.12,2.55 0.92,Premium,E,SI1,61.7,57,4637,6.32,6.2,3.86 0.32,Ideal,E,VS2,61.8,54,768,4.43,4.4,2.73 0.54,Ideal,H,IF,61.5,54,1981,5.27,5.3,3.25 0.4,Ideal,G,IF,61.2,56,1199,4.74,4.77,2.91 1.28,Very Good,G,VVS2,59.5,56,11478,7.12,7.16,4.25 0.42,Premium,G,VS2,60.6,59,1087,4.85,4.78,2.92 1.04,Premium,H,VS2,60.4,59,5777,6.66,6.51,3.98 0.91,Premium,G,SI1,61.8,60,4045,6.18,6.21,3.83 0.33,Very Good,H,VS2,58.8,62,486,4.49,4.53,2.65 0.31,Ideal,E,VS1,61.3,54,664,4.37,4.4,2.69 0.61,Very Good,D,VS1,62.4,57,2096,5.44,5.46,3.4 0.3,Ideal,H,VVS2,61.6,55,605,4.3,4.34,2.66 1.57,Premium,J,VS1,61.3,59,8595,7.44,7.47,4.57 0.72,Very Good,J,VS1,62.3,57,2136,5.73,5.77,3.58 1.11,Premium,F,SI2,62.2,57,5284,6.67,6.61,4.13 0.4,Premium,D,SI2,61.7,58,855,4.74,4.69,2.91 0.7,Good,F,VVS1,63.3,56,3310,5.64,5.7,3.59 1,Premium,D,SI2,59.4,60,4626,6.56,6.48,3.87 0.61,Ideal,E,VVS2,62,54,3011,5.43,5.47,3.38 1,Premium,F,VS2,62.8,59,6328,6.35,6.32,3.98 1.05,Ideal,F,SI2,60.9,56,4591,6.56,6.64,4.02 1.01,Premium,I,SI1,61.6,58,3944,6.45,6.51,3.99 0.51,Ideal,F,VS2,63.2,57,1687,5.08,5.05,3.2 1.2,Premium,H,SI2,62.4,61,5040,6.81,6.78,4.24 1.52,Ideal,J,VS1,62.3,58,8608,7.32,7.35,4.57 0.51,Premium,F,VVS2,61.9,56,2310,5.17,5.13,3.19 0.5,Very Good,H,IF,61.4,61,1923,5.14,5.03,3.12 1.01,Premium,G,SI1,63,60,4118,6.34,6.3,3.98 0.8,Very Good,F,VS1,62.6,57,3720,5.9,5.98,3.72 2.01,Very Good,I,SI1,62.8,60,14811,7.99,8.04,5.03 1,Premium,E,SI1,61.6,59,5600,6.41,6.38,3.94 1,Good,J,VS1,58.1,64,3920,6.63,6.51,3.82 0.52,Premium,F,VS2,61.4,62,1605,5.19,5.16,3.18 1.3,Very Good,I,VS2,61.8,56,7087,6.98,7.04,4.33 2,Very Good,I,SI1,62.9,59.2,15081,7.95,8.08,5.05 0.31,Very Good,I,VS2,61.6,56,468,4.36,4.39,2.69 1.63,Very Good,I,SI1,62,54,9090,7.6,7.67,4.73 0.3,Premium,H,VVS2,62.1,52,776,4.31,4.29,2.67 1.1,Premium,G,VS2,62.8,58,6387,6.6,6.58,4.14 0.23,Very Good,F,VVS2,61,59,465,3.93,3.97,2.41 1.23,Premium,I,SI2,62.1,59,4773,6.83,6.79,4.23 1.02,Good,G,VS2,63.6,57,5816,6.38,6.41,4.07 0.71,Premium,F,VS1,59.2,58,2839,5.87,5.82,3.46 1.69,Ideal,H,I1,62,56,6757,7.66,7.61,4.73 1.6,Ideal,G,VS2,61.9,56,15000,7.53,7.47,4.64 0.32,Ideal,H,IF,61.9,54.2,783,4.38,4.42,2.72 0.73,Very Good,G,SI2,62.2,58,2057,5.71,5.77,3.57 0.32,Ideal,D,VS2,62.7,54,758,4.36,4.38,2.74 0.7,Ideal,E,VS2,61.1,59,3201,5.67,5.73,3.48 0.3,Ideal,H,VS1,62.1,54,526,4.32,4.35,2.69 0.9,Good,I,VS2,63.8,55,3303,6.07,6.16,3.9 0.52,Premium,H,SI2,60.9,61,975,5.15,5.1,3.12 0.97,Premium,F,SI1,62.7,59,4561,6.28,6.31,3.95 0.32,Very Good,H,SI1,62.6,55,461,4.37,4.38,2.74 0.54,Ideal,F,SI1,61.2,56,1307,5.23,5.29,3.22 1.21,Good,F,VS2,63.7,58,7911,6.67,6.71,4.26 1.51,Very Good,I,SI1,63.1,56,7891,7.28,7.33,4.61 1.01,Premium,F,VS2,58.9,58,6271,6.59,6.51,3.86 1.57,Very Good,J,VS2,62.6,59,7832,7.39,7.43,4.64 0.73,Premium,I,VS1,60.3,58,2371,5.83,5.87,3.53 1.2,Ideal,I,SI1,62.5,57,5107,6.77,6.71,4.21 3.04,Premium,I,SI2,59.3,60,18559,9.51,9.46,5.62 0.31,Very Good,G,VVS1,63.1,56,1046,4.35,4.33,2.74 0.5,Premium,E,I1,60.7,61,840,5.14,5.05,3.09 0.38,Ideal,I,VS1,62.4,54.4,703,4.62,4.66,2.9 1.12,Premium,G,VS2,60.7,53,6774,6.81,6.7,4.1 1.33,Premium,F,SI2,60.7,62,5288,7.12,7.07,4.31 1.11,Ideal,J,VS1,61.7,57,4854,6.67,6.72,4.13 0.71,Ideal,G,SI1,62.4,56,2386,5.74,5.71,3.57 1.03,Ideal,G,VS1,62.1,57,6558,6.44,6.47,4.01 0.32,Very Good,G,VVS1,61.4,55,772,4.41,4.45,2.72 1.55,Premium,D,VS2,61.5,58,16137,7.51,7.48,4.61 0.72,Premium,F,VS2,60.8,58,2530,5.78,5.74,3.5 0.31,Good,F,VS2,63.4,56,625,4.29,4.32,2.73 0.42,Ideal,G,IF,62,57,1310,4.82,4.8,2.98 2.1,Premium,H,SI2,60.4,59,16479,8.28,8.33,5.02 0.66,Ideal,H,VS2,61.4,56,2178,5.62,5.65,3.46 0.48,Premium,F,SI1,60.6,62,1110,5.06,5,3.05 0.91,Very Good,D,SI1,63,59,4429,6.11,6.15,3.86 0.5,Ideal,E,SI2,62.5,57,1154,5.04,5.07,3.16 0.57,Ideal,I,VS1,62.2,55,1448,5.28,5.33,3.3 1.09,Premium,F,SI1,60.9,59,5384,6.64,6.59,4.03 1,Premium,H,SI1,62.3,60,4788,6.38,6.34,3.96 0.4,Very Good,E,VS2,63,58,791,4.7,4.73,2.97 1.2,Ideal,I,SI1,60.1,56,5578,6.9,6.84,4.13 0.71,Premium,I,VS2,59.3,59,2300,5.89,5.81,3.47 0.34,Ideal,D,VS2,62,55,1033,4.48,4.45,2.77 1.25,Good,J,SI1,63.6,57,5110,6.86,6.81,4.35 0.41,Ideal,D,SI1,61.7,54,1015,4.79,4.78,2.95 0.51,Fair,D,SI2,66.5,58,1109,4.95,4.89,3.27 0.56,Ideal,E,SI1,62.7,57,1698,5.27,5.23,3.29 1.04,Ideal,G,VS1,61.5,57,7457,6.5,6.54,4.01 0.3,Ideal,I,SI1,61.9,57,422,4.29,4.31,2.66 0.5,Premium,F,VS2,61.7,60,1323,5.06,5.02,3.11 0.28,Very Good,G,VVS2,62.3,56,522,4.16,4.19,2.6 0.37,Very Good,E,VS1,62,56,925,4.59,4.63,2.86 0.8,Premium,F,SI2,58.5,62,2371,6.08,6.05,3.55 0.81,Very Good,F,SI2,62.7,58,2942,5.92,5.95,3.72 0.51,Ideal,E,VVS2,62.8,56,2211,5.13,5.15,3.23 0.98,Ideal,G,SI1,62.3,56,4665,6.37,6.34,3.96 1.51,Good,H,VS2,63.6,61,8904,7.08,7.03,4.49 0.5,Premium,D,SI1,60.3,58,1433,5.12,5.1,3.08 0.43,Ideal,F,VVS2,62.2,55,1250,4.85,4.83,3.01 0.7,Ideal,F,SI1,61.1,57,2516,5.75,5.71,3.5 0.3,Premium,E,SI1,61.8,60,675,4.28,4.23,2.63 0.7,Very Good,F,VS2,62.9,56,2400,5.66,5.73,3.58 0.92,Very Good,D,VS1,61.9,58,7544,6.19,6.24,3.85 2.57,Premium,J,SI1,63,58,18485,8.77,8.65,5.49 2.25,Ideal,I,SI2,60.7,56,11104,8.54,8.5,5.17 0.51,Ideal,G,VVS2,61.5,57,1875,5.13,5.18,3.17 1.05,Ideal,H,SI2,61.9,56,4504,6.49,6.56,4.04 0.3,Ideal,E,VS1,62.5,56,694,4.27,4.31,2.68 1.01,Premium,J,VS2,62.4,60,3296,6.45,6.35,3.99 </pre>
D3.js: Changing the tick values on x-axis based on the screen width
I am making a responsive D3.js Bar Chart, by setting the height to clientWidth. Though the chart resizes after reloading in a new size, when the size is small the x-axis values overlap. I need to avoid this, how can i do it? Script: clientw = document.body.clientWidth; var margin = {top: 40, right: 20, bottom: 30, left: 40}, width = clientw - margin.left - margin.right, height = 500 - margin.top - margin.bottom; var x = d3.scale.ordinal() .rangeRoundBands([0, width], .1); var y = d3.scale.linear() .range([height, 0]); var xAxis = d3.svg.axis() .scale(x) .orient("bottom"); var yAxis = d3.svg.axis() .scale(y) .orient("left") .ticks(10) .tickFormat(d3.format("s")); var tip = d3.tip() .attr('class', 'd3-tip') .offset([-10, 0]) .html(function(d) { return "<strong>Hola:</strong> <span style='color:red'>" + d.hola+ "°C"+"</span>"; }) 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 + ")"); svg.call(tip); d3.tsv("data.tsv", type, function(error, data) { x.domain(data.map(function(d) { return d.hermanos; })); y.domain([0, 45]); svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis); 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("Hola"); svg.selectAll(".bar") .data(data) .enter().append("rect") .attr("width", x) .attr("fill","grey") .attr("class", "bar") .attr("x", function(d) { return x(d.hermanos); }) .attr("width", x.rangeBand()) .attr("y", function(d) { return y(d.hola); }) .attr("height", function(d) { return height- y(d.hola); }) .on('mouseover', tip.show) .on('mouseout', tip.hide) }); function type(d) { d.hola= +d.hola; return d; }
Not able Zoom on D3 Group Bar Chart
I have created a group bar chart, & try to apply zoom, but zoom is only happened for the first group & not for the complete group bar chart. Any help will be really appreciated. Thanks in advance. you can find working fiddle here: http://jsfiddle.net/fiddlefollower/qkHK6/893/ code details: var x0 = d3.scale.ordinal() .rangeRoundBands([0, width], .1); var x1 = d3.scale.ordinal(); var y = d3.scale.linear() .range([height, 0]); var color = d3.scale.ordinal() .range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]); var xAxis = d3.svg.axis().scale(x0).orient("bottom"); var yAxis = d3.svg.axis() .scale(y) .orient("left") .tickFormat(d3.format(".1s")); var svg = d3.select("#chart").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 + ")") .call(d3.behavior.zoom().scaleExtent([1, 10]).on("zoom", zoom)); var ageNames = d3.keys(data[0]).filter(function(key) { return key !== "State"; }); console.log("ageNames="+JSON.stringify(ageNames)); data.forEach(function(d) { d.ages = ageNames.map(function(name) { return {name: name, value: +d[name]}; }); console.log("d.ages="+JSON.stringify(d.ages)); }); x0.domain(data.map(function(d) { return d.State; })); x1.domain(ageNames).rangeRoundBands([0, x0.rangeBand()]); y.domain([0, d3.max(data, function(d) { console.log(" before retuen d.ages="+d.ages); return d3.max(d.ages, function(d) { console.log("d.value;="+d.value); return d.value; }); })]); svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis); svg.append("g") .attr("class", "y axis") .call(yAxis) .append("text") .attr("transform", "rotate(-90)") .attr("y", 6) .attr("dy", ".5em") .style("text-anchor", "end") .text("Population"); var state = svg.selectAll(".state") .data(data) .enter().append("g") .attr("class", "state") .attr("transform", function(d) { return "translate(" + x0(d.State) + ",0)"; }); state.selectAll("rect") .data(function(d) { return d.ages; }) .enter().append("rect") .attr("width", x1.rangeBand()) .attr("x", function(d) { return x1(d.name); }) .attr("y", function(d) { return y(d.value); }) .attr("height", function(d) { return height - y(d.value); }) .style("fill", function(d) { return color(d.name); }); function zoom() { svg.select(".state").attr("transform", "translate("+ d3.event.translate[0]+")scale(" + d3.event.scale + ",1)"); svg.select(".x.axis").attr("transform", "translate(" + d3.event.translate[0]+","+(height)+")").call(xAxis.scale(x0.rangeRoundBands([0, width * d3.event.scale],.5 * d3.event.scale))); svg.select(".y.axis").call(yAxis); }
In the zoom function svg.select(".state") selects only the first group of bars, svg.selectAll(".state") selects all groups. Grouping all states in a "g" element with the new variable allStates var allStates = svg.append("g") .attr("class", "allStates"); and referencing to this new variable var state = allStates.selectAll(".state") .data(data) .enter().append("g") .attr("class", "state") .attr("transform", function(d) { return "translate(" + x0(d.State) + ",0)"; }); and also in zoom function svg.select(".allStates").attr("transform", "translate(" + d3.event.translate[0]+",0)scale(" + d3.event.scale + ",1)"); on doubleclick event it will zoom over all the states
D3 unexpected identifier
I was trying to make a d3 example from http://bl.ocks.org/mbostock/3887051 modified with my data. I use concepts similar to example. I didn't have problems with acquiring the data, but there's an unexpected identifier error. <script> var margin = {top: 20, right: 20, bottom: 30, left: 40}, width = 960 - margin.left - margin.right, height = 500 - margin.top - margin.bottom; var x0 = d3.scale.ordinal() .rangeRoundBands([0, width], .1); var x1 = d3.scale.ordinal(); var y = d3.scale.linear() .range([height, 0]); var color = d3.scale.ordinal() .range(["#98abc5", "#8a89a6"]); var xAxis = d3.svg.axis() .scale(x0) .orient("bottom"); var yAxis = d3.svg.axis() .scale(y) .orient("left") .tickFormat(d3.format(".2s")); 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 + ")"); d3.csv("datatest.csv", function(error, data) { var inflasiTahun = d3.keys(data[0]).filter(function(key) { return key !== "tahun"; }); data.forEach(function(d) { d.inflasi = inflasiTahun.map(function(name) { return {name: name, value: parseFloat(d[name])}; }); }); x0.domain(data.map(function(d) { return d.tahun; })); x1.domain(inflasiTahun).rangeRoundBands([0, x0.rangeBand()]); y.domain([0, d3.max(data, function(d) { return d3.max(d.inflasi, function(d) { return d.value; }); }) svg.append("g") //this is the error .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis); 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("Inflasi"); var state = svg.selectAll(".state") .data(data) .enter().append("g") .attr("class", "g") .attr("transform", function(d) { return "translate(" + x0(d.tahun) + ",0)"; }); state.selectAll("rect") .data(function(d) { return d.inflasi; }) .enter().append("rect") .attr("width", x1.rangeBand()) .attr("x", function(d) { return x1(d.name); }) .attr("y", function(d) { return y(d.value); }) .attr("height", function(d) { return height - y(d.value); }) .style("fill", function(d) { return color(d.name); }); }); </script> I dont know In the console, the unexpected identifier points to this: svg.append("g") //this is the error
You forgot to close the y.domain([ with ]); on the following line: y.domain([0, d3.max(data, function(d) { return d3.max(d.inflasi, function(d) { return d.value; }); }) Tools like JSLint and JSHint as well as proper indentation can help you in tracking down this kind of errors.
Add text on top of bar in d3js chart -- no <text> elements added
I am creating a bar chart with d3.js from data stored in tsv file. I want to insert a text in each bar. How I can do? I have tried even this solution, but doesn't work. Here is the code of my function: var margin = {top: 20, right: 20, bottom: 30, left: 40}, width = 960 - margin.left - margin.right, height = 500 - margin.top - margin.bottom; var formatPercent = d3.format(".0%"); var x = d3.scale.ordinal() .rangeRoundBands([0, width], .1, 1); var y = d3.scale.linear() .range([height, 0]); var xAxis = d3.svg.axis() .scale(x) .orient("bottom"); var yAxis = d3.svg.axis() .scale(y) .orient("left"); 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 + ")"); function visualize(file){ d3.tsv(file, function(error, data) { data.forEach(function(d) { d.weight = +d.weight; }); x.domain(data.map(function(d) { return d.concept; })); y.domain([0, d3.max(data, function(d) { return d.weight; })]); svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis); 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("weight"); svg.selectAll(".bar") .data(data) .enter().append("rect").style("fill", function (d){return d.color;}) .attr("class", "bar") .attr("x", function(d) { return x(d.concept); }) .attr("width", x.rangeBand()) .attr("y", function(d) { return y(d.weight); }) .attr("height", function(d) { return height - y(d.weight); }); svg.selectAll("text") .data(data) .enter() .append("text") .text(function(d) { return d.concept; }) .attr("text-anchor", "middle") .attr("x", x) .attr("y",y) .attr("font-family", "sans-serif") .attr("font-size", "11px") .attr("fill", "white"); }); } All my code with the files tsv are here: full code
AmeliaBR is right as usual, and I am only putting this answer because while I was working on it, I saw myself changing the code so that it really makes use of the Enter, Update, Exit selection paradigm. I have made quite a few changes in that regard. Here is the code, FWIW: var margin = {top: 20, right: 20, bottom: 30, left: 40}, width = 960 - margin.left - margin.right, height = 500 - margin.top - margin.bottom; var formatPercent = d3.format(".0%"); var x = d3.scale.ordinal() .rangeRoundBands([0, width], .1, 1); var y = d3.scale.linear() .range([height, 0]); var xAxis = d3.svg.axis() .scale(x) .orient("bottom"); var yAxis = d3.svg.axis() .scale(y) .orient("left"); 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 + ")"); svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis); 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("weight"); var g = svg.append("g"); function update(file){ d3.tsv(file, function(error, data) { data.forEach(function(d) { d.weight = +d.weight; }); x.domain(data.map(function(d) { return d.concept; })); y.domain([0, d3.max(data, function(d) { return d.weight; })]); var bar = g.selectAll(".bar") .data(data); bar.enter() .append("rect") .attr("class","bar"); bar .style("fill", function (d){return d.color;}) .attr("class", "bar") .attr("x", function(d) { return x(d.concept); }) .attr("width", x.rangeBand()) .attr("y", function(d) { return y(d.weight); }) .attr("height", function(d) { return height - y(d.weight); }); bar.exit().remove(); var text = g.selectAll(".text") .data(data); text.enter() .append("text") .attr("class","text"); text .attr("text-anchor", "right") .attr("x", function(d) { return x(d.concept); }) .attr("y", function(d) { return y(d.weight) + 22;}) .attr("font-family", "sans-serif") .attr("font-size", "11px") .attr("fill", "white") .text(function(d) { return d.concept; }); text.exit().remove(); }); } And you call it like by doing update("data16.tsv") and then update("data15.tsv").
When you draw an axis, it creates separate <text> elements for each label inside the axis group inside the SVG. So if you then try to select all the <text> elements in the SVG, you're going to select all your axis labels. If you have more axis labels than data for text elements, your enter() selection will be empty and nothing will happen. To be sure you're only selecting the correct <text> elements, give your text labels a class to distinguish them from the axis labels. And then use that class to narrow-down your selector: svg.selectAll("text.bar-label") .data(data) .enter() .append("text") .attr("class", "bar-label")