簡體   English   中英

使用d3.js拼出多層餅圖的效果

[英]Piece out effect for Multilayer pie Chart using d3.js

我有一個具有不同內半徑的多層餅圖,如下所示:

在此處輸入圖片說明

上面的餅圖的代碼可以在這里找到:

var width = 960,
            height = 500,
            radius = Math.min(width, height) / 2;

        var color = d3.scale.ordinal()
            .range(["cyan", "green", "blue", "brown", "violet", "orange", "purple"]);
    var arcMajor = d3.svg.arc()
        .outerRadius(function (d) {
            return radius - 20;
        })
        .innerRadius(0);
    //this for making the minor arc
    var arcMinor = d3.svg.arc()
        .outerRadius(function (d) {
            // scale for calculating the radius range([20, radius - 40])
            var s = scale((d.data.major - d.data.minor));
            if (s > radius - 20) {
                return radius - 20;
            }

            return scale(d.data.major - d.data.minor);
        })
        .innerRadius(0);
    var labelr = 260;
    var pie = d3.layout.pie()
        .sort(null)
        .value(function (d) {
            return d.major;
        });


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

    data = [{
        major: 500,
        minor: 250,
        grp: 1
    }, {
        major: 100,
        minor: 80,
        grp: 2
    }, {
        major: 100,
        minor: 50,
        grp: 3
    }, {
        major: 100,
        minor: 60,
        grp: 4
    }, {
        major: 100,
        minor: 10,
        grp: 5
    }];
    var scale = d3.scale.linear()
    .range([d3.min(data, function (d) {
        return d.minor;
    }), radius - 100 - d3.max(data, function (d) {
        return d.minor / d.major;
    })])
    //setting the scale domain
    .domain([d3.min(data, function (d) {
        return d.minor;
    }), d3.max(data, function (d) {
        return d.minor;
    })]);

    var g = svg.selectAll(".arc")
        .data(pie(data))
        .enter().append("g")
        .attr("class", "arc");
    g.append("svg:text")
.attr("transform", function (d) {
    var c = arcMajor.centroid(d),
        x = c[0],
        y = c[1],
        // pythagorean theorem for hypotenuse
        h = Math.sqrt(x * x + y * y);
    return "translate(" + (x / h * labelr) + ',' +
       (y / h * labelr) + ")";
})
.attr("dy", ".35em")
.attr("text-anchor", function (d) {
    // are we past the center?
    return (d.endAngle + d.startAngle) / 2 > Math.PI ?
        "end" : "start";
})
.text(function (d, i) { return d.value.toFixed(2); });
    //this makes the major arc
    g.append("path")
        .attr("d", function (d) {
            return arcMajor(d);
        })
        .style("fill", function (d) {
            return d3.rgb(color(d.data.grp));
        });

    //this makes the minor arcs
    g.append("path")
        .attr("d", function (d) {
            return arcMinor(d);
        })
        .style("fill", function (d) {
            return d3.rgb(color(d.data.grp)).darker(2);//for making the inner path darker
        });

http://jsfiddle.net/6e8aue0h/10/

我想為該餅圖添加分段功能。 像這樣:

在此處輸入圖片說明

我嘗試使用d3-pie插件,但是沒有用。

當您將鼠標懸停在特定部分上時,它應該顯示出來,如下圖所示。 https://github.com/dansdom/plugins-d3-pie

在這種特殊情況下,我該如何實施?

非常感謝你

在這里,我以類似的方式為主要餡餅添加了分段效果,您可以為內部餡餅添加效果。 我在變量上添加了弧

var arcOver = d3.svg.arc()
        .outerRadius(radius + 9);

以及主要弧線的mouseenter和mouseout功能。

.on("mouseenter", function(d) {

            d3.select(this)
               .attr("stroke","white")
               .transition()
               .duration(1000)
               .attr("d", arcOver)             
               .attr("stroke-width",6);
        })
        .on("mouseleave", function(d) {
            d3.select(this).transition()            
               .attr("d", arcMajor)
               .attr("stroke","none");
        })

