javascript - 基于数据属性的 d3 节点子结构/样式

标签 javascript d3.js

我想创建多个函数,这些函数根据数据以不同的方式“设置”矩形(即调用不同的 .attr().style() 函数甚至根据数据附加其他元素)。

我设法使用 .call(myDecorator) 将样式分派(dispatch)给一个单独的函数,但在这里我有点吃惊。在rectDecorator中,我希望根据d.type调用不同的子选择。目前 (.style('fill'...).style(...).style(...)) 仅显示装饰矩形的可能方法之一,但理想情况下,我想根据 d.type“分支”到不同的链式命令。知道如何实现吗?

    function rectDecorator(selection) {
      // call different selection.xyz functions to style rect differently based on `d.type`
      return selection
        .style('fill', function(d) {
          return d.color;
        })
        .style('fill-opacity', 1)
        .style('stroke-width', 0);
    }


    d3.select('svg')
      .selectAll('g')
      .data(data)
      .join(
        enter => enter
          .append('g')
          .append('rect')
            .attr('x', ...)
            .attr('y', ...)
            .attr('height', 20)
            .attr('width', 40)
            .call(rectDecorator)
        update => update(),
        exit => exit.remove()

最佳答案

对此有多种可能的解决方案,但在某些时候,您将不得不遍历选择以检查每个元素的单独类型以找到特定的装饰器。您可以设置一个 Map,从而将类型映射到它们相应的装饰器。

const decorators = new Map([
  ["type1", selection => selection.attr("attr1", "...")],
  ["type2", selection => selection.attr("attr2", "...")]
]);

之后,您可以使用 .each() 轻松循环选择。并根据数据的 type 属性从 map 中获取合适的装饰器:

.each(function(d) {
  d3.select(this).call(decorators.get(d.type));
})

对于工作演示,请查看以下代码片段:

const decorators = new Map([
    ["red", selection => selection.attr("fill", "red")],
    ["green", selection => selection.attr("fill", "none").attr("stroke", "green")]
  ]);

const data = [{ type: "green" }, { type: "red" }];

d3.select('body').append("svg")
  .selectAll('g')
  .data(data)
  .join(
    enter => enter
    .append('g')
    .append('rect')
      .attr('x', (_, i) => i * 50 + 50)
      .attr('y', 50)
      .attr('height', 20)
      .attr('width', 40)
      .each(function(d) {
        d3.select(this).call(decorators.get(d.type));
      })
  );
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.15.0/d3.js"></script>

关于javascript - 基于数据属性的 d3 节点子结构/样式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60294414/

相关文章:

javascript - 最多 6 个字符的混合数字的正则表达式验证

javascript - 当我将数组索引存储为变量时,代码不起作用

javascript - 当涉及到 Websockets 时,我不确定要使此应用程序在 Google Cloud 上正常运行我缺少什么

angular - d3 v4 插件 - 如何需要其他 d3 插件?

javascript - D3js强制布局 - 节点之间的渐变线

javascript - 如何避免在 D3 中对颜色进行硬编码

javascript - ng-show 令人不安的 div 布局 - angularJS

javascript - 使用 v-if 隐藏后,文件输入不会显示文件名

javascript - 在 D3 中的条形图上需要有关年份和犯罪头变量选择的帮助

javascript - 将子组中的名称排序为组 - 重组 json 数据