Javascript D3 JS Sankey图中的甜甜圈图

Javascript D3 JS Sankey图中的甜甜圈图,javascript,svg,d3.js,sankey-diagram,Javascript,Svg,D3.js,Sankey Diagram,我有一个D3JS Sankey图,有很多数据。数据的末尾总是公司。公司节点是一个简单的圆。但围绕这个圆圈,我想要一个甜甜圈图表,有两个值。这些值在公司节点中以numsms和nummid的形式存在。你也可以在下图中看到这一点 图表示例: 所以我想在公司周围画一张油炸圈饼图。但我似乎无法实现这一点,我只找到了甜甜圈图表作为自己的svg的示例 我的圆圈代码: svg.selectAll(".node.circle") .append("circle") .attr("

我有一个D3JS Sankey图,有很多数据。数据的末尾总是公司。公司节点是一个简单的圆。但围绕这个圆圈,我想要一个甜甜圈图表,有两个值。这些值在公司节点中以numsms和nummid的形式存在。你也可以在下图中看到这一点

图表示例:

所以我想在公司周围画一张油炸圈饼图。但我似乎无法实现这一点,我只找到了甜甜圈图表作为自己的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循环中,我将类名“node circle”替换为“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
        }
    });

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

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


希望这有帮助。

终于回到这个问题上来了

下面是一个包含圆环图的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); });

Sankey+Piechart在此处的实现:
(尽管饼图位于静态div中,所以每次调用时都将其移动到节点上方)

请用数据示例更新您的问题。如果不能够重新创建一个完整的示例,很难回答这个问题……代码太大,服务器上有嵌套项。因此,我不能在不修改太多代码的情况下创建一个jsfidle。对于这个问题,还有很多不必要的代码。如果你指的是JSON字符串中的数据,那么我有一点:我把它放在JSFIDLE中,因为它是一个相当长的字符串。谢谢,它已经有帮助了。如果有效的话,我会随时通知你。如果我有其他的建议/方法。
//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>");
$('.inlinesparkline').sparkline(); 
// 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); });