這是示例。

  var width = 960, height = 500, radius = Math.min(width, height) / 2; var color = d3.scale.ordinal() .range(["cyan", "green", "blue", "brown", "violet", "orange", "purple"]); var arcMajor = d3.svg.arc() .outerRadius(function (d) { return radius - 20; }) .innerRadius(0); var arcOver = d3.svg.arc() .outerRadius(radius + 9); //this for making the minor arc var arcMinor = d3.svg.arc() .outerRadius(function (d) { // scale for calculating the radius range([20, radius - 40]) var s = scale((d.data.major - d.data.minor)); if (s > radius - 20) { return radius - 20; } return scale(d.data.major - d.data.minor); }) .innerRadius(0); var arcOverMin = d3.svg.arc() .outerRadius(radius - 90 ); // Define the div for the tooltip var div = d3.select("body").append("div") .attr("class", "tooltip") .style("opacity", 0); var labelr = 260; var pie = d3.layout.pie() .sort(null) .value(function (d) { return d.major; }); var svg = d3.select("body").append("svg") .attr("width", width) .attr("height", height) .append("g") .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")"); data = [{ major: 500, minor: 250, grp: 1 }, { major: 100, minor: 80, grp: 2 }, { major: 100, minor: 50, grp: 3 }, { major: 100, minor: 60, grp: 4 }, { major: 100, minor: 10, grp: 5 }]; var scale = d3.scale.linear() .range([d3.min(data, function (d) { return d.minor; }), radius - 100 - d3.max(data, function (d) { return d.minor / d.major; })]) //setting the scale domain .domain([d3.min(data, function (d) { return d.minor; }), d3.max(data, function (d) { return d.minor; })]); var g = svg.selectAll(".arc") .data(pie(data)) .enter().append("g") .attr("class", "arc"); g.append("svg:text") .attr("transform", function (d) { var c = arcMajor.centroid(d), x = c[0], y = c[1], // pythagorean theorem for hypotenuse h = Math.sqrt(x * x + y * y); return "translate(" + (x / h * labelr) + ',' + (y / h * labelr) + ")"; }) .attr("dy", ".35em") .attr("text-anchor", function (d) { // are we past the center? return (d.endAngle + d.startAngle) / 2 > Math.PI ? "end" : "start"; }) .text(function (d, i) { return d.value.toFixed(2); }); //this makes the major arc g.append("path") .attr("d", function (d) { return arcMajor(d); }) .on("mouseenter", function(d) { d3.select(this) .attr("stroke","white") .transition() .duration(1000) .attr("d", arcOver) .attr("stroke-width",6); div.transition() .duration(200) .style("opacity", .9); div.html( '<a href= "http://facebook.com">' + // The first <a> tag d.data.major + "</a>" + "<br/>" + d.data.minor) .style("left", (d3.event.pageX) + "px") .style("top", (d3.event.pageY - 28) + "px"); }) .on("mouseleave", function(d) { d3.select(this).transition() .attr("d", arcMajor) .attr("stroke","none"); }) .style("fill", function (d) { return d3.rgb(color(d.data.grp)); }); //this makes the minor arcs g.append("path") .attr("d", function (d) { return arcMinor(d); }) .on("mouseenter", function(d) { d3.select(this) .attr("stroke","white") .transition() .duration(1000) .attr("d", arcOverMin) .attr("stroke-width",6); }) .on("mouseleave", function(d) { d3.select(this).transition() .attr("d", arcMinor) .attr("stroke","none"); }) .style("fill", function (d) { return d3.rgb(color(d.data.grp)).darker(2);//for making the inner path darker }); 
 .arc text { font: 10px sans-serif; text-anchor: middle; } .arc path { stroke: #fff; } div.tooltip { position: absolute; text-align: center; width: 60px; height: 28px; padding: 2px; font: 12px sans-serif; background: lightsteelblue; border: 0px; border-radius: 8px; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> 

您只需要增加圓弧的outerRadius實現此效果。

希望這可以幫助。

 var arcMajorOver = d3.svg.arc()
   .outerRadius(function(d) {
     return radius - 10;
   });

 var arcMinorOver = d3.svg.arc()
   .outerRadius(function(d) {
     var s = scale((d.data.major - d.data.minor));
     if (s > radius - 20) {
       return radius - 20;
     }    
     return scale(d.data.major - d.data.minor) + 10;
   });

 //this makes the major arc
 g.append("path")
   .attr("d", function(d) {
     return arcMajor(d);
   })
   .style("fill", function(d) {
     return d3.rgb(color(d.data.grp));
   }).on("mouseenter", function(d) {
     d3.select(this)
       .attr("stroke", "white")
       .transition()
       .duration(1000)
       .attr("d", arcMajorOver)
       .style("stroke-width",6);
   })
   .on("mouseleave", function(d) {
     d3.select(this).transition()
       .attr("d", arcMajor)
       .style("stroke-width",0);
   });;;

 //this makes the minor arcs
 g.append("path")
   .attr("d", function(d) {
     return arcMinor(d);
   })
   .style("fill", function(d) {
     return d3.rgb(color(d.data.grp)).darker(2); //for making the inner path darker
   }).on("mouseenter", function(d) {
     d3.select(this)
       .attr("stroke", "white")
       .transition()
       .duration(1000)
       .attr("d", arcMinorOver)
       .style("stroke-width",6);
   })
   .on("mouseleave", function(d) {
     d3.select(this).transition()
       .attr("d", arcMinor)
       .style("stroke-width",0);
   });

 var width = 960, height = 500, radius = Math.min(width, height) / 2; var color = d3.scale.ordinal() .range(["cyan", "green", "blue", "brown", "violet", "orange", "purple"]); var arcMajor = d3.svg.arc() .outerRadius(function(d) { return radius - 20; }) .innerRadius(0); var arcMajorOver = d3.svg.arc() .outerRadius(function(d) { return radius - 10; }); //this for making the minor arc var arcMinor = d3.svg.arc() .outerRadius(function(d) { // scale for calculating the radius range([20, radius - 40]) var s = scale((d.data.major - d.data.minor)); if (s > radius - 20) { return radius - 20; } return scale(d.data.major - d.data.minor); }) .innerRadius(0); var arcMinorOver = d3.svg.arc() .outerRadius(function(d) { var s = scale((d.data.major - d.data.minor)); if (s > radius - 20) { return radius - 20; } return scale(d.data.major - d.data.minor) + 10; }); var labelr = 260; var pie = d3.layout.pie() .sort(null) .value(function(d) { return d.major; }); var svg = d3.select("body").append("svg") .attr("width", width) .attr("height", height) .append("g") .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")"); data = [{ major: 500, minor: 250, grp: 1 }, { major: 100, minor: 80, grp: 2 }, { major: 100, minor: 50, grp: 3 }, { major: 100, minor: 60, grp: 4 }, { major: 100, minor: 10, grp: 5 }]; var scale = d3.scale.linear() .range([d3.min(data, function(d) { return d.minor; }), radius - 100 - d3.max(data, function(d) { return d.minor / d.major; })]) //setting the scale domain .domain([d3.min(data, function(d) { return d.minor; }), d3.max(data, function(d) { return d.minor; })]); var g = svg.selectAll(".arc") .data(pie(data)) .enter().append("g") .attr("class", "arc"); g.append("svg:text") .attr("transform", function(d) { var c = arcMajor.centroid(d), x = c[0], y = c[1], // pythagorean theorem for hypotenuse h = Math.sqrt(x * x + y * y); return "translate(" + (x / h * labelr) + ',' + (y / h * labelr) + ")"; }) .attr("dy", ".35em") .attr("text-anchor", function(d) { // are we past the center? return (d.endAngle + d.startAngle) / 2 > Math.PI ? "end" : "start"; }) .text(function(d, i) { return d.value.toFixed(2); }); //this makes the major arc g.append("path") .attr("d", function(d) { return arcMajor(d); }) .style("fill", function(d) { return d3.rgb(color(d.data.grp)); }).on("mouseenter", function(d) { d3.select(this) .transition() .duration(1000) .attr("d", arcMajorOver) .style("stroke-width",6); }) .on("mouseleave", function(d) { d3.select(this).transition() .attr("d", arcMajor) .style("stroke-width", 0); });;; //this makes the minor arcs g.append("path") .attr("d", function(d) { return arcMinor(d); }) .style("fill", function(d) { return d3.rgb(color(d.data.grp)).darker(2); //for making the inner path darker }).on("mouseenter", function(d) { d3.select(this) .transition() .duration(1000) .attr("d", arcMinorOver) .style("stroke-width",6); }) .on("mouseleave", function(d) { d3.select(this).transition() .attr("d", arcMinor) .style("stroke-width", 0); }); 
 .arc text { font: 10px sans-serif; text-anchor: middle; } .arc path { stroke: #fff; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM