D3.js Bar Chart not loading bars - javascript
This is my first time using D3.js, I adapted the code below from a tutorial and am pulling data from a .csv the axis are loading just fine, but for some reason the bar chart isnt rendering the bars? I'm sure it's something really simple.
Any help would really be much appreciated!
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.bar {
fill: steelblue;
}
.bar:hover {
fill: brown;
}
.axis--x path {
display: none;
}
</style>
<svg width="960" height="500"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var svg = d3.select("svg"),
margin = {top: 20, right: 20, bottom: 30, left: 40},
width = +svg.attr("width") - margin.left - margin.right,
height = +svg.attr("height") - margin.top - margin.bottom;
var x = d3.scaleBand().rangeRound([0, width]).padding(0.1),
y = d3.scaleLinear().rangeRound([height, 0]);
var g = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
d3.csv("/dash/templates/dashing/Features.csv", function(d) {
d.Used = +d.Used;
return d;
}, function(error, data) {
if (error) throw error;
x.domain(data.map(function(d) { return d.Feature; }));
y.domain([0, d3.max(data, function(d) { return d.Used; })]);
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).ticks(10, ))
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", "0.71em")
.attr("text-anchor", "end")
.text("Feature");
g.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) { return x(d.Feature); })
.attr("y", function(d) { return y(d.Used); })
.attr("width", x.bandwidth())
.attr("height", function(d) { return height - y(d.Feature); });
});
</script>
Your assumption is correct. A minor error in the code for calculating height of bars. You have to use return height - y(d.Used); instead of return height - y(d.Feature);
g.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) {
return x(d.Feature);
})
.attr("y", function(d) {
return y(d.Used);
})
.attr("width", x.bandwidth())
.attr("height", function(d) {
return height - y(d.Used); //Updated Line
});
var svg = d3.select("svg"),
margin = {
top: 20,
right: 20,
bottom: 30,
left: 40
},
width = +svg.attr("width") - margin.left - margin.right,
height = +svg.attr("height") - margin.top - margin.bottom;
var x = d3.scaleBand().rangeRound([0, width]).padding(0.1),
y = d3.scaleLinear().rangeRound([height, 0]);
var g = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var data = [{
Feature: "Feature 1",
Used: 10
}, {
Feature: "Feature 2",
Used: 20
}, {
Feature: "Feature 3",
Used: 15
}];
x.domain(data.map(function(d) {
return d.Feature;
}));
y.domain([0, d3.max(data, function(d) {
return d.Used;
})]);
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).ticks(10, ))
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", "0.71em")
.attr("text-anchor", "end")
.text("Feature");
g.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) {
return x(d.Feature);
})
.attr("y", function(d) {
return y(d.Used);
})
.attr("width", x.bandwidth())
.attr("height", function(d) {
return height - y(d.Used);
});
.bar {
fill: steelblue;
}
.bar:hover {
fill: brown;
}
.axis--x path {
display: none;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="960" height="500"></svg>
Related
How to make d3-diagram visualization from json-array working?
I have a problem with a d3 visualization (bar chart) that doesn't work. Instead of loading the data from a CSV file like in the tutorials on the d3 page (https://bl.ocks.org/mbostock/3885304), I want it to load from a JSON-array. Though I'm not sure why it doesn't seem like it loads at all. Can be something when I added the time parse, or placed the x.domain(data.map(function(d) { return d.date; })); outside a CSV load data snippet. Thank you for your help! <script type="text/javascript"> var data = [{date:"1999-06-23" ,value:1},{date:"1999-06-24" ,value:2},{date:"1999-06-28" ,value:3},{date:"1999-06-29" ,value:4},{date:"1999-06-30" ,value:5}]; var parseDate = d3.timeParse("%Y-%m-%d"); data.forEach(function(d) { d.date = parseDate(d.date); d.value = +d.value; }); var xAxis = d3.axisBottom(x) .tickFormat(d3.timeFormat("%Y-%m-%d")); var yAxis = d3.axisLeft(y) .ticks(10); var svg = d3.select("#graph").append("svg") .attr("width", 956) .attr("height", 360) margin = {top: 50, right: 100, bottom: 50, 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 + ")"); var x = d3.scaleBand().rangeRound([0, width]).paddingInner(0.05); var y = d3.scaleLinear().range([height, 0]); x.domain(data.map(function(d) { return d.date; })); y.domain([0, d3.max(data, function(d) { return d.value; })]); g.selectAll("bar") .data(data) .enter().append("rect") .style("fill", "steelblue") .attr("x", function (d) { return x(d.date); }) .attr("y", function (d) { return y(d.value); }) .attr("width", x.bandwidth()) .attr("height", function(d) { return height - y(d.value); }); svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis) .selectAll("text") .style("text-anchor", "end") .attr("dx", "-.8em") .attr("dy", "-.55em") .attr("transform", "rotate(-90)" ); 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("Value ($)"); </script> .axis { font: 10px sans-serif; } .axis path, .axis line { fill: none; stroke: #000; shape-rendering: crispEdges; } <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.0.0/d3.min.js"></script> <!DOCTYPE html> <html> <head> <link rel="stylesheet" href="style.css"> </head> <body> <script src="script.js"></script> </body> </html>
The list of the problems: Your reference to D3 is v3. However, your code uses v4. You are defining the axes generators before defining the scales. You are not translating the axes. Besides that, there is no such a thing as "JSON array". That's just an array. You probably meant hardcoded data Here is the working code: var data = [{ date: "1999-06-23", value: 1 }, { date: "1999-06-24", value: 2 }, { date: "1999-06-28", value: 3 }, { date: "1999-06-29", value: 4 }, { date: "1999-06-30", value: 5 }]; var parseDate = d3.timeParse("%Y-%m-%d"); data.forEach(function(d) { d.date = parseDate(d.date); d.value = +d.value; }); var svg = d3.select("body").append("svg") .attr("width", 956) .attr("height", 360); var margin = { top: 50, right: 100, bottom: 50, 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 + ")"); var x = d3.scaleBand().rangeRound([0, width]).paddingInner(0.05); var y = d3.scaleLinear().range([height, 0]); x.domain(data.map(function(d) { return d.date; })); y.domain([0, d3.max(data, function(d) { return d.value; })]); var xAxis = d3.axisBottom(x) .tickFormat(d3.timeFormat("%Y-%m-%d")); var yAxis = d3.axisLeft(y) .ticks(10); g.selectAll("bar") .data(data) .enter().append("rect") .style("fill", "steelblue") .attr("x", function(d) { return x(d.date); }) .attr("y", function(d) { return y(d.value); }) .attr("width", x.bandwidth()) .attr("height", function(d) { return height - y(d.value); }); svg.append("g") .attr("class", "x axis") .attr("transform", "translate(" + margin.left + "," + (height + margin.bottom) + ")") .call(xAxis) .selectAll("text") .style("text-anchor", "end") .attr("dx", "-.8em") .attr("dy", "-.55em") .attr("transform", "rotate(-90)"); svg.append("g") .attr("class", "y axis") .attr("transform", "translate(" + margin.left + "," + margin.top + ")") .call(yAxis) .append("text") .attr("transform", "rotate(-90)") .attr("y", 6) .attr("dy", ".71em") .style("text-anchor", "end") .text("Value ($)"); <script src="https://d3js.org/d3.v4.min.js"></script>
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.v3.min.js:2 Uncaught TypeError: Cannot read property 'length' of undefined
I have a mistake and I can not find it, thanks for your help. My data is called consumer_complaints.csv: date_received,product,sub_product,issue,sub_issue,consumer_complaint_narrative,company_public_response,company,state,zipcode,tags,consumer_consent_provided,submitted_via,date_sent_to_company,company_response_to_consumer,timely_response, consumer_disputed,complaint_id 08/30/2013,Mortgage,Other mortgage,Loan modification,collection,foreclosure,U.S. Bancorp,CA,95993,Referral,09/03/2013,Closed with explanation,Yes,Yes,511074 My code: <!DOCTYPE html> <meta charset="utf-8"> <style> body { font: 10px sans-serif; } .axis path, .axis line { fill: none; stroke: #000; shape-rendering: crispEdges; } .bar { fill: steelblue; } .x.axis path { display: none; } </style> <body> <script src="//d3js.org/d3.v3.min.js"></script> <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(["#ff0000", "#00ff00"]); 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("consumer_complaints.csv", function(error, data) { if (error) throw error; var nested_data = d3.nest() .key(function(d) { return d.submitted_via; }) .entries(data); var subVia = []; nested_data.forEach(function(d,i){ var count = 0; subVia[i] = d.key; d.values.forEach(function(v){ if(v.consumer_disputed == "Yes") count++ }); d.dispu = [{name: "Yes",value: count/d.values.length},{name: "No",value: (d.values.length-count)/d.values.length}]; }); x0.domain(subVia.forEach(function(d,i){ return subVia[i]; })); x1.domain(subVia).rangeRoundBands([0, x0.rangeBand()]); y.domain([0, d3.max(nested_data, function(d) { return d3.max(d.dispu, function(d) { 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", ".71em") .style("text-anchor", "end") .text("Satisfaction"); var state = svg.selectAll(".state") .data(data) .enter().append("g") .attr("class", "state") .attr("transform", subVia.forEach( function(d,i) {console.log(subVia[i]); return "translate(" + x0(subVia[i]) + ",0)"; })); state.selectAll("rect") .data(function(d) { return d.dispu; }) .enter().append("rect") .attr("width", x1.rangeBand()) .attr("x", function(d) { return x1(d.key); }) .attr("y", function(d) { return y(d.value); }) .attr("height", function(d) { return height - y(d.value); }) .style("fill", function(d) { return color(d.key); }); var legend = svg.selectAll(".legend") .data(subVia.slice().reverse()) .enter().append("g") .attr("class", "legend") .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; }); legend.append("rect") .attr("x", width - 18) .attr("width", 18) .attr("height", 18) .style("fill", color); legend.append("text") .attr("x", width - 24) .attr("y", 9) .attr("dy", ".35em") .style("text-anchor", "end") .text(function(d) { return d; }); }); </script>
<!DOCTYPE html> <meta charset="utf-8"> <style> body { font: 10px sans-serif; } .axis path, .axis line { fill: none; stroke: #000; shape-rendering: crispEdges; } .bar { fill: steelblue; } .x.axis path { display: none; } </style> <body> <script src="//d3js.org/d3.v3.min.js"></script> <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(["#ff0000", "#00ff00"]); 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("consumer_complaints.csv", function(error, data) { if (error) throw error; var nested_data = d3.nest() .key(function(d) { return d.submitted_via; }) .entries(data); var subVia = []; nested_data.forEach(function(d,i){ var count = 0; subVia[i] = d.key; d.values.forEach(function(v){ if(v.consumer_disputed == "Yes") count++ }); d.dispu = [{name: "Yes",value: count/d.values.length},{name: "No",value: (d.values.length-count)/d.values.length}]; }); x0.domain(subVia.forEach(function(d,i){ return subVia[i]; })); x1.domain(subVia).rangeRoundBands([0, x0.rangeBand()]); y.domain([0, d3.max(nested_data, function(d) { return d3.max(d.dispu, function(d) { 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", ".71em") .style("text-anchor", "end") .text("Satisfaction"); var state = svg.selectAll(".state") .data(data) .enter().append("g") .attr("class", "state") .attr("transform", subVia.forEach( function(d,i) {console.log(subVia[i]); return "translate(" + x0(subVia[i]) + ",0)"; })); state.selectAll("rect") .data(function(d) { return d.dispu; }) .enter().append("rect") .attr("width", x1.rangeBand()) .attr("x", function(d) { return x1(d.key); }) .attr("y", function(d) { return y(d.value); }) .attr("height", function(d) { return height - y(d.value); }) .style("fill", function(d) { return color(d.key); }); var legend = svg.selectAll(".legend") .data(subVia.slice().reverse()) .enter().append("g") .attr("class", "legend") .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; }); legend.append("rect") .attr("x", width - 18) .attr("width", 18) .attr("height", 18) .style("fill", color); legend.append("text") .attr("x", width - 24) .attr("y", 9) .attr("dy", ".35em") .style("text-anchor", "end") .text(function(d) { return d; }); }); </script>
D3 chart not showing up
Problem Having trouble getting my chart in D3 to show up. Getting an Uncaught SyntaxError: Unexpected end of input with my scripts.js index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <link rel="stylesheet" href="assets/css/style.css"> </head> <body> <script src="assets/js/scripts.js"></script> <script src="http://d3js.org/d3.v3.min.js"></script> </body> </html> scripts.js $(function() { 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", "#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(".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("assets/data/data.csv", function(error, data) { var ageNames = d3.keys(data[0]).filter(function(key) { return key !== "State"; }); data.forEach(function(d) { d.ages = ageNames.map(function(name) { return {name: name, value: +d[name]}; }); }); x0.domain(data.map(function(d) { return d.State; })); x1.domain(ageNames).rangeRoundBands([0, x0.rangeBand()]); y.domain([0, d3.max(data, function(d) { return d3.max(d.ages, function(d) { 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", ".71em") .style("text-anchor", "end") .text("Population"); var state = svg.selectAll(".state") .data(data) .enter().append("g") .attr("class", "g") .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); }); var legend = svg.selectAll(".legend") .data(ageNames.slice().reverse()) .enter().append("g") .attr("class", "legend") .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; }); legend.append("rect") .attr("x", width - 18) .attr("width", 18) .attr("height", 18) .style("fill", color); legend.append("text") .attr("x", width - 24) .attr("y", 9) .attr("dy", ".35em") .style("text-anchor", "end") .text(function(d) { return d; }); }); style.css body { font: 10px sans-serif; } .axis path, .axis line { fill: none; stroke: #000; shape-rendering: crispEdges; } .bar { fill: blue; } .x.axis path { display: none; }
I found that I got the same error when pasting your code directly into JSFiddle. It went away when I properly closed the main function. For reference, here's your code in live snippet form with the extra closing braces: var csvData = [ {"State":0, "Age":31, "Names":["Austin"]}, {"State":0, "Age":31, "Names":["Austin"]}, {"State":0, "Age":31, "Names":["Austin"]}, ]; $(function() { $("#placeholder").remove(); 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", "#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(".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 + ")"); var data = csvData; var ageNames = d3.keys(data[0]).filter(function(key) { return key !== "State"; }); data.forEach(function(d) { d.ages = ageNames.map(function(name) { return {name: name, value: +d[name]}; }); }); x0.domain(data.map(function(d) { return d.State; })); x1.domain(ageNames).rangeRoundBands([0, x0.rangeBand()]); y.domain([0, d3.max(data, function(d) { return d3.max(d.ages, function(d) { 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", ".71em") .style("text-anchor", "end") .text("Population"); var state = svg.selectAll(".state") .data(data) .enter().append("g") .attr("class", "g") .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); }); var legend = svg.selectAll(".legend") .data(ageNames.slice().reverse()) .enter().append("g") .attr("class", "legend") .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; }); legend.append("rect") .attr("x", width - 18) .attr("width", 18) .attr("height", 18) .style("fill", color); legend.append("text") .attr("x", width - 24) .attr("y", 9) .attr("dy", ".35em") .style("text-anchor", "end") .text(function(d) { return d; }); }); body { font: 10px sans-serif; } .axis path, .axis line { fill: none; stroke: #000; shape-rendering: crispEdges; } .bar { fill: blue; } .x.axis path { display: none; } <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
On the d3.csv("csv...") call - try adding another }); to the end of it. I tried your code out on JSFiddle, and that seemed to resolve the syntax error. EDIT: My bad. Left in a hurry. Here's the fiddle: http://jsfiddle.net/strsjpxa/ I later noticed it made more sense to close the function at the end.
Hyperlink chart bars using D3
I am using the D3 toolkit to create a stacked bar graph of some data. I want link the bars to a separate page with more detail about the underlying data for that bar. I can't figure out how to turn the bars into hyperlinks. The code below is based on a demo that I have been tinkering with. When I inspect the code in Google Chrome it looks correct but the bars aren't clickable. Tremendous thanks in advance for ideas and suggestions on this! Source, attempting to add link to Google to each bar: <!DOCTYPE html> <meta charset="utf-8"> <style> body { font: 10px sans-serif; } .axis path, .axis line { fill: none; stroke: #000; shape-rendering: crispEdges; } .bar { fill: steelblue; } .x.axis path { display: none; } </style> <body> <script src="d3.min.js"></script> <script> var margin = {top: 20, right: 20, bottom: 30, left: 40}, width = 960 - margin.left - margin.right, height = 500 - margin.top - margin.bottom; var x = d3.scale.ordinal() .rangeRoundBands([0, width], .1); var y = d3.scale.linear() .rangeRound([height, 0]); var color = d3.scale.ordinal() .range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]); var xAxis = d3.svg.axis() .scale(x) .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("./data.csv", function(error, data) { color.domain(d3.keys(data[0]).filter(function(key) { return key !== "State"; })); data.forEach(function(d) { var y0 = 0; d.ages = color.domain().map(function(name) { return {name: name, y0: y0, y1: y0 += +d[name]}; }); d.total = d.ages[d.ages.length - 1].y1; }); data.sort(function(a, b) { return b.total - a.total; }); x.domain(data.map(function(d) { return d.State; })); y.domain([0, d3.max(data, function(d) { return d.total; })]); 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("Population"); var state = svg.selectAll(".state") .data(data) .enter().append("g") .attr("class", "g") .attr("xlink:href", function(d) { return "http://www.google.com"; }) .attr("transform", function(d) { return "translate(" + x(d.State) + ",0)"; }); state.selectAll("rect") .data(function(d) { return d.ages; }) .enter().append("rect") .attr("width", x.rangeBand()) .attr("y", function(d) { return y(d.y1); }) .attr("height", function(d) { return y(d.y0) - y(d.y1); }) .style("fill", function(d) { return color(d.name); }); state.append("a") .attr("xlink:href", "http://www.google.com") ; var legend = svg.selectAll(".legend") .data(color.domain().slice().reverse()) .enter().append("g") .attr("class", "legend") .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; }); legend.append("rect") .attr("x", width - 18) .attr("width", 18) .attr("height", 18) .style("fill", color); legend.append("text") .attr("x", width - 24) .attr("y", 9) .attr("dy", ".35em") .style("text-anchor", "end") .text(function(d) { return d; }); }); </script>
I'm not sure that you can add "a" html mark in SVG. But you can add an event on each bar segment: state.on('click',function(d){ ... some great code ... })