Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
157 views
in Technique[技术] by (71.8m points)

javascript - Total height of Stacked Bar on tip of every rectangle in stacked Bar Chart using d3

I drawn a stackedbar Chart in which now I trying to place the Total value(I mean the yaxis value) on tip of the every rectangle. I have coded to fetch the details but here the problem is I am getting Every Layer value on tip of every layer but i need to show only the last layer value.

the problem is shown in below fig's.enter image description hereenter image description here

My code is Shown below

var fData =    
[{"orders":"A","Total_Orders":76,"A_Lines":123,"B_Lines":0,"C_Lines":0,"D_Lines":0,"Total_Lines":123,"Total_Units":3267},
{"orders":"B","Total_Orders":68,"A_Lines":0,"B_Lines":107,"C_Lines":0,"D_Lines":0,"Total_Lines":107,"Total_Units":3115},
{"orders":"C","Total_Orders":81,"A_Lines":0,"B_Lines":0,"C_Lines":123,"D_Lines":0,"Total_Lines":123,"Total_Units":3690},
{"orders":"D","Total_Orders":113,"A_Lines":0,"B_Lines":0,"C_Lines":0,"D_Lines":203,"Total_Lines":203,"Total_Units":7863},
{"orders":"AB","Total_Orders":62,"A_Lines":70,"B_Lines":76,"C_Lines":0,"D_Lines":0,"Total_Lines":146,"Total_Units":1739},
{"orders":"AC","Total_Orders":64,"A_Lines":77,"B_Lines":0,"C_Lines":79,"D_Lines":0,"Total_Lines":156,"Total_Units":2027},
{"orders":"AD","Total_Orders":100,"A_Lines":127,"B_Lines":0,"C_Lines":0,"D_Lines":144,"Total_Lines":271,"Total_Units":6467},
{"orders":"BC","Total_Orders":64,"A_Lines":0,"B_Lines":80,"C_Lines":84,"D_Lines":0,"Total_Lines":164,"Total_Units":1845},
{"orders":"BD","Total_Orders":91,"A_Lines":0,"B_Lines":108,"C_Lines":0,"D_Lines":135,"Total_Lines":243,"Total_Units":4061},
{"orders":"CD","Total_Orders":111,"A_Lines":0,"B_Lines":0,"C_Lines":132,"D_Lines":147,"Total_Lines":279,"Total_Units":5011},
{"orders":"ABC","Total_Orders":45,"A_Lines":58,"B_Lines":63,"C_Lines":55,"D_Lines":0,"Total_Lines":176,"Total_Units":1245},
{"orders":"ABD","Total_Orders":69,"A_Lines":105,"B_Lines":87,"C_Lines":0,"D_Lines":116,"Total_Lines":308,"Total_Units":4538},
{"orders":"ACD","Total_Orders":66,"A_Lines":91,"B_Lines":0,"C_Lines":88,"D_Lines":132,"Total_Lines":311,"Total_Units":4446},{
{"orders":"BCD","Total_Orders":68,"A_Lines":0,"B_Lines":84,"C_Lines":95,"D_Lines":111,"Total_Lines":290,"Total_Units":4187},
{"orders":"ABCD","Total_Orders":56,"A_Lines":96,"B_Lines":90,"C_Lines":93,"D_Lines":143,"Total_Lines":422,"Total_Units":6331}] 
var headers = ["A_Lines", "B_Lines", "C_Lines", "D_Lines"];
            var colors = ["#9999CC", "#F7A35C", "#99CC99", "#CCCC99"];
            var colorScale = d3.scale.ordinal()
                               .domain(headers)
                               .range(colors);
            var layers = d3.layout.stack()(headers.map(function (count) {
                return fData.map(function (d, i) {
                    // alert(d);
                    return { x: d.ORDER_TYPE, y: +d[count], color: colorScale(count) };
                });
            }));
            //StackedBar Rectangle Max

            var yStackMax = d3.max(layers, function (layer) { return d3.max(layer, function (d) { return d.y0 + d.y; }); });
            // Set x, y and colors
            var xScale = d3.scale.ordinal()
         .domain(layers[0].map(function (d) { return d.x; }))
         .rangeRoundBands([25, width], .08);

            var y = d3.scale.linear()
                .domain([0, yStackMax])
                .range([height, 0]);

            //    var color = d3.scale.ordinal()
            //.domain(headers)
            // .range(["#9999CC", "#F7A35C", "#99CC99", "#CCCC99"]);

            // Define and draw axes
            var xAxis = d3.svg.axis()
                        .scale(xScale)
                        .tickSize(1)
                        .tickPadding(6)
                        .orient("bottom");

            var yAxis = d3.svg.axis()
                        .scale(y)
                        .orient("left")
                        .tickFormat(d3.format(".2s"));

            var layer = svg.selectAll(".layer")
                .data(layers)
                .enter().append("g")
                .attr("class", "layer")
                .style("fill", function (d, i) { return colorScale(i); });

            var rect = layer.selectAll("rect")
                .data(function (d) { return d; })
                .enter().append("rect")
                .attr("x", function (d) { return xScale(d.x); })
                .attr("y", height)
                .attr("width", xScale.rangeBand())
                .attr("height", 0)
                .attr("class", function (d) {
                    return "rect bordered " + "color-" + d.color.substring(1);
                });



            layer.selectAll("text.rect")
             .data(function (layer) { return layer; })
             .enter().append("text")
             .attr("text-anchor", "middle")
             .attr("x", function (d) { return xScale(d.x) + xScale.rangeBand() / 2; })
             .attr("y", function (d) { return y(d.y + d.y0) - 3; })
             .text(function (d) { return d.y + d.y0; })
             .style("fill", "4682b4");


            //********** AXES ************
            svg.append("g")
                .attr("class", "x axis")
                .attr("transform", "translate(0," + height + ")")
                .call(xAxis)
                .selectAll("text").style("text-anchor", "end")
                    .attr("dx", "-.8em")
                    .attr("dy", ".15em")
                    .attr("transform", function (d) {
                        return "rotate(-45)"
                    });

            svg.attr("class", "x axis")
               .append("text")
               .attr("text-anchor", "end")  // this makes it easy to centre the text as the transform is applied to the anchor
               .attr("transform", "translate(" + (width / 2) + "," + (height + 60) + ")")  // centre below axis
               .text("Order Velocity Group");


            svg.append("g")
                .attr("class", "y axis")
                .attr("transform", "translate(20,0)")
                .call(yAxis)
              .append("text")
                .attr("transform", "rotate(-90)")
                .attr({ "x": -75, "y": -70 })
                .attr("dy", ".75em")
                .style("text-anchor", "end")
                .text("No. Of Lines");

            //********** LEGEND ************

            var legend = svg.selectAll(".legend")
                        .data(headers.slice().reverse())
                    .enter().append("g")
                    .attr("class", "legend")
                    .attr("transform", function (d, i) { return "translate(" + i * (-100) + "," + (height + 50) + ")"; });

            legend.append("rect")
                .attr("x", width - 18)
                .attr("width", 18)
                .attr("height", 18)
            //.style("fill", color);
                .style("fill", function (d, i) { return colors[i]; })
                .on("mouseover", function (d, i) {
                            svg.selectAll("rect.color-" + colors[i].substring(1)).style("stroke", "blue");
                                })
                .on("mouseout", function (d, i) {
                            svg.selectAll("rect.color-" + colors[i].substring(1)).style("stroke", "white");
                                });

            legend.append("text")
                  .attr("x", width - 24)
                  .attr("y", 9)
                  .attr("dy", ".35em")
                  .style("text-anchor", "end")
                  .text(function (d) { return d; });


            transitionStacked();
            function transitionStacked() {

                y.domain([0, yStackMax]);

                rect.transition()
                    .duration(500)
                    .delay(function (d, i) { return i * 10; })
                    .attr("y", function (d) { return y(d.y0 + d.y); })
                    .attr("height", function (d) { return y(d.y0) - y(d.y0 + d.y); })
                  .transition()
                    .attr("x", function (d) { return xScale(d.x); })
                    .attr("width", xScale.rangeBand());

                rect.on('mouseover', tip.show)
                .on('mouseout', tip.hide)

            };

can anyone help me.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Here is what you need: First, we'll set fData as the data for the texts:

layer.selectAll("text.rect")
    .data(fData)
    .enter()
    .append("text")

But, as this dataset doesn't have the correct yScale value, we'll have to extract it using a filter:

.attr("y", function (d) { 
    var filtered = fData.filter(function(e){ 
        return e.Total_Units == d.Total_Units
    });
    return y(filtered[0].Total_Lines) - 3; 
})

All together:

layer.selectAll("text.rect")
    .data(fData)
    .enter().append("text")
    .attr("text-anchor", "middle")
    .attr("x", function(d) {
        return xScale(d.orders) + xScale.rangeBand() / 2;
    })
    .attr("y", function(d) {
        var filtered = fData.filter(function(e) {
            return e.Total_Units == d.Total_Units
        });
        return y(filtered[0].Total_Lines) - 3;
    })
    .text(function(d) {
        return d.Total_Units
    })
    .style("fill", "4682b4");

Here is your fiddle: https://jsfiddle.net/wnwb6meh/


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...