将力导向图与圆环图D3JS组合

时间:2014-11-26 15:21:15

标签: d3.js graph charts

我想将两个图表组合在一起。 第一个力量有向图与甜甜圈图表。 clik之后的每个节点有效导向图将通过圆环图显示上下文菜单。我准备了两张图表,但我不知道如何将它们组合起来。

强制指令代码:

//图2 - 上下文菜单圆环图

var dataset = [
    {
        size: 2,
        label: "Item 1"
    },
    {
        size: 1,
        label: "Item 2"
    },    
    {
        size: 65,
        label: "Item 3"
    },    
    {
        size: 45,
        label: "Item 4"
    },    
    {
        size: 50,
        label: "Item 5"
    }
];

var width = 460,
    height = 300,
    radius = Math.min(width, height) / 2;


var color = d3.scale.category20();
var pie = d3.layout.pie()
    .sort(null)
    .value(function(d) { return Object.keys(dataset).length; }); // zde je nutné zadat celkovou populaci - početz prvků v 

// Menu

// Arc setting
var arc = d3.svg.arc()
    .innerRadius(radius - 100)
    .outerRadius(radius - 50);

// Graph space
var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height)
    .append("g")
    .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

// Prepare graph and load data
var g = svg.selectAll(".arc")
    .data(pie(dataset))
    .enter().append("g")
    .attr("class", "arc");

// Add colors
var path =  g.append("path")
    .attr("d", arc)
    .attr("fill", function (d) { return color(d.data.size);})

// Add labels
var asdfd =  g.append("text")
    .attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; })
    .attr("dy", ".35em")
    .style("text-anchor", "middle")
    .text(function(d) { return d.data.label; });

var oldColor;

// Add hover action
  path.on("mouseenter", function(d,i) {
              console.log("mousein"+ d.data.label)
              
              var thisPath = d3.select(this);
              
                  oldColor = thisPath.attr("fill"); // save old color
      
                  thisPath
                  .attr("fill", "blue")
                  .attr("cursor", "pointer")
                  .attr("class", "on");
     
      
  })
 
  path.on("mouseout", function(d) {
                 d3.select(this)
                 .attr("fill", oldColor)
                 .attr("class", "off");
   });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

组合的结果应该如下图所示:

enter image description here

感谢您的想法!

编辑:我可能会解决这个问题,但是有一些小的性能问题,任何人都可以帮我完成这个,图表是滞后的,我的节点之间的箭头有问题。向你求助!

