【问题标题】:D3 v3 - String values as x-axis domain for stacked chart not workingD3 v3 - 作为堆叠图表的 x 轴域的字符串值不起作用
【发布时间】:2018-08-16 12:47:07
【问题描述】:

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

我想使用字符串作为 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>

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

【问题讨论】:

  • 您现在使用上述数据对象得到的输出是什么?
  • 如果我为 x 轴提供“DB”数据,所有条形都将堆积在 0 上。
  • 是的,这是可能的。介意发布您的代码吗?更好的是代码 sn-p 可以通过修复进行分叉。
  • bl.ocks.org/mbostock/3885304 将 x-scale 的域设置为您想要作为刻度文本的字符串
  • @rioV8 我试过但没用。第二张图是我得到的结果。

标签: javascript jquery html d3.js


【解决方案1】:

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

您正在使用 name 绘制 X 轴,但它在分配给 layers 数组时没有被映射。

相关变化:

  1. d.date 更改为d.name

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

    .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>

希望这有助于解决问题。

【讨论】:

  • 天啊,非常感谢!!!它就像一个魅力!我已经打破我的头 2 周来解决它!非常感谢!!
  • 当然。很高兴我能帮上忙! :) 当您拥有正确的数据时,提出解决方案总是更容易。感谢您回复。
【解决方案2】:

如果您有一个 'aa' .. 'jj' 的列表,并且您将 x 的域设置到此列表,您很可能不会得到像 '0-15' 和 '15-30' 这样的刻度线。

从数据集中提取 x 域值或提取唯一值的其他方法。这是问题中的小数据集。

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

【讨论】:

  • 我只得到第二个图像结果。
  • @Yogapriya:如果我用你的虚拟数据改变你的示例代码中的这一行,我会得到'0-15'...刻度标记文本
猜你喜欢
  • 2013-03-12
  • 2015-06-25
  • 1970-01-01
  • 2012-07-31
  • 2018-09-19
  • 2021-01-21
  • 2021-09-29
  • 2011-11-25
相关资源
最近更新 更多