D3 JS Sankey图中的圆环图

时间:2015-04-16 11:52:42

标签: javascript svg d3.js sankey-diagram

我有一个D3 Js Sankey图,包含大量数据。在数据的最后总是公司。公司节点是一个简单的圈子。但是在那个圈子里我想要一个带有2个值的圆环图。值在公司节点内作为numsms和nummid。你也可以在下面的图片中看到。

图表示例: enter image description here

所以我想在公司周围圈出一个圆环图。但我似乎无法将其发挥作用,我只发现了甜甜圈图表的例子作为自己的svg。

我的圈子代码:

svg.selectAll(".node.circle")
        .append("circle")
        .attr("r", function(d) {
            if(d.node.indexOf("company-") > -1) {
                return company_circle_size(d);
            } else {
                return page_circle_size(d);
            }
        })
        .attr("cy", function(d) { return d.dy/2;})
        .attr("cx", function(d) {
            var cx = sankey.nodeWidth() - 30;
            if(d.node.indexOf("company-") > -1) {
                cx = cx + 15;
            }
            return cx;
        })
        .style("fill", function (d) {
            if(d.node.indexOf("company-") > -1) {
                if(d.name.indexOf("No data") > -1) {
                    return "grey";
                }
                var color = '';
                switch(d.status) {
                    case 'Approved':
                        color = 'green';
                        break;
                    case 'inactive ':
                        color = 'red';
                        break;
                    case 'initial':
                        color = 'yellow';
                        break;
                    case 'review':
                        color = 'blue';
                        break;
                    default:
                        color = 'grey';
                        break;
                }
                return color;
            }
            return "grey";
            //return d.color = color(d.name.replace(/ .*/, ""));
        })
        .style("fill-opacity", ".9")
        .style("shape-rendering", "auto")
        .style("stroke", function (d) {
            return d3.rgb(d.color).darker(2);
        })
        .append("title")
        .text(function (d) {
            if(d.node.indexOf("company-") > -1) {
                if(d.cpId != null) {
                    return d.name + "\n cpId: " + d.cpId;
                }
                return d.name;
            }
            return d.name + "\n" + format(d.value);
        });

在for循环中,我替换了类名"节点圈"到"节点公司"。

$(selector).attr("class", "node company")

我尝试了一些事情,我认为代码需要放在这里。

svg.selectAll('.company').each(function(companyNode) {
        var values = [[companyNode.numsms, companyNode.nummid]];
        var total = companyNode.numsms + companyNode.nummid;

        if(total > 0) {
            // create donut chart
        }
    });

2 个答案:

答案 0 :(得分:1)

您可以使用foriegnObject将div附加到节点。在该div中将您的值传递给内联jquery迷你图表(线,饼等)。设置div的透明度,使其不会阻止图表。将值添加到原始sankey数据数组(即source,target,value,numsms,numid),然后使用d.numsms在append中调用它们。

//sparkline plugin and setup...  http://omnipotent.net/jquery.sparkline/#s-docs
//something like the following, look at the fiddle for more info

node.append("foreignObject")
.attr("width", sankey.nodeWidth()*2)
.attr("height", function(d) { return d.dy/2 })
.attr("transform", function(d) { return "translate(" + (d.x+20) + "," + (d.y+10) + ")"; })
.append("xhtml:body")
.style("font", "14px 'Helvetica Neue'")
.html("<div>Inline Sparkline: <span class='inlinesparkline'>1,4,4,7,5,9,10</span></div>");

将div添加到每个节点后,调用该插件以激活内联图表。

$('.inlinesparkline').sparkline(); 

看看我的小提琴。它不是一个sankey,但它确实向您展示了如何实现foriegnObject。

d3.js diagram with inline charts!

希望这有帮助。

答案 1 :(得分:1)

最后回到了这个问题。

这里有一个quick example,其中包含一个包含圆环图的sankey图表。我不适合你的数据,这是一个通用的例子。

// if no pie data, just use rects as normal
node.filter(function(d){
    return !d.pieData;
  })
  .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);
  });

// set up donut chart stuff
var pColor = d3.scale.ordinal()
    .range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);

var arc = d3.svg.arc()
    .outerRadius(50)
    .innerRadius(20);

var pie = d3.layout.pie()
    .sort(null)
    .value(function(d) { return d.value; });

// if we have pie data, draw the donut chart
var g = node.filter(function(d){
    return d.pieData;
  })
  .append("g")
  .attr('transform', function(d,i){
     return 'translate('+d.dx/2+','+d.dy/2+')'; // proper position
  })
  .attr("class","donut")
  .selectAll(".arc")
  .data(function(d){
    return pie(d.pieData); // nested selection to assign data
  })
  .enter().append("g")
  .attr("class", "arc");

g.append("path")
  .attr("d", arc)
  .style("fill", function(d,i) { return color(i); });