简体   繁体   中英

D3 v3 - String values as x-axis domain for stacked chart not working

I have been struggling to get this chart work. I tried so many methods. It didn't show any error but doesn't draw the chart properly.

I want to use strings as x axis domain. I had even tried to set domain for x-scale. Still no use. The code which I have tried so far:

 $(".wrapper").delay(600).fadeIn(500); var barDataset = [{ "name": "aA", "date": 1, "successful": 1, "unsuccessful": 2 }, { "name": "bB", "date": 2, "successful": 41, "unsuccessful": 8 }, { "name": "cC", "date": 3, "successful": 44, "unsuccessful": 4 }, { "name": "dD", "date": 4, "successful": 2, "unsuccessful": 5 }, { "name": "eE", "date": 5, "successful": 21, "unsuccessful": 1 }, { "name": "fF", "date": 6, "successful": 14, "unsuccessful": 6 }, { "name": "gG", "date": 7, "successful": 42, "unsuccessful": 1 }, { "name": "hH", "date": 8, "successful": 10, "unsuccessful": 1 }, { "name": "iI", "date": 9, "successful": 24, "unsuccessful": 10 }, { "name": "jJ", "date": 10, "successful": 23, "unsuccessful": 6 }, { "name": "kK", "date": 11, "successful": 21, "unsuccessful": 15 }, { "name": "lL", "date": 12, "successful": 28, "unsuccessful": 15 } ] function drawBarGraph(data) { var status = ["successful", "unsuccessful"]; var colors = [ ["Successful", "#50E3C2"], ["Unsuccessful", "#EF5C6E"] ]; var margin = { top: 30, right: 30, bottom: 40, left: 60 }, width = 860 - margin.left - margin.right, height = 290 - margin.top - margin.bottom; var z = d3.scale.ordinal() .range(["#50E3C2", "#EF5C6E"]); /* var n = 12; var x = d3.scale.linear() .domain([1, n - 1]) .rangeRound([0, width], .1);*/ var x = d3.scale.ordinal() .domain(data.map(function(d) { return d['name']; })) .rangeRoundBands([0, width], .5); var y = d3.scale.linear() .rangeRound([height, 0]); var xAxis = d3.svg.axis() .scale(x) .orient("bottom") /*.tickFormat(d3.format("d")) .ticks(30)*/ ; var yAxis = d3.svg.axis() .scale(y) .orient("left") .ticks(5) .tickFormat(d3.format("d")); var svg = d3.select("#chart-bar") .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 layers = d3.layout.stack() (status.map(function(c) { return data.map(function(d) { return { x: d.date, y: d[c] }; }); })); y.domain([ 0, d3.max(layers[layers.length - 1], function(d) { return d.y0 + dy; }) ]); // gridlines in y axis function function make_y_gridlines() { return d3.svg.axis().scale(y) .orient("left").ticks(5); } // add the Y gridlines svg.append("g") .attr("class", "gridline") .call(make_y_gridlines() .tickSize(-width) .tickFormat("") ); svg.append("g") .attr("class", "axis axis--x") .attr("transform", "translate(6," + height + ")") .call(xAxis) .append("text") .attr("transform", "translate(364,0)") .attr("y", "3em") .style("text-anchor", "middle") .text("Days"); svg.append("g") .attr("class", "axis axis--y") .call(yAxis) .append("text") .attr("transform", "rotate(-90)") .attr("x", "-5em") .attr("y", "-2.5em") .style("text-anchor", "end") .text("Number of calls sent"); function type(d) { // d.date = parseDate(d.date); d.date; status.forEach(function(c) { d[c] = +d[c]; }); return d; } var tooltip = d3.select("#chart-bar").append("div") .attr("class", "tooltip") .style("opacity", 0); var layer = svg.selectAll(".layer") .data(layers) .enter().append("g") .attr("class", "layer") .style("fill", function(d, i) { return z(i); }); layer.selectAll("rect") .data(function(d) { return d; }) .enter().append("rect") .on("mouseover", function(d) { tooltip.transition() .duration(200) .style("opacity", 1); tooltip.html("<span>" + dy + " calls" + "</span>") .style("left", (d3.event.pageX - 25) + "px") .style("top", (d3.event.pageY - 28) + "px"); }) .on("mouseout", function(d) { tooltip.transition() .duration(500) .style("opacity", 0); }) .attr("x", function(d) { return x(dx); }) .attr("y", function(d) { return height; }) .attr("width", 12) .attr("height", 0) .transition().duration(1500) .attr("y", function(d) { return y(dy + d.y0); }) .attr("height", function(d) { return y(d.y0) - y(dy + d.y0); }); } drawBarGraph(barDataset); $('.count').each(function() { $(this).prop('Counter', 0).animate({ Counter: $(this).text() }, { duration: 1500, easing: 'swing', step: function(now) { $(this).text(Math.ceil(now)); } }); }); 
 @import url("https://fonts.googleapis.com/css?family=Overpass"); * { box-sizing: border-box; font: normal 14px/1.5 "Overpass", sans-serif; } body { background: #76daff; } .chart-wrapper { background: #333B66; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; clear: both; padding: 20px 0 10px; } text { font-size: 12px; fill: #A7B2EB; } .axis path, .axis line, .gridline line { fill: none; stroke: #fff; opacity: 0.1; shape-rendering: crispEdges; } .line { stroke: #17EAD9; stroke-width: 3px; fill: none; } path.domain { fill: none; opacity: 0.1; } div.tooltip { color: #4a4a4a; position: absolute; text-align: center; padding: 3px 6px; font-size: 12px; background: #fff; border-radius: 4px; pointer-events: none; } .tick text { font-size: 10px; } .vbroadcast-legend { float: right; margin-right: 40px; margin-top: 16px; } .vbroadcast-legend li { color: #fff; font-size: 13px; float: left; list-style: none; margin-left: 20px; padding-left: 18px; position: relative; } .vbroadcast-legend li:before { content: ""; height: 12px; left: 0; position: absolute; top: 3px; width: 12px; } .vbroadcast-legend li.successful:before { background: #50e3c2; } .vbroadcast-legend li.unsuccessful:before { background: #ef5c6e; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> <div id="chart-bar" class="chart-wrapper"></div> 

Kindly help me in fixing it. Thanks in advance.

If you have a list of 'aa' .. 'jj' and you set the domain of x to this list you most likely do not get tick marks like '0-15' and '15-30'.

Extract the x-domain values from the dataset or some other means of extracting the unique values. This is with the small dataset in the question.

var strn = ['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh', 'ii', 'jj'];
// ...
//x.domain(strn);
x.domain(data.map(d=>d.DB));

Thanks for getting back with the data. It's a minor fix in your code.

You're using name for drawing the X axis but it's not being mapped while being assigned to the layers array.

Relevant changes:

  1. Changed d.date to d.name

     return data.map(function(d) { return { x: d.name, y: d[c] }; }); 
  2. Assigning x to the rect s using this dx and axes rangeBand to align it with the ticks.

     .attr("x", function(d) { return x(dx) + x.rangeBand()/2; }) 

Snippet:

 $(".wrapper").delay(600).fadeIn(500); var barDataset = [{ "name": "aA", "date": 1, "successful": 1, "unsuccessful": 2 }, { "name": "bB", "date": 2, "successful": 41, "unsuccessful": 8 }, { "name": "cC", "date": 3, "successful": 44, "unsuccessful": 4 }, { "name": "dD", "date": 4, "successful": 2, "unsuccessful": 5 }, { "name": "eE", "date": 5, "successful": 21, "unsuccessful": 1 }, { "name": "fF", "date": 6, "successful": 14, "unsuccessful": 6 }, { "name": "gG", "date": 7, "successful": 42, "unsuccessful": 1 }, { "name": "hH", "date": 8, "successful": 10, "unsuccessful": 1 }, { "name": "iI", "date": 9, "successful": 24, "unsuccessful": 10 }, { "name": "jJ", "date": 10, "successful": 23, "unsuccessful": 6 }, { "name": "kK", "date": 11, "successful": 21, "unsuccessful": 15 }, { "name": "lL", "date": 12, "successful": 28, "unsuccessful": 15 } ] function drawBarGraph(data) { var status = ["successful", "unsuccessful"]; var colors = [ ["Successful", "#50E3C2"], ["Unsuccessful", "#EF5C6E"] ]; var margin = { top: 30, right: 30, bottom: 40, left: 60 }, width = 860 - margin.left - margin.right, height = 290 - margin.top - margin.bottom; var z = d3.scale.ordinal() .range(["#50E3C2", "#EF5C6E"]); /* var n = 12; var x = d3.scale.linear() .domain([1, n - 1]) .rangeRound([0, width], .1);*/ var x = d3.scale.ordinal() .domain(data.map(function(d) { return d['name']; })) .rangeRoundBands([0, width], .5); var y = d3.scale.linear() .rangeRound([height, 0]); var xAxis = d3.svg.axis() .scale(x) .orient("bottom") /*.tickFormat(d3.format("d")) .ticks(30)*/ ; var yAxis = d3.svg.axis() .scale(y) .orient("left") .ticks(5) .tickFormat(d3.format("d")); var svg = d3.select("#chart-bar") .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 layers = d3.layout.stack() (status.map(function(c) { return data.map(function(d) { return { x: d.name, y: d[c], }; }); })); y.domain([ 0, d3.max(layers[layers.length - 1], function(d) { return d.y0 + dy; }) ]); // gridlines in y axis function function make_y_gridlines() { return d3.svg.axis().scale(y) .orient("left").ticks(5); } // add the Y gridlines svg.append("g") .attr("class", "gridline") .call(make_y_gridlines() .tickSize(-width) .tickFormat("") ); svg.append("g") .attr("class", "axis axis--x") .attr("transform", "translate(6," + height + ")") .call(xAxis) .append("text") .attr("transform", "translate(364,0)") .attr("y", "3em") .style("text-anchor", "middle") .text("Days"); svg.append("g") .attr("class", "axis axis--y") .call(yAxis) .append("text") .attr("transform", "rotate(-90)") .attr("x", "-5em") .attr("y", "-2.5em") .style("text-anchor", "end") .text("Number of calls sent"); function type(d) { // d.date = parseDate(d.date); d.date; status.forEach(function(c) { d[c] = +d[c]; }); return d; } var tooltip = d3.select("#chart-bar").append("div") .attr("class", "tooltip") .style("opacity", 0); var layer = svg.selectAll(".layer") .data(layers) .enter().append("g") .attr("class", "layer") .style("fill", function(d, i) { return z(i); }); layer.selectAll("rect") .data(function(d) { return d; }) .enter().append("rect") .on("mouseover", function(d) { tooltip.transition() .duration(200) .style("opacity", 1); tooltip.html("<span>" + dy + " calls" + "</span>") .style("left", (d3.event.pageX - 25) + "px") .style("top", (d3.event.pageY - 28) + "px"); }) .on("mouseout", function(d) { tooltip.transition() .duration(500) .style("opacity", 0); }) .attr("x", function(d) { return x(dx) + x.rangeBand()/2; }) .attr("y", function(d) { return height; }) .attr("width", 12) .attr("height", 0) .transition().duration(1500) .attr("y", function(d) { return y(dy + d.y0); }) .attr("height", function(d) { return y(d.y0) - y(dy + d.y0); }); } drawBarGraph(barDataset); $('.count').each(function() { $(this).prop('Counter', 0).animate({ Counter: $(this).text() }, { duration: 1500, easing: 'swing', step: function(now) { $(this).text(Math.ceil(now)); } }); }); 
 @import url("https://fonts.googleapis.com/css?family=Overpass"); * { box-sizing: border-box; font: normal 14px/1.5 "Overpass", sans-serif; } body { background: #76daff; } .chart-wrapper { background: #333B66; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; clear: both; padding: 20px 0 10px; } text { font-size: 12px; fill: #A7B2EB; } .axis path, .axis line, .gridline line { fill: none; stroke: #fff; opacity: 0.1; shape-rendering: crispEdges; } .line { stroke: #17EAD9; stroke-width: 3px; fill: none; } path.domain { fill: none; opacity: 0.1; } div.tooltip { color: #4a4a4a; position: absolute; text-align: center; padding: 3px 6px; font-size: 12px; background: #fff; border-radius: 4px; pointer-events: none; } .tick text { font-size: 10px; } .vbroadcast-legend { float: right; margin-right: 40px; margin-top: 16px; } .vbroadcast-legend li { color: #fff; font-size: 13px; float: left; list-style: none; margin-left: 20px; padding-left: 18px; position: relative; } .vbroadcast-legend li:before { content: ""; height: 12px; left: 0; position: absolute; top: 3px; width: 12px; } .vbroadcast-legend li.successful:before { background: #50e3c2; } .vbroadcast-legend li.unsuccessful:before { background: #ef5c6e; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> <div id="chart-bar" class="chart-wrapper"></div> 

Hope this helps solve the issue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM