D3.js 使用函数时如何应用多个类

Posted

技术标签:

【中文标题】D3.js 使用函数时如何应用多个类【英文标题】:D3.js How to apply multiple classes when using a function 【发布时间】:2013-04-12 17:19:43 【问题描述】:

我目前正在使用 D3.js,但遇到了一个我似乎无法解决的问题。

我有一个 CSV,其中有一个名为“Set”的列和一个名为“Year”的列。我想从这些列中提取值并将它们用作类名。这是我目前拥有的...

var circle = svg.selectAll("circle")
            .data(data)
            .enter()
            .append("circle")
            .attr("class", function(d) 
                if (d["Set"] == 1)
                
                    return "set-1";
                
                if (d["Set"] == 2)
                
                    return "set-2";
                
            );

这工作得很好,并且给每个数据点一个类名。但是,当我尝试以下操作时,“Set”类名被“Year”类名覆盖。

var circle = svg.selectAll("circle")
            .data(data)
            .enter()
            .append("circle")
            .attr("class", function(d) 
                if (d["Set"] == 1)
                
                    return "set-1";
                
                if (d["Set"] == 2)
                
                    return "set-2";
                
            .attr("class", function(d) 
                if (d["Year"] == 2012)
                
                    return "2012";
                
                if (d["Year"] == 2013)
                
                    return "2013;
                
            );

如何纠正这段代码,以便添加额外的类名而不是覆盖它们。

希望有人能提供帮助。

【问题讨论】:

你考虑过使用 jQuery 吗?它有一个很好的addClass() 方法。 但是如何访问 .CSV 并将类应用到正确的数据节点? 在CSV文件中加载后可以添加类吗? 【参考方案1】:

更新

似乎,D3.js v5+ 不再接受这种方法

原答案

您也可以使用哈希作为classed 函数的参数:

var circle = svg.selectAll("circle")
  .data(data)
  .enter()
  .append('circle')
  .classed(
    '2012': function(d)  return d['Year'] === 2012; ,
    '2013': function(d)  return d['Year'] === 2013; ,
    'set-1': function(d)  return d['Set'] === 1; ,
    'set-2': function(d)  return d['Set'] === 2; 
  );

【讨论】:

【参考方案2】:

有一种替代方法很有用。您可以使用 selection.classed('class-name', true)selection.classed('class-name', false) 从元素中分配或删除类:

var circle = svg.selectAll("circle")
    .data(data)
    .enter()
    .append('circle')
    .classed('2012', function(d)  return d['Year'] === 2012; )
    .classed('2013', function(d)  return d['Year'] === 2013; )
    .classed('set-1', function(d)  return d['Set'] === 1; )
    .classed('set-2', function(d)  return d['Set'] === 2; );

我更喜欢这种方式,因为您可以使用相同的语法从元素中删除类。

【讨论】:

非常好的答案!我喜欢使用智能 D3 classed() 方法的建议。 +1! 使用classed(而不是attr('class'...)的更好理由是它不会清除已分配给该元素的其他类。【参考方案3】:

你只想要一个能同时做这两件事的函数。大概是这样的……

var circle = svg.selectAll("circle")
        .data(data)
        .enter()
        .append("circle")
        .attr("class", function(d) 
            var c = "";
            if (d["Set"] == 1)
            
                c = "set-1";
            
            if (d["Set"] == 2)
            
                c = "set-2";
            
            if (d["Year"] == 2012)
            
                c += " 2012";
            
            if (d["Year"] == 2013)
            
                c += " 2013;
            
            return c;
        );

【讨论】:

您先生绝对是个天才,为我节省了大量时间。 也可以直接拼接:.attr("class", function(d) "set-" + d["Set"] + " " + d["Year"] ). @LarsKotthoff 我想你需要一个return 没有..? 不喜欢这个diy。 Pablo 和@Ivan 的 OO 方法要好得多

以上是关于D3.js 使用函数时如何应用多个类的主要内容,如果未能解决你的问题,请参考以下文章

在我的 React.js 应用程序中导入 D3.js 库时出错

使用 AngularJs 和 D3.js 从 svg 元素调用自定义函数

使用 D3.js 为每个数据成员附加多个非嵌套元素

将 D3.js 7.0.0 与 Next.js 11.0.1 一起使用时,如何解决“[ERR_REQUIRE_ESM]:必须使用导入来加载 ES 模块”?

如何在带有 D3 的 Angular 中使用“this”?

使用d3.js滚动时如何将x轴保持在固定位置?