简体   繁体   中英

D3 JS stacked bar at top instead of bottom using path

I followed the following SA question to build a stacked bar chart using <path> instead of <rect> , so I can style the top bar part to have a rounded corner.

How to Make a bar chart with rounded corners with extended grid in d3.js?

Here is a code pen with my code showing my code and the wrong effect: https://codepen.io/Yeronimo/pen/jOPWBGL

The problem is that the stacked bars align at the top.

I have tried many changes to the bar function and the calling "attr d" function, but I seem to be only making things worse. Any help would be appreciated.

And here a poorly shopped image of what it should look like. So the idea is that the bars have the correct height and correct order in my current code, just that they should be aligning at the bottom. In the image the rounded corners got lost, but they are visible in the pen.

底部的酒吧很好

Change the base y of the bars from yscale(d[1]) to yscale(0) like the following:

return bar((xscale(xlabels[i]) + (xscale.bandwidth() / num_groups) * gnum) + 5,
            yscale(0),
            14,
            yscale(d[1]), s);

Now the bars will be upright. But don't be fooled. The stacks that appear on the graph are not correct, and do not reflect the data properly. That is because the h parameter in the bar function is the height of the bar, and d[1] is, in fact, y - h . So the bar function needs to be corrected.

function bar(x, y, w, y1, r, f) {
    // Flag for sweep:
    if (f == undefined) f = 1;
    // x coordinates of top of arcs
    var x0 = x + r;
    var x1 = x + w - r;
    // y coordinates of bottom of arcs
    var y0 = y1 + r;
    // just for convenience (slightly different than above):
    var l = "L", a = "A";

    var parts = ["M", x, y, l, x, y0, a, r, r, 0, 0, f, x0, y1, l, x1, y1, a, r, r, 0, 0, f, x + w, y0, l, x + w, y, "Z"];
    return parts.join(" ");
}

The same effect can be achieved by calling the original bar with yscale(0) - yscale(d[1]) , but this will create unnecessary redundancy. Now the bars are in their correct sizes.

However, the shorter bars are now hidden behind the longer ones in each stacks. So the draw order of the bars need to be reversed. Alter the datasets as such, performing stack.reverse() for each stack.

var datasets = [
            d3.stack().keys(['LKV', 'SROI', 'NoRisk'])(data).reverse(),
            d3.stack().keys(['LKV1', 'SROI1', 'NoRisk1'])(data).reverse(),
            d3.stack().keys(['LKV2', 'SROI2', 'NoRisk2'])(data).reverse()
        ];

That's it. Here 's my version.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM