d3堆叠条形图不更新

d3 Stacked Bar Chart Not Updating

本文关键字:更新 条形图 d3      更新时间:2023-09-26

我正在按照Mike在http://bl.ocks.org/mbostock/4679202/的示例制作堆叠条形/倍数图表。这工作得很好,我的图表在起始数据集的倍数和堆栈之间转换得很好。查看此处提琴http://jsfiddle.net/sc4jaxg3/。

然而,当我尝试更新()并加入到第二个测试数据集时…什么也不会发生。我怀疑这是由于分配给组"g"和其中的"rects"的数据之间存在一些明显的差异,但我对为什么它不起作用无能为力。如有任何帮助,我将不胜感激。

第二个问题,不那么重要:我在每个"矩形"上面都有标签,显示实际的数值,除了每个组的第一个矩形外,它看起来很好。

请参阅下面我的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);

你应该这样替换过滤器选择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>
相关文章: