在Force-Directed Graph中覆盖d3索引值

时间:2015-04-10 01:23:47

标签: javascript d3.js

我使用强制有向图来绘制公司的实体关系。我想要做的是使用我的内置索引值作为"索引"节点而不是数组索引。如何覆盖设置的d3索引值?小提琴 - http://jsfiddle.net/thielcole/ed9noqw1/

var forceLinks = [];
var forceData = [];

d3.csv('AmazonExampleforiCharts.csv', function(d) {
    return { // This is the index I would like to use
        index: d.Node,
        parent: d.ParentNode,
        color: d.NodeColor,
        level: d.Hierarchy_code,
        business: d.Business_Name,
        power: d.Decisionpower,
        hover: d.HoverOverValue,
        link: d.LinkVALUE
    };
}, function(error, rows) {
        forceData = rows;
        $.each(forceData, function(i, d) {
             // console.log(d.parent);

            if (d.parent != "" && d.parent !== undefined) { // generating link information here, I have to subtract one initially to match the array index
                forceLinks.push({source: parseInt(d.parent , 10) - 1 , target: parseInt(d.index , 10) - 1, value: parseInt(d.level , 10)});
            }
            console.log(d);
        });

    $.each(forceLinks, function(i, d) {
        // console.log(d);
    });


    initiateChart();
});

function initiateChart() {
    var height = 1000,
        width = 1400;



    var graphData = [];
    var graphLinks = [];

    graphData = forceData;
    graphLinks = forceLinks;

    var color = d3.scale.category20();

    var svg = d3.select('.svg')
            .attr('width', width)
            .attr('height', height);

    var force = d3.layout.force()
            .charge(-120)
            .linkDistance(30)
            .size([width, height]);
    // this is where it gets set 
    force.nodes(graphData)
            .links(graphLinks)
            .start();

    var link = svg.selectAll('.link')
            .data(graphLinks)
            .enter().append('line')
            .attr('class', 'link')
            .style('stroke-width', function (d) {
                return Math.sqrt(d.value);
            });

    var node = svg.selectAll('.node')
            .data(graphData)
            .enter().append('circle')
            .attr('class', 'node')
            .attr('r', 8)
            .style('fill', function (d) {
                return color(d.level);
            })
            .on('mouseover', function(d , i) {

                d3.select(this).attr('r', 12);
                var tooltip = d3.select('body')
                        .append('div')
                        .attr('class', 'tooltip')
                        .style('position','absolute')
                        .style('top', (d3.event.pageY - 10) + 'px')
                        .style('left' , (d3.event.pageX) + 'px' )
                        .style('z-index' , '10')
                        .text(d.hover);
                console.log(d)

            })
            .on('click', function(d , i) {
                    showChildren(d);
            })
            .on('mouseout', function(d, i) {

                d3.select(this).attr('r', 8);
                d3.select('body').selectAll('.tooltip')
                        .remove();
            })
            .call(force.drag);

    //Now we are giving the SVGs co-ordinates - the force layout is generating the co-ordinates which this code is using to update the attributes of the SVG elements

    force.on("tick", function () {
        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;
                })

    });

}

1 个答案:

答案 0 :(得分:0)

var node = svg.selectAll('.node')
                .data(graphData)
                .enter().append('circle')
                .attr('class', 'node')
                .attr('r', 8)
                .attr('id', function(d){return(d.index);})// use the data 'index' property as node 'id' attribute
                .style('fill', function (d) {
                    return color(d.level);
                })
                .call(force.drag);

' -es' -es将存储在圈子中?' id'属性为字符串(而不是数字):

enter image description here

您可以根据需要添加任意数量的属性,稍后再调用它们。实际上,id标记不是最佳选择。更好的选择是:data-indexdata-iddata-company等。

PS:

符号.attr('class', 'node')不是错误,但d3.js对类有特殊的selection.classed(name[, value])方法。我建议您使用本机js数组的属性:

var styles = {
    node: {stroke: "white", "stroke-width": 1.5, r: 8},
    link: {stroke: "#999", "stroke-width": 0.6}
};
...
var node = svg.selectAll('.node')
    ...
    .attr(styles.node)
    ...

顺便说一句,在SVG中fill是属性。

DEMO:http://jsfiddle.net/3gw8vxa3/