javascript - d3 自定义刻度线(基于nextSibling)

标签 javascript d3.js

我的数据中有间隙(在 y 轴上),因此即使我更愿意使用线性刻度,我也必须使用序数刻度 - 这样就看不到孔洞。

但是,我确实想使用不同的刻度线直观地显示数据不连续。这里的想法是检查下一个值 - 当前值是否为 1,如果不是,则绘制一条不同的刻度线。

使用this example我使用了 this.parentNode.nextSibling - 但它没有获得所需的值。

我怎样才能做到这一点?

下面的示例代码。我希望 2、5 和 8 的线条以不同的刻度显示(比如 Stroke-dasharray: "10,2" 或者可能是不同的颜色)

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Ticks problem</title>
  </head>
  <body>

    <svg width="500" height="300"></svg>

    <script src="https://d3js.org/d3.v4.min.js" charset="utf-8"></script>
    <script type="text/javascript">
      var svg = d3.select("svg"),
        margin = {top: 20, right: 0, bottom: 20, left: 0},
        width = +svg.attr("width") - margin.left - margin.right,
        height = +svg.attr("height") - margin.top - margin.bottom,
        g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");

      var data = [5, 15, 7, 10, 4, 12, 14];

      var yDomain = [1, 2, 4, 5, 8, 10, 11];
      var yRange  = Array(data.length+1).fill().map((d,i)=>(i+1)*35);
      var yScale = d3.scaleOrdinal()
          .domain(yDomain)
          .range(yRange);

      var yAxis = d3.axisRight(yScale)
        .ticks(data.length+1)
        .tickSize(width);

      function customYAxis(g) {
        g.call(yAxis);
        g.attr("id", "y-axis");
        g.select(".domain").remove();
        //g.selectAll(".tick line").attr("stroke", "#777").attr("stroke-dasharray", "2,2");
        g.selectAll(".tick line")
        .attr("stroke", "#777")
        .attr("stroke-dasharray", (d,i)=>{
          //let n = d3.select(this.parentNode.nextSibling).datum(); // not working
          //console.log(i + " " + d+" "+n);
          // return "10,2" if n-d > 1
          return "2,2"; // return some default for now
        })
        g.selectAll(".tick text").attr("x", 4).attr("dy", -4);
      }

      g.append('g').call(customYAxis);
    </script>

  </body>
</html>

最佳答案

记住,selection.attr()将被调用提供三个参数:

being passed the current datum (d), the current index (i), and the current group (nodes), with this as the current DOM element (nodes[i])

您可以使用第三个参数来访问下一个元素的数据。由于i是当前元素的索引,因此node[i+1]将指向下一个元素。您可以轻松选择下一个元素并使用 .datum() 检索绑定(bind)数据。

d3.select(nodes[i+1]).datum()

剩下的唯一一件事就是采用保护措施,以免读取 nodes 数组中的最后一个元素。

i < nodes.length - 1 && d3.select(nodes[i+1]).datum()

这可以直接在您的 .attr() setter 中使用:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Ticks problem</title>
  </head>
  <body>

    <svg width="500" height="300"></svg>

    <script src="https://d3js.org/d3.v4.min.js" charset="utf-8"></script>
    <script type="text/javascript">
      var svg = d3.select("svg"),
        margin = {top: 20, right: 0, bottom: 20, left: 0},
        width = +svg.attr("width") - margin.left - margin.right,
        height = +svg.attr("height") - margin.top - margin.bottom,
        g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");

      var data = [5, 15, 7, 10, 4, 12, 14];

      var yDomain = [1, 2, 4, 5, 8, 10, 11];
      var yRange  = Array(data.length+1).fill().map((d,i)=>(i+1)*35);
      var yScale = d3.scaleOrdinal()
          .domain(yDomain)
          .range(yRange);

      var yAxis = d3.axisRight(yScale)
        .ticks(data.length+1)
        .tickSize(width);

      function customYAxis(g) {
        g.call(yAxis);
        g.attr("id", "y-axis");
        g.select(".domain").remove();
        //g.selectAll(".tick line").attr("stroke", "#777").attr("stroke-dasharray", "2,2");
        g.selectAll(".tick line")
        .attr("stroke", "#777")
        .attr("stroke-dasharray", (d, i, nodes) => {
          return i < nodes.length - 1 && d3.select(nodes[i+1]).datum() - d > 1 ? "10,2" : "2,2";
        })
        g.selectAll(".tick text").attr("x", 4).attr("dy", -4);
      }

      svg.append('g').call(customYAxis);
    </script>

  </body>
</html>

关于javascript - d3 自定义刻度线(基于nextSibling),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47796771/

相关文章:

javascript - 当创建无限动画的另一个实例时,它消失了

javascript - JS - 使用for循环复制数组属性

javascript - 循环图像动画

javascript - 替换javascript中的类值

d3.js - d3 v6 指针函数未调整缩放和平移

html - Bootstrap 不允许我将数据与其他库一起使用

javascript - 使 Chart.js 雷达标签可点击

javascript - 正则表达式 flavor 翻译

javascript - d3 从 Angular 中选择

javascript - 在D3.JS的Choropleth map 上添加图例