如何强制y位置的一个分支在d3 sankey插件? [英] How to force y position of one branch in d3 sankey plugin?

查看:409
本文介绍了如何强制y位置的一个分支在d3 sankey插件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想强制sankey图的一个分支在上面。

I would like to force one branch of sankey diagram to be on top.

而不是像这样的图:

Instead of diagram like this:

想生成图表,其中节点1,2,7,15 ,10和14总是位于顶部:

would like to generate diagram where nodes 1, 2, 7, 15, 10 and 14 are always on top:

链接到当前代码: http://jsfiddle.net/w5jfp9t0/1/

var margin = {top: 1, right: 1, bottom: 6, left: 1};
var width = 1052 - margin.left - margin.right;
var height = 500 - margin.top - margin.bottom;

var formatNumber = d3.format(",.0f"),
    format = function(d) { return formatNumber(d); },
    color = d3.scale.category20();

var svg = d3.select("#chart_sankey").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

var sankey = d3.sankey()
                         .nodeWidth(35)
                         .nodePadding(10)
                         .size([width, height]);

var path = sankey.link();

raw = '{"nodes":[{"name":"Node 1"},{"name":"Node 2"},{"name":"Node 3"},{"name":"Node 4"},{"name":"Node 5"},{"name":"Node 6"},{"name":"Node 7"},{"name":"Node 8"},{"name":"Node 9"},{"name":"Node 10"},{"name":"Node 11"},{"name":"Node 12"},{"name":"Node 13"},{"name":"Node 14"},{"name":"Node 15"}],"links":[{"source":9,"target":13,"value":25},{"source":14,"target":9,"value":37},{"source":14,"target":11,"value":16},{"source":14,"target":12,"value":8},{"source":14,"target":10,"value":68},{"source":6,"target":14,"value":154},{"source":6,"target":8,"value":40},{"source":1,"target":6,"value":345},{"source":1,"target":7,"value":66},{"source":1,"target":3,"value":17},{"source":1,"target":4,"value":25},{"source":1,"target":5,"value":117},{"source":0,"target":1,"value":692},{"source":0,"target":2,"value":19}]}';
data = JSON.parse(raw);

sankey.nodes(data.nodes)
    .links(data.links)
    .layout(32);

var link = svg.append("g")
            .selectAll(".link")
            .data(data.links)
            .enter().append("path")
            .attr("class", "link")
            .attr("d", path)
            .style("stroke-width", function(d) { return Math.max(1, d.dy); })
            .sort(function(a, b) { return b.dy - a.dy; });

var nodes = data.nodes;

var node = svg.append("g").selectAll(".node")
    .data(nodes)
  .enter().append("g")
    .attr("class", "node")
    .attr("transform", function(d) {
        return "translate(" + d.x + "," + d.y + ")"; })
  .call(d3.behavior.drag()
    .origin(function(d) { return d; })
    .on("dragstart", function() { this.parentNode.appendChild(this); })
    .on("drag", dragmove));

sankey.relayout();

node.filter(function(d) { return d.value != 0; }) // append text only if node value is not zero
    .append("rect")
    .attr("height", function(d) { return d.dy; })
    .attr("width", sankey.nodeWidth())
    .style("fill", function(d) { return d.color = color(d.name.replace(/ .*/, "")); })
    .style("stroke", function(d) { return d3.rgb(d.color).darker(2); })
  .append("title")
    .text(function(d) { return d.name + "\n" + format(d.value); });

node.filter(function(d) { return d.value != 0; }) // append text only if node value is not zero
    .append("text")
    .attr("x", -6)
    .attr("y", function(d) { return d.dy / 2; })
    .attr("dy", ".35em")
    .attr("text-anchor", "end")
    .attr("transform", null)
    .text(function(d) { return d.name; })
    .filter(function(d) { return d.x == 0; }) // at first column append text after column
    .attr("x", 6 + sankey.nodeWidth())
    .attr("text-anchor", "start");

function dragmove(d) {
  d3.select(this).attr("transform", "translate(" + d.x + "," + (d.y = Math.max(0, Math.min(height - d.dy, d3.event.y))) +  ")");
  sankey.relayout();
  link.attr("d", path);
}

我需要改变什么才能完成?

What do I need to change to accomplish this?

推荐答案

注意
说实话,我从来没有使用过这个插件。我没有看到一个选项来直接获得所需的行为 - 因此我查看sankey.js的来源进行调整。下面我将说明我会如何修改 - 您可能需要更彻底地:)

Note To be honest, I never used that plugin. I don't see an option to get the desired behaviour directly - thus I looked at the source of sankey.js to make the adjustments. Below I show how I'd modify - you might want to do it more thoroughly :)

创意

查看sankey.js的代码,您会看到使用 center 函数放置节点(y方向):

Looking at the code of sankey.js, you see that the nodes are placed (y-direction) using the center function:

function center(node) {
  return node.y + node.dy / 2;
}

由于我没有看到要更改此行为的参数,它到:

As I don't see a parameter to change that behaviour, you can change it to:

function center(node) {
  return 0;
}

如果您还还原排序顺序:

If you then also revert the sorting order:

function ascendingDepth(a, b) {
  return b.y - a.y;
}

您会得到以下图片:

这篇关于如何强制y位置的一个分支在d3 sankey插件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