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

Dal*_*lly 22 html javascript css svg d3.js

我目前正在使用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";
                }
            });
Run Code Online (Sandbox Code Playgroud)

这完全正常,并为每个数据点提供一个类名.但是,当我尝试以下操作时,"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;
                }
            });
Run Code Online (Sandbox Code Playgroud)

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

希望有人能提供帮助.

Pab*_*rro 62

有一种替代方法可能有用.您可以使用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; });
Run Code Online (Sandbox Code Playgroud)

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

  • 更好的理由是使用`classed`(而不是`attr('class'...`)它将不会清除已经分配给该元素的其他类. (8认同)

Iva*_*ack 18

您还可以使用哈希作为函数的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; }
  });
Run Code Online (Sandbox Code Playgroud)

  • 这很优雅,但在D3 v5中不起作用。 (2认同)

Rob*_*son 15

你只想要一个能让两件事都做不到的功能.沿着这些路线的东西也许......

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;
        });
Run Code Online (Sandbox Code Playgroud)

  • 你也可以直接连接:`.attr("class",function(d){"set-"+ d ["Set"] +""+ d ["Year"]})`. (6认同)
  • 不喜欢这个diy。Pablo和@Ivan的OO方法要好得多 (2认同)