d3堆积条形图未更新

时间:2015-09-13 01:52:54

标签: javascript json d3.js

按照迈克在http://bl.ocks.org/mbostock/4679202/的例子,我正在制作堆积条/倍数图表。这很好用,我的图表在多次和堆栈与起始数据集之间转换得很好。请参阅此处的小提琴http://jsfiddle.net/sc4jaxg3/

但是,当我尝试Update()并加入第二个测试数据集时......没有任何反应。我怀疑这是由于分配给组“g”的数据与其中的“rects”之间存在一些明显的差异,但我最终知道为什么它不起作用。任何帮助将不胜感激。

第二个问题而不是优先级:我在每个“rect”上面都有标签显示实际的数值,除了每个组的第一个部分外,它看起来很好。

请参阅下面的我的js代码。谢谢!

var testViz = [

{ gender: "F", group: "18-24", total: 14 },
{ gender: "F", group: "25-34", total: 52 },
{ gender: "F", group: "35-44", total: 125 },
{ gender: "F", group: "45-54", total: 139 },
{ gender: "F", group: "55-64", total: 140 },
{ gender: "F", group: "65-74", total: 43 },
{ gender: "F", group: "75-84", total: 5 },
{ gender: "M", group: "18-24", total: 8 },
{ gender: "M", group: "25-34", total: 15 },
{ gender: "M", group: "35-44", total: 36 },
{ gender: "M", group: "45-54", total: 45 },
{ gender: "M", group: "55-64", total: 34 },
{ gender: "M", group: "65-74", total: 21 },
{ gender: "M", group: "75-84", total: 3 }

];

var testViz2 = [

{ gender: "F", group: "18-24", total: 14 },
{ gender: "F", group: "25-34", total: 111 },
{ gender: "F", group: "35-44", total: 134 },
{ gender: "F", group: "45-54", total: 139 },
{ gender: "F", group: "55-64", total: 140 },
{ gender: "F", group: "65-74", total: 43 },
{ gender: "F", group: "75-84", total: 2 },
{ gender: "M", group: "18-24", total: 8 },
{ gender: "M", group: "25-34", total: 15 },
{ gender: "M", group: "35-44", total: 23 },
{ gender: "M", group: "45-54", total: 45 },
{ gender: "M", group: "55-64", total: 34 },
{ gender: "M", group: "65-74", total: 112 },
{ gender: "M", group: "75-84", total: 3 }

];

var margin = { top: 0, right: 20, bottom: 20, left: 60 },
    width = 600 - margin.left - margin.right,
    height = 400 - margin.top - margin.bottom;

var y0 = d3.scale.ordinal()
    .rangeRoundBands([height, 0], .2);

var y1 = d3.scale.linear();

var x = d3.scale.ordinal()
    .rangeRoundBands([0, width], .1, 0);

var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom");

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

var stack = d3.layout.stack()
    .values(function (d) { return d.values; })
    .x(function (d) { return d.group; })
    .y(function (d) { return d.total; })
    .out(function (d, y0) { d.valueOffset = y0; });

var color = d3.scale.ordinal().range(["#0094cc", "#FF8408"]);

var svg = d3.select("#genderChart").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

this.DrawGenderChart = function (data) {

data.forEach(function (d) {
    d.total = +d.total;
});

var dataByGender = d3.nest()
    .key(function(d) { return d.gender; })
    .entries(data);

stack(dataByGender);
x.domain(dataByGender[0].values.map(function (d) { return d.group; }));
y0.domain(dataByGender.map(function (d) { return d.key; }));
y1.domain([0, d3.max(data, function (d) { return d.total; })]).range([y0.rangeBand(), 0]);

var group = svg.selectAll(".gender")
    .data(dataByGender)
  .enter().append("g")
    .attr("class", "gender")
    .attr("transform", function (d) { return "translate(0," + y0(d.key) + ")"; });

group.append("text")
    .attr("class", "gender-label")
    .attr("x", -50)
    .attr("y", function (d) { return y1(d.values[0].total / 2); })
    .attr("dy", ".35em")
    .text(function (d) {
        var output;

        if (d.key == "F")
            output = "Female";
        else if (d.key == "M")
            output = "Male";
        else
            output = "Unknown";

        return output;
    });

var rects = group.selectAll("rect")
    .data(function (d) { return d.values; })

rects.exit().remove();

rects.enter().append("rect")
    .style("fill", function (d) { return color(d.gender); })
    .attr("x", function (d) { return x(d.group); })
    .attr("y", function (d) { return y1(d.total); })
    .attr("width", x.rangeBand())
    .attr("height", function (d) { return y0.rangeBand() - y1(d.total); });

group.selectAll("text")
    .data(function (d) { console.log(d); return d.values; })
  .enter().append("text")
    .attr("text-anchor", "middle")
    .attr("class", "rect-label")
    .attr("x", function (d) { return x(d.group) + (x.rangeBand() / 2); })
    .attr("y", function (d) { return y1(d.total) - 10; })
    .text(function (d) { return d.total; });


group.filter(function (d, i) { return !i; }).append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + y0.rangeBand() + ")")
    .call(xAxis);


d3.selectAll(".genderCompare").on("click", function () {


    if (this.textContent === "Compare by Gender") transitionMultiples();
    else transitionStacked();

});

function transitionMultiples() {
    var t = svg.transition().duration(750),
        g = t.selectAll(".gender").attr("transform", function (d) { return "translate(0," + y0(d.key) + ")"; });
    g.selectAll("rect").attr("y", function (d) { return y1(d.total); });
    g.select(".gender-label").attr("y", function (d) { return y1(d.values[0].total / 2); })
    g.selectAll(".rect-label").attr("opacity", 1);
}

function transitionStacked() {
    var t = svg.transition().duration(750),
        g = t.selectAll(".gender").attr("transform", "translate(0," + y0(y0.domain()[0]) + ")");
    g.selectAll("rect").attr("y", function (d) { return y1(d.total + d.valueOffset); });
    g.select(".gender-label").attr("y", function (d) { return y1(d.values[0].total / 2 + d.values[0].valueOffset); })
    g.selectAll(".rect-label").attr("opacity", 0);
}
};

DrawGenderChart(testViz);
DrawGenderChart(testViz2);

1 个答案:

答案 0 :(得分:0)

你应该用这个替换过滤器选择JS代码:

d3.selectAll(".compare-criteria").on("click", function () {
   if (this.className.indexOf("genderCompare") > 0) 
     transitionMultiples();
   else 
     transitionStacked();
});

用这个html:

<div id="genderChart">
    <span class="compare-criteria ageCompare">Compare by Age</span>
    <span class="compare-criteria genderCompare option-selected">Compare by Gender</span>
</div>