繁体   English   中英

D3水平条形图不会过渡到新数据集

[英]D3 horizontal bar chart will not transition to new dataset

我正在研究d3.js水平条形图( http://bl.ocks.org/juan-cb/ab9a30d0e2ace0d2dc8c ),它会根据用户选择来更新/转换。 目前,我已向图形添加了标签,但不再更新。 不知道问题出在哪里。 条形图应从左侧开始,但由于某种原因也已移至右侧。 为了在标签上添加标签,我添加了“ g”元素来同时容纳rect和文本。 任何帮助将不胜感激。

JsFiddle- https: //jsfiddle.net/fewpwqhd/1/

JS

datasetTotal = [{
    label: "Category 1",
    value: 19
}, {
    label: "Category 2",
    value: 5
}, {
    label: "Category 3",
    value: 13
}, {
    label: "Category 4",
    value: 17
}, {
    label: "Category 5",
    value: 21
}, {
    label: "Category 6",
    value: 25
}];

datasetOption1 = [{
    label: "Category 1",
    value: 22
}, {
    label: "Category 2",
    value: 33
}, {
    label: "Category 3",
    value: 4
}, {
    label: "Category 4",
    value: 15
}, {
    label: "Category 5",
    value: 36
}, {
    label: "Category 6",
    value: 0
}];

datasetOption2 = [{
    label: "Category 1",
    value: 10
}, {
    label: "Category 2",
    value: 20
}, {
    label: "Category 3",
    value: 30
}, {
    label: "Category 4",
    value: 5
}, {
    label: "Category 5",
    value: 12
}, {
    label: "Category 6",
    value: 23
}];

d3.selectAll("input").on("change", selectDataset);

function selectDataset() {
    var value = this.value;
    if (value == "total") {
        change(datasetTotal);
    } else if (value == "option1") {
        change(datasetOption1);
    } else if (value == "option2") {
        change(datasetOption2);
    }
}

var margin = {
        top: (parseInt(d3.select('body').style('height'), 10) / 20),
        right: (parseInt(d3.select('body').style('width'), 10) / 20),
        bottom: (parseInt(d3.select('body').style('height'), 10) / 20),
        left: (parseInt(d3.select('body').style('width'), 10) / 5)
    },
    width = parseInt(d3.select('body').style('width'), 10) - margin.left - margin.right,
    height = parseInt(d3.select('body').style('height'), 10) - margin.top - margin.bottom;

var div = d3.select("body").append("div").attr("class", "toolTip");

var formatPercent = d3.format("");

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

var x = d3.scale.linear()
    .range([0, width]);

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

var yAxis = d3.svg.axis()
    .scale(y)
    .orient("left");
//.tickFormat(formatPercent);

var svg = d3.select("body").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 + ")");

svg.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")")
    .call(xAxis);

d3.select("input[value=\"total\"]").property("checked", true);
change(datasetTotal);

function change(dataset) {

    y.domain(dataset.map(function(d) {
        return d.label;
    }));
    x.domain([0, d3.max(dataset, function(d) {
        return d.value;
    })]);

    svg.append("g")
        .attr("class", "x axis")
        .attr("transform", "translate(0," + height + ")")
        .call(xAxis);

    svg.select(".y.axis").remove();
    svg.select(".x.axis").remove();

    svg.append("g")
        .attr("class", "y axis")
        .call(yAxis)
        .append("text")
        .attr("transform", "rotate(0)")
        .attr("x", 50)
        .attr("dx", ".1em")
        .style("text-anchor", "end")
        .text("Option %");


    var bar = svg.selectAll(".bar")
        .data(dataset, function(d) {
            return d.label;
        })
        // new data:
        .enter().append("g");

    bar.append("rect")
        .attr("class", "bar")
        .attr("x", function(d) {
            return x(d.value);
        })
        .attr("y", function(d) {
            return y(d.label);
        })
        .attr("width", function(d) {
            return width - x(d.value);
        })
        .attr("height", y.rangeBand());

    bar.append("text")
        .attr("x", function(d) {
            return x(d.value) - 3;
        })
        .attr("text-anchor", "end")
        .attr("y", function(d) {
            return y(d.label) + y.rangeBand() / 2;
        })
        .attr("dy", ".35em")
        .text(function(d) {
            return d.value;
        });


    var bars = d3.select("svg").selectAll("g.rects").data(dataset);

    // removed data:
    bars.exit().remove();

    // updated data:
    bars.transition()
        .duration(750)
        .attr("x", function(d) {
            return 0;
        })
        .attr("y", function(d) {
            return y(d.label);
        })
        .attr("width", function(d) {
            return x(d.value);
        })
        .attr("height", y.rangeBand());

};

这是我的建议:由于您要将矩形和文本元素都附加到<g> (组),因此您的enter-update-exit模式应适用于组,而不适用于矩形和文本:

var bar = svg.selectAll(".bar")
    .data(dataset, function(d) {
        return d.label;
    });

var barExit = bar.exit().remove();

var barEnter = bar.enter()
    .append("g")
    .attr("class", "bar");

实际上,由于您的数据集始终有6个类别,因此您甚至不需要所有这些类别(代码可能会大大缩短)。

这是您更新的小提琴: https : //jsfiddle.net/2523onr3/

附言:我自由地使标杆从左到右而不是从右到左增长。 如果不正确,只需更改xwidth属性。

我会对这种方法的利弊感兴趣吗?

https://jsfiddle.net/sjp700/2523onr3/2/

bar = svg.selectAll(".bar")
              .data(dataset)

        bar_g = bar.enter()
              .append("g")
              .attr("class", "bar")
             .transition()
              .attr("transform", function (d) { return "translate(" + x(0) + "," + y(d.label) + ")"; });

        svg.selectAll(".bar")
             .append("rect")
             .attr("class", "rectband");

        svg.selectAll(".bar")
            .append("text")
            .attr("class", "textband");

        bar.selectAll(".textband")
          .attr("transform", function (d) { return "translate(" + x(d.value) + "," + 0 + ")"; })
          .attr("y", 30)
          .attr("dy", ".35em")
          .style("fill", "black")
          .text(function (d) { return d.value; });

        bar.selectAll(".rectband")
          .attr("width", function (d) { return x(d.value); })
          .attr("height", y.rangeBand());       

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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