var json = {
    "nodes": [{
        "id": -1146034065,
            "name": "/",
            "group": 0
    }, {
        "id": -990073683,
            "name": "/blog/",
            "group": 0
    }, {
        "id": -1724280020,
            "name": "/menu/",
            "group": 0
    }, {
        "id": 1176095248,
            "name": "/napojovy-listek/",
            "group": 0
    }, {
        "id": -2085082741,
            "name": "/fotogalerie/",
            "group": 0
    }, {
        "id": 883542796,
            "name": "/rezervace/",
            "group": 0
    }, {
        "id": 369131020,
            "name": "/kontakt/",
            "group": 0
    }, {
        "id": -1276353015,
            "name": "/en/",
            "group": 0
    }, {
        "id": -1557747058,
            "name": "/o-nas/",
            "group": 404
    }, {
        "id": 890427810,
            "name": "/en/about-us/",
            "group": 0
    }, {
        "id": -978700858,
            "name": "/en/menu-2/",
            "group": 0
    }, {
        "id": 1436673749,
            "name": "/en/napojovy-listek/",
            "group": 0
    }, {
        "id": -489730654,
            "name": "/en/photograph/",
            "group": 0
    }, {
        "id": -1461616187,
            "name": "/en/reservation/",
            "group": 0
    }, {
        "id": 1520755615,
            "name": "/en/contact/",
            "group": 0
    }, {
        "id": 37644686,
            "name": "/en//kontakt/",
            "group": 0
    }, {
        "id": 1131720527,
            "name": "/en//o-nas/",
            "group": 404
    }],
        "links": [{
        "source": -990073683,
            "target": -1146034065,
            "value": 1
    }, {
        "source": -1724280020,
            "target": -1146034065,
            "value": 1
    }, {
        "source": 1176095248,
            "target": -1146034065,
            "value": 1
    }, {
        "source": -2085082741,
            "target": -1146034065,
            "value": 1
    }, {
        "source": 883542796,
            "target": -1146034065,
            "value": 1
    }, {
        "source": 369131020,
            "target": -1146034065,
            "value": 1
    }, {
        "source": -1276353015,
            "target": -1146034065,
            "value": 1
    }, {
        "source": -1557747058,
            "target": -1146034065,
            "value": 1
    }, {
        "source": 890427810,
            "target": -990073683,
            "value": 1
    }, {
        "source": -978700858,
            "target": -1724280020,
            "value": 1
    }, {
        "source": 1436673749,
            "target": 1176095248,
            "value": 1
    }, {
        "source": -489730654,
            "target": -2085082741,
            "value": 1
    }, {
        "source": -1461616187,
            "target": 883542796,
            "value": 1
    }, {
        "source": 1520755615,
            "target": 369131020,
            "value": 1
    }, {
        "source": 37644686,
            "target": -1276353015,
            "value": 1
    }, {
        "source": 1131720527,
            "target": -1276353015,
            "value": 1
    }, {
        "source": -1146034065,
            "target": -1146034065,
            "count": 1,
            "value": 1
    }, {
        "source": -1146034065,
            "target": -990073683,
            "count": 1,
            "value": 1
    }, {
        "source": -1146034065,
            "target": -1724280020,
            "count": 3,
            "value": 1
    }, {
        "source": -1146034065,
            "target": 1176095248,
            "count": 3,
            "value": 1
    }, {
        "source": -1146034065,
            "target": -2085082741,
            "count": 3,
            "value": 1
    }, {
        "source": -1146034065,
            "target": 883542796,
            "count": 3,
            "value": 1
    }, {
        "source": -1146034065,
            "target": 369131020,
            "count": 3,
            "value": 1
    }, {
        "source": -1146034065,
            "target": -1276353015,
            "count": 1,
            "value": 1
    }, {
        "source": -1146034065,
            "target": -1557747058,
            "count": 2,
            "value": 1
    }, {
        "source": -990073683,
            "target": -1146034065,
            "count": 1,
            "value": 1
    }, {
        "source": -990073683,
            "target": -990073683,
            "count": 1,
            "value": 1
    }, {
        "source": -990073683,
            "target": -1724280020,
            "count": 1,
            "value": 1
    }, {
        "source": -990073683,
            "target": 1176095248,
            "count": 1,
            "value": 1
    }, {
        "source": -990073683,
            "target": -2085082741,
            "count": 1,
            "value": 1
    }, {
        "source": -990073683,
            "target": 883542796,
            "count": 1,
            "value": 1
    }, {
        "source": -990073683,
            "target": 369131020,
            "count": 1,
            "value": 1
    }, {
        "source": -990073683,
            "target": 890427810,
            "count": 1,
            "value": 1
    }, {
        "source": -1724280020,
            "target": -1146034065,
            "count": 1,
            "value": 1
    }, {
        "source": -1724280020,
            "target": -990073683,
            "count": 1,
            "value": 1
    }, {
        "source": -1724280020,
            "target": -1724280020,
            "count": 1,
            "value": 1
    }, {
        "source": -1724280020,
            "target": 1176095248,
            "count": 1,
            "value": 1
    }, {
        "source": -1724280020,
            "target": -2085082741,
            "count": 1,
            "value": 1
    }, {
        "source": -1724280020,
            "target": 883542796,
            "count": 1,
            "value": 1
    }, {
        "source": -1724280020,
            "target": 369131020,
            "count": 1,
            "value": 1
    }, {
        "source": -1724280020,
            "target": -978700858,
            "count": 1,
            "value": 1
    }, {
        "source": 1176095248,
            "target": -1146034065,
            "count": 1,
            "value": 1
    }, {
        "source": 1176095248,
            "target": -990073683,
            "count": 1,
            "value": 1
    }, {
        "source": 1176095248,
            "target": -1724280020,
            "count": 1,
            "value": 1
    }, {
        "source": 1176095248,
            "target": 1176095248,
            "count": 1,
            "value": 1
    }, {
        "source": 1176095248,
            "target": -2085082741,
            "count": 1,
            "value": 1
    }, {
        "source": 1176095248,
            "target": 883542796,
            "count": 1,
            "value": 1
    }, {
        "source": 1176095248,
            "target": 369131020,
            "count": 1,
            "value": 1
    }, {
        "source": 1176095248,
            "target": 1436673749,
            "count": 1,
            "value": 1
    }, {
        "source": -2085082741,
            "target": -1146034065,
            "count": 1,
            "value": 1
    }, {
        "source": -2085082741,
            "target": -990073683,
            "count": 1,
            "value": 1
    }, {
        "source": -2085082741,
            "target": -1724280020,
            "count": 1,
            "value": 1
    }, {
        "source": -2085082741,
            "target": 1176095248,
            "count": 1,
            "value": 1
    }, {
        "source": -2085082741,
            "target": -2085082741,
            "count": 1,
            "value": 1
    }, {
        "source": -2085082741,
            "target": 883542796,
            "count": 1,
            "value": 1
    }, {
        "source": -2085082741,
            "target": 369131020,
            "count": 1,
            "value": 1
    }, {
        "source": -2085082741,
            "target": -489730654,
            "count": 1,
            "value": 1
    }, {
        "source": 883542796,
            "target": -1146034065,
            "count": 1,
            "value": 1
    }, {
        "source": 883542796,
            "target": -990073683,
            "count": 1,
            "value": 1
    }, {
        "source": 883542796,
            "target": -1724280020,
            "count": 1,
            "value": 1
    }, {
        "source": 883542796,
            "target": 1176095248,
            "count": 1,
            "value": 1
    }, {
        "source": 883542796,
            "target": -2085082741,
            "count": 1,
            "value": 1
    }, {
        "source": 883542796,
            "target": 883542796,
            "count": 1,
            "value": 1
    }, {
        "source": 883542796,
            "target": 369131020,
            "count": 1,
            "value": 1
    }, {
        "source": 883542796,
            "target": -1461616187,
            "count": 1,
            "value": 1
    }, {
        "source": 369131020,
            "target": -1146034065,
            "count": 1,
            "value": 1
    }, {
        "source": 369131020,
            "target": -990073683,
            "count": 1,
            "value": 1
    }, {
        "source": 369131020,
            "target": -1724280020,
            "count": 1,
            "value": 1
    }, {
        "source": 369131020,
            "target": 1176095248,
            "count": 1,
            "value": 1
    }, {
        "source": 369131020,
            "target": -2085082741,
            "count": 1,
            "value": 1
    }

    ]
}


