使用 D3 创建可点击的图例

Creating clickable legends with D3

我正在尝试使用 D3 创建多折线图,但我一直无法关闭折线的可见性。到目前为止,只有一行,虽然我试图弄清楚(这仍然是一个初学者),但我无法让图例出现,所以我无法测试它是否真的会也摆脱这条线。这是 JavaScript 代码:

var BlackBird = [{
    "population": "100",
    "year": "1970"
}, {
"population": "100.8",
    "year": "1971"
}, {
"population": "103.5",
    "year": "1972"
}, {
"population": "95.6",
    "year": "1973"
}, {
"population": "101.7",
    "year": "1974"
}, {
"population": "102",
    "year": "1975"
}
];

var vis = d3.select("#visualisation"),
    WIDTH = 1110,
    HEIGHT = 580,
    MARGINS = {
        top: 30,
        right: 20,
        bottom: 20,
        left: 50
    },

xScale = d3.scale.linear()
    .range([MARGINS.left, WIDTH - MARGINS.right])
    .domain([1970,2008]),

yScale = d3.scale.linear()
    .range([HEIGHT - MARGINS.top, MARGINS.bottom])
    .domain([0,300]),

xAxis = d3.svg.axis()
    .scale(xScale)
    .ticks(25)
    .tickFormat(d3.format('0f')),

yAxis = d3.svg.axis()
    .scale(yScale)
    .orient("left")
    .ticks(12);

vis.append("svg:g")
    .attr("class", "axis")
    .attr("transform", "translate(0," + (HEIGHT - MARGINS.bottom) + ")")
    .call(xAxis);

vis.append("svg:g")
    .attr("class", "axis")
    .attr("transform", "translate(" + (MARGINS.left) + ",0)")
    .call(yAxis);

var lineGen = d3.svg.line()
    .x(function(d) {
        return xScale(d.year);
    })
    .y(function(d) {
        return yScale(d.population);
    })

    .interpolate("basis"); 

vis.append('path')
    .attr('d', lineGen(BlackBird))
    .attr('stroke-width', 5)
    .attr('fill', 'none')
    .attr('opacity', '0.2')
    .attr("id", "aline");

vis.append("text")
    .attr("x", WIDTH + MARGINS.left +10)             
    .attr("y", 10)    
    .attr("class", "legend")
    .style("fill", "steelblue")         
    .on("click", function(){
        var active   = aline.active ? false : true,
        newOpacity = active ? 0 : 1;
        d3.select("#aline").attr("opacity", newOpacity);
        aline.active = active;
    })
    .text("Blue Line");

HTML:

<!DOCTYPE html> <html lang= "en"> <head> <meta charset="UTF-8"> <title>D3 Birds</title> <link rel="stylesheet" href="D3Bird2.css"> </head> <body> <svg id="visualisation" width="1140" height="600"></svg> <div id ="BlaBird"> <img src="Blackbird.png" alt="A Blackbird" class= "Birdie"> </div> <script src="d3.min.js" charset="utf-8"> </script> <script src="script2.js" charset="utf-8"></script> </body> </html>

CSS:

.axis path {
  fill: none;
  stroke: #777;
  shape-rendering: crispEdges;
}
.axis text {
  font-family: Lato;
  font-size: 13px;
}
#aline {
  stroke: #000;
  opacity: 0.5;
  transition: 0.5s;
}
#aline: hover {
  opacity: 1;
  transition: 0.5s;
}
.Birdie {
  transition: 0.5s;
  opacity: 0.5;
}
#BlaBird {
  position: absolute;
  left: 1150px;
  top: 30px;
}
.legend {
  font-size: 16px;
  font-weight: bold;
  text-anchor: start;
}

首先,您没有包含 HTML 标记,但我假设 #visualisation 是一个 SVG 元素。确保您已为其分配高度和宽度属性。

其次,您没有为线条指定 stroke 颜色。我假设您在 CSS 某处执行此操作。

第三,修改你的变量名后,这一行:

.attr("x", width + margin.left +10) 

是问题所在。这会将文本元素推到它的 SVG 之外。

这里是 example 我已经解决了其中的一些问题。

编辑

查看您的 CSS 后出现新问题。您正在代码中设置 attribute 不透明度,CSS 设置 style 不透明度。两者都设置后,浏览器将使用该样式。因此,将您的点击处理程序更改为:

  .on("click", function() {
    var active = aline.active ? false : true,
      newOpacity = active ? 0 : 1;
    d3.select("#aline").style("opacity", newOpacity); //<-- set style, not attr
    aline.active = active;
  })

例子updated.