javascript - D3.js - 在与图例交互时突出显示图表元素,反之亦然

标签 javascript d3.js toggle mouseover

我目前在每个节点上都有悬停效果,在图例的每个元素上也有悬停效果。

我想在用户与图例交互时执行效果,以便突出显示图表上的相关节点,反之亦然。我还想打开和关闭效果。

因此,当用户单击/悬停在节点上时,相关的图例项会以灰色突出显示。

当用户点击/悬停在图例项上时,相关节点会以黑色笔划突出显示。

我看过以下内容 ( Selectable Elements ),但不知道如何将其应用到我的代码中。

到目前为止,我的理解是我需要在鼠标悬停和切换时将一个类(类似于 .selected)应用于相关元素。

JSFiddle

//Nodes V2

var width = 300,
    height = 300,
    colors = d3.scale.category20b();

var force = d3.layout.force()
    .gravity(.2)
    .charge(-3000)
    .size([width, height]);

//Svg Chart SVG Settings
var svg = d3.select("#chart").append("svg:svg")
    .attr("width", width)
    .attr("height", height);

var root = getData();
var nodes = flatten(root),
    links = d3.layout.tree().links(nodes);

nodes.forEach(function(d, i) {
    d.x = width/2 + i;
    d.y = height/2 + 100 * d.depth;
});

root.fixed = true;
root.x = width / 2;
root.y = height / 2;

force.nodes(nodes)
    .links(links)
    .start();

var link = svg.selectAll("line")
    .data(links)
   .enter()
    .insert("svg:line")
    .attr("class", "link");

var node = svg.selectAll("circle.node")
    .data(nodes)
   .enter()
    .append("svg:circle")
    .attr("r", function(d) { return d.size/200; })
    //.attr('fill', function(d) { return d.color; }) // Use Data colors
    .attr('fill', function(d, i) { return colors(i); }) // Use D3 colors
    .attr("class", "node")
    .call(force.drag)

    .on('click', function(){
        d3.select( function (d){
            return i.li;
        })
            .style('background', '#000')       
    })

//Adding an event - mouseover/mouseout
    .on('mouseover', function(d) {

        d3.select(this)
            .transition()//Set transition
                .style('stroke', '#222222')
                .attr("r", function(d) { return (d.size/200) + 2; })
    })

    .on('mouseout', function(d) {

        d3.select(this)
            .transition()
                .style('stroke', '#bfbfbf')
                .attr("r", function(d) { return (d.size/200) - 2; })

        d3.select('ul')        
    });

//Add a legend
var legend = d3.select('#key').append('div')
    .append('ul')
    .attr('class', 'legend')
    .selectAll('ul')
    .data(nodes)
    .enter().append('li')
        .style('background', '#ffffff')
    .text(function(d) { return d.name; })

    .on('mouseover', function(d) {

        d3.select(this)
            .transition().duration(200)//Set transition
            .style('background', '#ededed')
    })

    .on('mouseout', function(d) {

        d3.select(this)
            .transition().duration(500)//Set transition
            .style('background', '#ffffff')
    })

    .append('svg')
        .attr('width', 10)
        .attr('height', 10)
        .style('float', 'right')
        .style('margin-top', 4)
    .append('circle')
        .attr("r", 5)
        .attr('cx', 5)
        .attr('cy', 5)
        .style('fill', function(d, i) { return colors(i); });

//Add Ticks
force.on("tick", function(e) {

    link.attr("x1", function(d) { return d.source.x; })
        .attr("y1", function(d) { return d.source.y; })
        .attr("x2", function(d) { return d.target.x; })
        .attr("y2", function(d) { return d.target.y; });

    node.attr("cx", function(d) { return d.x; })
        .attr("cy", function(d) { return d.y; });

});


//Center Node
var userCenter = d3.select("svg").append("svg:circle")
    .attr('class', 'user')
    .attr('r', 30)
    .attr('cx', width/2)
    .attr('cy', height/2)
    .style('fill', '#bfbfbf')

var label = d3.select('svg').append("text")
    .text('USER')
    .attr('x', width/2)
    .attr('y', height/2)
    .attr('text-anchor','middle')
    .attr('transform', 'translate(0, 5)')
    .style('font-size','12px')
    .attr('fill','#666666')

//Fix Root
function flatten(root) {
    var nodes = [];
    function recurse(node, depth) {
        if (node.children) {
            node.children.forEach(function(child) {
                recurse(child, depth + 1);
            });
        }
        node.depth = depth;
        nodes.push(node);
    }
    recurse(root, 1);
    return nodes;
}

//Data
function getData() {
    return {
        "name": "flare",
        "size": 0,
            "children": [
                { "name": "Jobs", "size": 3743 },
                { "name": "Contact", "size": 3302 },
                { "name": "Dietary", "size": 2903 },
                { "name": "Bookings", "size": 4823 },
                { "name": "Menu", "size": 3002 },
                { "name": "Cards", "size": 3120 },
                { "name": "Newsletter", "size": 3302 }
            ]
    };
}

最佳答案

您应该对节点和图例项使用相同的事件(鼠标悬停、鼠标移出)函数。

//Adding an event - mouseover/mouseout
    .on('mouseover', onMouseover)

    .on('mouseout', onMouseout);
...

//Legend
    .on('mouseover', onMouseover)

    .on('mouseout', onMouseout)

然后,您使用传递给函数的数据来选择正确的元素来更改样式。

function onMouseover(elemData) {

    d3.select("svg").selectAll("circle")
    .select( function(d) { return d===elemData?this:null;})
    .transition()//Set transition
                .style('stroke', '#222222')
                .attr("r", function(d) { return (d.size/200) + 2; })

     d3.select('#key').selectAll('li')
     .select( function(d) { return d===elemData?this:null;})
            .transition().duration(200)//Set transition
            .style('background', '#ededed')


}

function onMouseout(elemData) {

    d3.select("svg").selectAll("circle")
    .select( function(d) { return d===elemData?this:null;})
                                .transition()
                .style('stroke', '#bfbfbf')
                .attr("r", function(d) { return (d.size/200) - 2; })        

     d3.select('#key').selectAll('li')
     .select( function(d) { return d===elemData?this:null;})
                        .transition().duration(500)//Set transition
            .style('background', '#ffffff')


}

这是更新的 JSFiddle

关于javascript - D3.js - 在与图例交互时突出显示图表元素,反之亦然,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39833781/

相关文章:

Javascript 逻辑运算符 && 用于分配属性

php - 如何使用backbone.js从服务器渲染数据

javascript - 无法通过 LinkedIn 授权

javascript - D3中的长按事件

javascript - D3 教程在本地计算机上不起作用

javascript - 单击按钮时使用 JQuery 显示/隐藏某些 Div

javascript - 如何通过单击另一个链接来打开切换功能

javascript - vue js Prop 重置计时器

javascript - 当单独定义列时使用 D3 加载 JSON

css - 我怎样才能让菜单出现在左边呢?