var width = 960,
    height = 700

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);
    // Per-type markers, as they don't inherit styles.
    svg.append("defs").selectAll("marker")
    .data(["a"])
    .enter().append("marker")
    .attr("id", function(d) { return d; })
    .attr("viewBox", "0 -5 10 10")
    .attr("refX", 15)
    .attr("refY", -1.5)
    .attr("markerWidth", 6)
    .attr("markerHeight", 6)
    .attr("orient", "auto")
    .append("path")
    .attr("d", "M0,-5L10,0L0,5");

var edges = [];
var fill = d3.scale.category10();

json.links.forEach(function (e) {
    // Get the source and target nodes
    var sourceNode = json.nodes.filter(function (n) {
        return n.id === e.source;
    })[0],
        targetNode = json.nodes.filter(function (n) {
            return n.id === e.target;
        })[0],
        count = e.count;

    // Add the edge to the array
    edges.push({
        source: sourceNode,
        target: targetNode,
        count: count,
        type: "a"
    });
});

var force = d3.layout.force()
    .gravity(0.01)
    .distance(500)
    .charge(-300)
    .linkDistance(300)
    .size([width, height])
    .nodes(json.nodes)
    .links(edges)
    .start();



var link =  svg.append("g").selectAll("link")
    .data(edges)
    .enter().append("path")
    .attr("class", "link")
    //.attr("marker-end", function(d) { return "url(#" + d.targetNode + ")"; })
    .style("stroke-width", function (d) {
    return Math.sqrt(d.count * 1, 5);
});



