D3 中的子弹图刻度 - Boothead 示例

Bullet Chart Ticks in D3 - Boothead Example

我正在尝试让 D3 子弹图表中的图表标签跟随数据本身,按照此处的第二个示例: Bullet chart ticks & labels in D3.js

问题是这个 (http://boothead.github.io/d3/ex/bullet.html) 的来源不再存在于互联网上,唯一的东西是我链接的这个 post 中的 gif。

enter image description here 有没有人有这个项目的原件或者有什么建议?

我正在使用 mbostock 的第一个示例并尝试复制底部的示例。

非常感谢

来自 bostock 示例的原始 bullet.js https://bl.ocks.org/mbostock/4061961

不是从刻度中获取刻度,而是从范围、度量和标记中获取值

围绕第 109 行更改

  // var tickVals = x1.ticks(8);
  var tickVals = rangez.concat(measurez).concat(markerz);
  // Update the tick groups.
  var tick = g.selectAll("g.tick")
      .data(tickVals, function(d) {
        return this.textContent || format(d);
      });


编辑

如果您根据从服务器获取的新数据更新数据,则会出现问题。一些滴答声最终出现在错误的位置。如果标记、度量、范围的数量也发生变化,它们最终也会出现在错误的位置。

这取决于您为子弹调用提供的选择。

混乱是主程序命名不当造成的

  var svg = d3.select("body").selectAll("svg")
      .data(data)
    .enter().append("svg")
      .attr("class", "bullet")
      .attr("width", svgWidth)
      .attr("height", svgHeight)
    .append("g")
      .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
      .call(chart);

顾名思义,svg 是对 svg 个元素的选择。这是不正确的,它是 g 个元素的选择。

update() 函数应该反映这一点

function updateData() {
    d3.json("mailboxes.json", function (error, data) {
        d3.select("body")
          .selectAll("svg")
          .select('g')
          .data(data)
          .call(chart.duration(500));
    });
}

如果项目符号图的数量在更新时发生变化,则存在无法创建或根据需要删除它们的问题。所以我们需要制作一个可以用于初始和更新调用的函数。

function drawCharts() {
    d3.json("mailboxes.json", function (error, data) {
        var svg = d3.select("body").selectAll("svg").data(data);
        svg.exit().remove();
        svg.enter().append("svg")
            .attr("class", "bullet")
            .attr("width", svgWidth)
            .attr("height", svgHeight)
          .append("g")
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

        d3.select("body")
          .selectAll("svg")
          .select('g')
          .data(data)
          .call(chart.duration(500));
    });
}

bullet.js [109] 中更好的更改是:

  // var tickVals = x1.ticks(8);
  var tickVals = [];
  rangez.concat(measurez).concat(markerz).forEach(e => {
      if (tickVals.indexOf(e) == -1) tickVals.push(e);
  });
  // Update the tick groups.
  var tick = g.selectAll("g.tick").data(tickVals);

就是不要用tick的值来匹配,以防我们在tick中有多个值,去掉重复的。

我们还需要更改报价的更新,向下约 30 行

  tickUpdate.select("text")
      .attr("y", height * 7 / 6);

  tickUpdate.select("text")
      .text(format)
      .attr("y", height * 7 / 6);