更新选择不起作用 [英] Update selection not working

查看:108
本文介绍了更新选择不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是D3的新手,我试图显示一个简单的d3条形图,该条形图会基于下拉菜单更改它正在显示的数据属性-数据保持不变,并且我显示的标签相同(x轴)的每个下拉菜单中,仅标签应过渡/更改其顺序,条形值应根据其显示的属性进行过渡/更改.

I'm new to D3 and I am trying to display a simple d3 bar chart that changes which data attribute it is visualizing based on a dropdown menu - the data remains the same and I am displaying the same labels (x-axis) with each dropdown selection, just the labels should transition/change their ordering and the bar values should transition/change based on which attribute they are showing.

但是,当下拉菜单更改时,不会调用过渡(更新)选择-仅在图表首次加载时调用.因此,基于该代码,y轴正在更改其数值,但是高度始终保持为初始高度,因此尽管标签发生了变化,但条形图完全没有动画.

When the dropdown menu changes however, the transition (update) selection isn't getting called - it is only called when the chart loads for the first time. Therefore, based on the code, the y-Axis is changing its numerical values, but the heights always remain the same as they are initiated so the bars don't animate at all despite the labels changing.

updateChart(menuSelection) { // called when dropdown selection changes, and initially upon page load with default menuSelection
    // I sort the data by the attribute of the dropdown item selected
    this.myData.sort(function(a,b){
        if(menuSelection == 1) return b.count - a.count;
        else if(menuSelection == 2) return b.positiveCount - a.positiveCount;
        else return b.negativeCount - a.negativeCount;
    });

    var m = this.myData.length;
    var svg = d3.select(".chart"),
        margin = {top: 40, right: 25, bottom: 40, left: 25},
        width = +svg.attr("width") - margin.left - margin.right,
        height = +svg.attr("height") - margin.top - margin.bottom;
    var g = svg.select("g.rectGroup").attr("transform", "translate(" + margin.left + "," + margin.top + ")").attr("class", "rectGroup");
    if(g.empty()) {
        g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")").attr("class", "rectGroup");
    }

    var x = d3.scaleBand()
        .domain(myData.map(function(d) { return d._id; }))
        .range([0, width])
        .padding(0.08);

    var yMax = d3.max(this.myData, function(d) {
        if(this.menuSelection == 1) return d.count;
        else if(this.menuSelection == 2) return d.positiveCount;
        else return d.negativeCount;
    });
    var y = d3.scaleLinear()
        .domain([0, yMax])
        .range([height, 0]);

    var xAxis = d3.axisBottom()
        .scale(x);
    var yAxis = d3.axisLeft()
        .scale(y);

    var yz = getHeights(m, menuSelection, this.myData); // ARRAY OF HEIGHTS DEPENDING ON MENU DROP DOWN SELECTION

    var bars = g.selectAll(".bar")
        .data(this.myData, function(d) {
            return d._id; // KEY IS ITEM NAME FOR OBJECT CONSTANCY; ALL ITEMS ARE DISPLAYED REGARDLESS OF ATTRIBUTE SELECTED, BUT ORDER/VALUES CHANGE FOR EACH ITEM
        })
        .enter().append("rect")
        .attr("class", "bar")
        .attr("height", 0)
        .attr("y", height);

    bars.transition().duration(700)
        .attr("x", function(d) { return x(d._id); })
        .attr("width", x.bandwidth())
        .attr("y", function(d, i) { return y(yz[i])})
        .attr("height", function(d, i) {
            return height - y(yz[i])
        });

    bars.exit().remove();

    svg.selectAll(".axis").remove();

    var height_to_use = +svg.attr("height") - margin.bottom
    var xAxis_g = svg.append("g")
        .attr("class", "x axis")
        .attr("transform", "translate(" + margin.left + "," + height_to_use + ")")
        .call(xAxis)
        .selectAll(".tick text")
        .call(wrap, x.bandwidth());

    svg.append("g")
        .attr("class", "y axis")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
        .call(yAxis);

    function getHeights(m, menuSelection, data) {
      var values = [];
      for (var i = 0; i < m; ++i) {
        if(menuSelection == 1) {
          values[i] = data[i].count;
        } else if(menuSelection == 2) {
          values[i] = data[i].positiveCount;
        } else {
          values[i] = data[i].negativeCount;
        }
      }
      return values;
    }
}

推荐答案

实际上,您没有在代码中选择了更新.

Actually, you don't have an update selection in your code.

要获得更新选择,请像这样拆分您的输入"选择:

For having an update selection, break up your "enter" selection, like this:

//this is the update selection
var bars = g.selectAll(".bar")
    .data(data, function(d) {
        return d._id;
    });

//and the remainder is the enter selection
bars.enter().append("rect")
    .attr("class", "bar")
    .attr("height", 0)
    .attr("y", height);

另外,值得一提的是,由于您的代码中没有更新选择,因此...

Also, it's worth mentioning that, since you don't have an update selection in your code, this...

bars.exit().remove();

...没用.

这篇关于更新选择不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