简体   繁体   English

在d3.js强制节点画布布局中更改节点组的颜色

[英]Change color of node groups in a d3.js force node canvas layout

I have a forced graph: 我有一个强制图:

var canvas = document.querySelector("canvas"),
        context = canvas.getContext("2d"),
        width = canvas.width,
        height = canvas.height,
        min = 5;

var simulation = d3.forceSimulation()
        .force("link", d3.forceLink()
                .id(function(d) { return d.id; })
                .iterations(2)
                .distance(function(d) {
                    return Math.sqrt((600 - d.value)) / 10;
                })
                .strength(8)
        )
        .force("charge", d3.forceManyBody()
                .strength(-300)
                .theta(0.9)
                .distanceMax(400)
        )
        .force("center", d3.forceCenter(width / 2, height / 2)
        )
        .force("collision", d3.forceCollide(1))
        ;


d3.json("/contigderivatives/data/", function(error, graph) {
    if (error) throw error;

    simulation
            .nodes(graph.nodes)
            .on("tick", ticked);

    simulation.force("link")
            .links(graph.links);

    d3.select(canvas)
            .call(d3.drag()
                    .container(canvas)
                    .subject(dragsubject)
                    .on("start", dragstarted)
                    .on("drag", dragged)
                    .on("end", dragended));

    function ticked() {
        context.clearRect(0, 0, width, height);

        context.beginPath();
        graph.links.forEach(drawLink);
        context.strokeStyle = "#aaa";
        context.stroke();

        context.beginPath();
        graph.nodes.forEach(drawNode);
        context.strokeStyle = "#fff";
        context.fillStyle = 'steelblue';
        context.stroke();
        context.fill();
    }
    function dragsubject() {
        return simulation.find(d3.event.x, d3.event.y);
    }
});

function dragstarted() {
    if (!d3.event.active) simulation.alphaTarget(0.1).restart();
    d3.event.subject.fx = d3.event.subject.x;
    d3.event.subject.fy = d3.event.subject.y;
}

function dragged() {
    d3.event.subject.fx = d3.event.x;
    d3.event.subject.fy = d3.event.y;
}

function dragended() {
    if (!d3.event.active) simulation.alphaTarget(0);
    d3.event.subject.fx = null;
    d3.event.subject.fy = null;
}

function drawLink(d) {
    context.moveTo(d.source.x, d.source.y);
    context.lineTo(d.target.x, d.target.y);
}

function drawNode(d){
    d.x = Math.max(min, Math.min(width - min, d.x));
    d.y = Math.max(min, Math.min(height - min, d.y));
    context.moveTo(d.x + 3, d.y);
    context.arc(d.x, d.y, 3, 0, 2 * Math.PI);
}

I'm trying to change the color of the nodes based on a grouping that is specified in the JSON that's an integer, where 0 = red, 1 = blue. 我试图根据JSON中指定的分组更改节点的颜色,该分组是整数,其中0 =红色,1 =蓝色。 There are plenty of examples of how to change the styles of a node when using SVGs, but there's not a lot when using a canvas. 有关使用SVG时如何更改节点样式的示例,有很多,但是使用画布时却没有很多。 Changing the line context.fillStyle = 'steelblue'; 更改线context.fillStyle = 'steelblue'; changes the fill color for all of the nodes.. How does one change the style and attributes of individual nodes when using a canvas? 更改所有节点的填充颜色。使用画布时,如何更改单个节点的样式和属性?

I made a color scale 我做了一个色标

 var color = d3.scaleOrdinal(d3.schemeCategory10);

Then on each node draw I color on the basis of node data properties: 然后在每个节点上根据节点数据属性绘制I颜色:

  function drawNode(d) {
    context.beginPath();//for each node do begin path as context fill style and stroke are different.
    context.moveTo(d.x + 3, d.y);
    context.arc(d.x, d.y, 3, 0, 2 * Math.PI);
    context.fillStyle = color(d.group);//coloring on the basis of the group
    context.strokeStyle = color(d.group);
    context.fill();
    context.stroke();
  }

Based on the bl.ock diagram you referred in the comment I have made a small working example here 基于您在评论中引用的bl.ock图,我在这里做了一个小的工作示例

Hope this fixes your problem. 希望这可以解决您的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM