首页 > 解决方案 > D3 v3 - 作为堆叠图表的 x 轴域的字符串值不起作用

问题描述

我一直在努力让这个图表工作。我尝试了很多方法。它没有显示任何错误,但没有正确绘制图表。

我想使用字符串作为 x 轴域。我什至尝试为 x-scale 设置域。还是没用。到目前为止我尝试过的代码:

$(".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 + d.y;
    })
  ]);


  // 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>" + d.y + " 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(d.x);
    })
    .attr("y", function(d) {
      return height;
    })
    .attr("width", 12)
    .attr("height", 0)
    .transition().duration(1500)
    .attr("y", function(d) {
      return y(d.y + d.y0);
    })
    .attr("height", function(d) {
      return y(d.y0) - y(d.y + 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>

请帮我修复它。提前致谢。

标签: javascriptjqueryhtmld3.js

解决方案


感谢您返回数据。这是您代码中的一个小修复。

name用于绘制 X 轴,但在分配给layers数组时未映射。

相关变化:

  1. 改为d.date_d.name

    return data.map(function(d) {
      return {
        x: d.name,
        y: d[c]
      };
    });
    
  2. 使用 this和轴rangeBand分配x给s以使其与刻度对齐。rectd.x

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

片段:

$(".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 + d.y;
    })
  ]);


  // 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>" + d.y + " 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(d.x) + x.rangeBand()/2;
    })
    .attr("y", function(d) {
      return height;
    })
    .attr("width", 12)
    .attr("height", 0)
    .transition().duration(1500)
    .attr("y", function(d) {
      return y(d.y + d.y0);
    })
    .attr("height", function(d) {
      return y(d.y0) - y(d.y + 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>

希望这有助于解决问题。


推荐阅读