// Přidáme k uzlu kontextové menu a zvýrazníme sousedy
var node = svg.selectAll("node")
    .data(json.nodes)
    .enter().append("g")
    .attr("class", "node")
    .style("fill", function (d) {
    return fill(d.group);
})
    .call(force.drag).on("mouseover", fade(.1)).on("mouseout", fade(1))
    .on("click", function (d, i) {
        svg.selectAll(".node").style("fill", function (d) { return fill(d.group);});
        d3.select(".menu").remove();
        
    var thisNode = d3.select(this);
    thisNode.attr('r', 25).style("fill", "lightcoral");

    var menuDataSet = [{
        size: 2,
        label: "Item 1"
    }, {
        size: 1,
        label: "Item 2"
    }, {
        size: 65,
        label: "Item 3"
    }, {
        size: 45,
        label: "Item 4"
    }, {
        size: 50,
        label: "Item 5"
    }];

    // Barvy menu
    var color = d3.scale.category20();
    var pie = d3.layout.pie()
        .sort(null)
        .value(function (d) {
        return Object.keys(menuDataSet).length;
    }); // zde je nutné zadat celkovou populaci - početz prvků v 

    // Menu
    var widthMenu = 180,
        heightMenu = 180,
        radiusMenu = Math.min(widthMenu, heightMenu) / 2;

    // Arc setting
    var arc = d3.svg.arc()
        .innerRadius(radiusMenu - 70)
        .outerRadius(radiusMenu - 25);

    // Graph space
    var svgMenu = thisNode.append("svg")
        .attr("width", widthMenu)
        .attr("height", heightMenu)
        .attr("class","menu")
        .attr("x", -90)
        .attr("y", -90)
        .append("g")
        .attr("transform", "translate(" + widthMenu / 2 + "," + heightMenu / 2 + ")");


    // Prepare graph and load data
    var g = svgMenu.selectAll(".arc")
        .data(pie(menuDataSet))
        .enter().append("g")
        .attr("class", "arc");

    // Add colors
    var path = g.append("path")
        .attr("d", arc)
        .attr("fill", function (d) {
        return color(d.data.size);
    })

    // Add labels
    var asdfd = g.append("text")
        .attr("transform", function (d) {
        return "translate(" + arc.centroid(d) + ")";
    })
        .attr("dy", ".35em")
        .style("text-anchor", "middle")
        .text(function (d) {
        return d.data.label;
    });

    // Add hover action
    path.on("mouseenter", function (d, i) {

        var thisPath = d3.select(this);
        thisPath.attr("fill", "blue")
            .attr("cursor", "pointer")
            .attr("class", "on");
    })

    path.on("mouseout", function (d) {
        d3.select(this)
            .attr("fill", function (d) {
            return color(d.data.size);
        })
            .attr("class", "off");
    });

});





/*
  node.append("image")
      .attr("xlink:href", "https://github.com/favicon.ico")
      .attr("x", -8)
      .attr("y", -8)
      .attr("width", 16)
      .attr("height", 16);
*/
node.append("circle").attr("r", 10);

node.append("text")
    .attr("dx", 12)
    .attr("dy", ".35em")
    .text(function (d) {
    return d.name
});

// přidá popisky k hranám
var labels = svg.selectAll('text')
    .data(edges)
    .enter().append('text')
    .attr("x", function (d) {
    return (d.source.y + d.target.y) / 2;
})
    .attr("y", function (d) {
    return (d.source.x + d.target.x) / 2;
})
    .attr("text-anchor", "middle")
    .text(function (d) {
    return d.count;
});


force.on("tick", function () {

    link.attr("d", function linkArc(d) {
  var dx = d.target.x - d.source.x,
      dy = d.target.y - d.source.y,
      dr = Math.sqrt(dx * dx + dy * dy);
  return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y;
}
);
    
    node.attr("transform", function (d) {
        return "translate(" + d.x + "," + d.y + ")";
    });

    labels.attr("x", function (d) {
        return (d.source.x + d.target.x + 10) / 2;
    })
        .attr("y", function (d) {
        return (d.source.y + d.target.y + 10) / 2;
    })


});



function transform(d) {
  return "translate(" + d.x + "," + d.y + ")";
}

var linkedByIndex = {};
edges.forEach(function (d) {
    linkedByIndex[d.source.index + "," + d.target.index] = 1;
});

function isConnected(a, b) {
    return linkedByIndex[a.index + "," + b.index] || linkedByIndex[b.index + "," + a.index] || a.index == b.index;
}


function fade(opacity) {
    return function (d) {

        // přidá popisky k hranám
        var labels = svg.selectAll('text')
            .data(edges)
            .enter().append('text')
            .attr("x", function (o) {
            return (o.source.y + o.target.y) / 2;
        })
            .attr("y", function (o) {
            return (o.source.x + o.target.x) / 2;
        })
            .attr("text-anchor", "middle")
            .text(function (o) {
            return o.count;
        });

        node.style("stroke-opacity", function (o) {
            thisOpacity = isConnected(d, o) ? 1 : opacity;
            this.setAttribute('fill-opacity', thisOpacity);
            return thisOpacity;
        });

        link.style("stroke-opacity", function (o) {
            return o.source === d || o.target === d ? 1 : opacity;
        });
    };
}
body {
    font-family:"Helvetica Neue", Helvetica, Arial, sans-serif;
    margin: auto;
    position: relative;
    width: 960px;
}
.link {
  fill: none;
  stroke: #666;
  stroke-width: 1.5px;
  stroke-dasharray: 0,4 1;
}

text {
    font: 10px sans-serif;
}
form {
    position: absolute;
    right: 10px;
    top: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

0 个答案:

没有答案