【问题标题】:D3.js How to apply multiple classes when using a functionD3.js 使用函数时如何应用多个类
【发布时间】: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文件中加载后可以添加类吗?

标签: javascript html css svg d3.js


【解决方案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 方法要好得多
    猜你喜欢
    • 1970-01-01
    • 2022-01-10
    • 2017-12-12
    • 1970-01-01
    • 2012-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多