How to simultaneously update the color of elements in a SVG when I mouseover elements of a second SVG using D3

会有一股神秘感。 提交于 2019-12-24 13:28:40

问题


I created two different SVGs. One contains a graph with data points, the other one contains three lines. The lines color are supposed to be dependent on the selected data point and I have not managed to get this done yet (more details below). The jsfiddle can be found here: jsfiddle.

What I would like to do is to change the color of the three lines when I mouseover the data points. I managed to change the color of all lines to the same color but would actually like to use the color that is associated to the respective data point but I don't know how I can pass the color data which are stored in myColors to the function where I set the lines' color.

The relevant code is shown below. I add a graph with datapoints to mySvg and when I mouseover the data points, I change their color to black and the color of the lines in the other SVG to green. However, instead of changing all lines' color to green, I would actually like to change their colors to the colors defined in myColors (see the above linked jsfiddle to find the data). How could I do this?

var circles = mySvg.selectAll("circle")
                         .data(lineData)
                         .enter()
                         .append("circle");

var circleAttributes = circles
                       .attr("cx", function (d) { return xScale(d.x); })
                       .attr("cy", function (d) { return yScale(d.y); })
                       .attr("r", 6)
                       .style("fill", 'red')
                       .on('mouseover', function(d){
                           d3.select(this).style("fill", 'black');
                           d3.select('#myLines').selectAll("line").attr("class","sweepline").style("stroke", 'green');

                           })

                       .on('mouseout', function(d){
                           d3.select(this).style("fill", 'red');

                        }); 

回答1:


As with many d3 problems this one is easily solved using data binding. Your custom colors could be bound to the lines you append to the second SVG. Since your array myColors, consisting of the arrays of custom colors per line, has the same structure as your other arrays like names, x1Val, y1Val and so forth, it can be easily integrated in the data array coords used for binding information to your lines:

var coords = d3.zip(names, x1Val, y1Val, x2Val, y2Val, myColors);

This data per line can later on be used in the mouseover event handler for your circles setting the stroke style on the lines.

.on('mouseover', function(d,i) {
    // ...
    d3.select('#myLines')
        .selectAll("line")
            .style("stroke", function(d) {
                return d[5][i].color;
            });
})

The callback determines the color by

  1. accessing the array of custom colors, which is at position 5 of the data array bound to the lines, hence d[5],
  2. getting the ith object of this array of colors. The i is the index of this circle, which is passed as parameter to the event handler and made available to the stroke callback by a closure,
  3. getting property .color from this object

Check the updated JSFiddle for a working example.


Furthermore, I have updated the mouseout handler to delete the previously set stroke style causing the lines to be reset to their default color set by class sweepline. This behaviour, at least to my eyes, seemed to be missing.

d3.select('#myLines')
    .selectAll("line")
        .style("stroke", null); 


来源:https://stackoverflow.com/questions/32355711/how-to-simultaneously-update-the-color-of-elements-in-a-svg-when-i-mouseover-ele

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!