首页 > 解决方案 > 将数据绑定到轴标签

问题描述

我正在使用 d3 v4。我想将数据 d.name 绑定到轴标签。但是在域的数据中使用不同的值 d.num。

d3.json("data.json", function(error, newdata) {
    if (error) throw error;

    data = newdata;
    var name = [];

    // data.forEach(function(d) {
    //   // console.log(d.name);
    //   if (name.length < data.length - 1) {
    //     // console.log("name.length = " + name.length);
    //     name.push(d.name);
    //   }
    // });

    // xAxis = d3.axisBottom(x).tickSize(0);

    xAxis = d3.axisBottom(x).tickSize(0).tickFormat(function(d, i) {
      console.log("name[" + i + "] = " + name[i]);
      console.log("data[" + i + "].name: " + data[i].num);
      // return name[i];
      return d.name;
    }).ticks(name.length).tickSize(10);

............

});

数据,

[{
    "name": "A",
    "num": "1",
    "distance": "1900"
  },
  {
    "name": "B",
    "num": "2",
    "distance": "1500"
  },
  {
    "name": "C",
    "num": "3",
    "distance": "2500"
  },
  {
    "name": "D",
    "num": "4",
    "distance": "2300"
  },
  {
    "name": "E",
    "num": "5",
    "distance": "2000"
  }
]

问题是数据没有绑定到 xAxis 变量。我怎么能这样做?

从代码的注释部分可以看出,我尝试将 d.name 值传递给名为 name 的数组。但这会在以后引起问题,所以这就是我尝试将实际数据 d.name 绑定到标签的原因。

有一个类似的帖子将数据绑定到轴刻度 d3.js但这是 2010 年,因此不适用于 v4。我也不确定如何在我的情况下应用它。

谢谢,

标签: d3.jsbindaxislabels

解决方案


轴上的每个刻度都绑定了一个基准:它是传递给轴的刻度域中的元素。

在您的特定情况下,最好的想法可能是使用filter零索引(或者find,如果浏览器支持它)根据刻度的基准(同样,对应于刻度的域)获取数据数组中的对象。

但是,回答您的问题标题(“如何将数据绑定到轴”),您可以通过直接操作第一个参数(tickFormat例如,甚至是each函数内部)来实现。但是,这将与当前数据混淆。

更安全的方法是使用局部变量,例如...

var local = d3.local();

...您可以使用它通过索引获取数据数组中的对象。之后,局部变量将绑定到 DOM 元素。

看一下这个演示,轴是使用num域的比例制作的,但是name属性会在 1 秒后改变,使用绑定到它们的局部变量:

var data = [{
    num: 1,
    name: "foo"
  },
  {
    num: 2,
    name: "bar"
  },
  {
    num: 3,
    name: "baz"
  }
];

var svg = d3.select("svg");

var local = d3.local();

var scale = d3.scalePoint()
  .range([50, 250])
  .domain(data.map(function(d) {
    return d.num
  }))

var axis = d3.axisBottom(scale)
  .tickFormat(function(d, i) {
    local.set(this, data[i].name);
    return d;
  })

var gX = svg.append("g")
  .attr("transform", "translate(0,100)")
  .call(axis);

d3.timeout(function() {
  axis.tickFormat(function() {
    return local.get(this)
  });
  gX.call(axis)
}, 1000)
<script src="https://d3js.org/d3.v5.min.js"></script>
<svg></svg>


推荐阅读