在堆积区域图表上创建圆圈

时间:2015-09-29 15:46:16

标签: javascript d3.js charts

我想在堆积区域图表上添加圈子,例如http://nvd3.org/examples/stackedArea.html,使用此示例:http://bl.ocks.org/mbostock/3020685

var stack = d3.layout.stack()
.offset("zero")
.values(function(d) { return d.values; })
.x(function(d) { return d.date; })
.y(function(d) { return d.value; });

var nest = d3.nest()
.key(function(d) { return d.key; });

var layers = stack(nest.entries(data));

svg.selectAll("circle")
        .data(layers)
        .enter().append('circle')
        .attr('cx', function (d, i) { return x(d.values[i].value); })
        .attr('cy', function (d, i) { return y(d.values[i].date); })
        .attr('r', 10);

当然,图表上没有圆圈,我很确定cycx的值不正确,但我无法理解它们。

这是数据:

key,value,date
Group1,37,04/23/12
Group2,12,04/23/12
Group3,46,04/23/12
Group1,32,04/24/12
Group2,19,04/24/12
Group3,42,04/24/12
Group1,45,04/25/12
Group2,16,04/25/12
Group3,44,04/25/12
Group1,24,04/26/12
Group2,52,04/26/12
Group3,64,04/26/12

更新: 好吧,经过一段时间我弄清楚了:

svg.selectAll("circle")
  .data(data)
  .enter().append('circle')
  .attr('cx', function (d, i) { return x(d.date); })
  .attr('cy', function (d, i) { return y(d.y0 + d.y); })

1 个答案:

答案 0 :(得分:0)

只是为了好玩......

d3.csv("https://rawgit.com/cool-Blue/SO-Questions/master/stack/data.csv",function(data){
        var size = {width: 500, height: 180},
            light = [0,0,1,0.2],
            svg = d3.select("body").append("svg").attr(size)
                .on("mousemove", function() {
                    var m = d3.mouse(svg.node()).map(function(d, i){
                            var side = [size.width, size.height][i];
                            return d / side
                        }),
                        m1 = m.map(Math.round),
                        m2 = [(m[0] % 0.5)*2, (m[1] % 0.5)*2];
                        cat10.copy().range(cat10.range().map(filters.FlatShade.bind(null, svg, [m1[0],m1[1],m2[0],m2[1]])));
                    console.log([m.map(f), [m1[0],m2[0]].map(f),[m1[1],m2[1]].map(f)].join("\t"))
                    function f(x){return d3.format(" >6.3f")(x)}
                }),
            x = d3.time.scale()
                .domain(["04/23/12", "04/26/12"].map(function(d){
                    return new Date(d)
                }))
                .range([0,size.width]),
            y = d3.scale.linear()
                .range([size.height, 0]),
            r = d3.scale.linear()
                .range([0, size.height]),
            cat10 = d3.scale.category10(),
            color = cat10.copy().range(cat10.range().map(filters.FlatShade.bind(null, svg, light)));

        data.forEach(function(d){
            d.date = new Date(d.date);
            d.value = +d.value
        });

        var stack = d3.layout.stack()
            .offset("wiggle")
            .order("inside-out")
            .values(function(d) { return d.values; })
            .x(function(d) {
                return d.date;
            })
            .y(function(d) {
                return +d.value;
            });

        var nest = d3.nest()
            .key(function(d) { return d.key; });

        var layers = stack(nest.entries(data));

        var monthHeights = layers.map(function(g){return d3.max(g.values, function(d){return d.y0 + d.y} )}),
            maxMonth = d3.max(monthHeights);
        y.domain([0, maxMonth]);
        r.domain(y.domain());
        x.range(x.range().map(function(d, i){return d + [maxMonth/2, -maxMonth/2][i]}));
        color.domain(layers.map(function(o){return o.key}));

        var layerGroups = svg.selectAll("circles")
            .data(layers)
            .enter().append('g')
            .attr({"class": "layer", "mix-blend-mode": "normal"}),
            areas = d3.svg.area()
                .x(function(d){
                    return x(d.date)
                })
                .y0(function(d){
                    return y(d.y0)
                })
                .y1(function(d){
                    return y(d.y0 + d.y)
                })
                .interpolate("cardinal"),
            bands = layerGroups.selectAll("path")
                .data(function(d){
                    return [d.values]
                })
                .enter().append("path")
                .attr({
                    "d": function(d) {
                        return areas(d)
                    },
                    opacity: 0.5,
                    stroke: function(d){
                        return color(d[0].key)
                    },
                    //                    "stroke-width": 6,
                    fill: function(d){
                        return color(d[0].key)
                    }
                }),
            circles = layerGroups.selectAll(".circle")
                .data(function(d){
                    return d.values
                })
                .enter().append("ellipse")
                .attr({
                    class: "circle",
                    'cx': function (d, i) {
                        return x(d.date);
                    },
                    'cy': function (d, i) {
                        return y(d.y0 + d.y/2);
                    },
                    'ry': function (d, i) {
                        return r(d.value/2);
                    },
                    'rx': function (d, i) {
                        return r(d.value/4);
                    },
                    "fill": function(d){
                        return color(d.key)
                    },
//                    "mix-blend-mode": "normal"
                })

    })
body{margin:0;}
        svg{outline:solid 1px #ccc}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tinycolor/1.1.2/tinycolor.min.js"></script>
<script src="https://gitcdn.xyz/repo/cool-Blue/d3-lib/master/filters/shadow.js"></script>