d3.js更新后的rect保留前一个

时间:2016-01-26 05:24:08

标签: javascript d3.js

我搜索了很多,但我的javascript知识仅限于获得解决方案并了解我找到的解决方案。

我创建了一个工作正常的D3.js图表​​。 它从json对象接收值,并根据值绘制颜色变化。

以下是D3的代码:

// Graphique D3.js
var margin = {top: 40, right: 20, bottom: 30, left: 40},
    width = 1100 - margin.left - margin.right,
    height = 250 - margin.top - margin.bottom;

// var formatPercent = d3.format(".0%");

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

var y = d3.scale.linear()
    .range([height, 0]);

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

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

var tip = d3.tip()
  .attr('class', 'd3-tip')
  .offset([-10, 0])
  .html(function(d) {
    return "<strong>temp:</strong> <span style='color:red'>" + d.temp + "</span>";
  })

var svg = d3.select("#graph").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.call(tip);

var dataJson = [
  { id: 0 ,timee:"0h00" , temp:1    },
  { id: 1 ,timee:"0h30" , temp:0    },
  { id: 2 ,timee:"1h00" , temp:0.5  },
  { id: 3 ,timee:"1h30" , temp:1    },
  { id: 4 ,timee:"2h00" , temp:1.5  },
  { id: 5 ,timee:"2h30" , temp:2    },
  { id: 6 ,timee:"3h00" , temp:2.5  },
  { id: 7 ,timee:"3h30" , temp:3    },
  { id: 8 ,timee:"4h00" , temp:3.5  },
  { id: 9 ,timee:"4h30" , temp:4    },
  { id:10 ,timee:"5h00" , temp:4.5  },
  { id:11 ,timee:"5h30" , temp:5    },
  { id:12 ,timee:"6h00" , temp:5.5  },
  { id:13 ,timee:"6h30" , temp:6    },
  { id:14 ,timee:"7h00" , temp:6.5  },
  { id:15 ,timee:"7h30" , temp:7    },
  { id:16 ,timee:"8h00" , temp:7.5  },
  { id:17 ,timee:"8h30" , temp:8    },
  { id:18 ,timee:"9h00" , temp:8.5  },
  { id:19 ,timee:"9h30" , temp:9    },
  { id:20 ,timee:"10h00", temp:10   },
  { id:21 ,timee:"10h30", temp:11   },
  { id:22 ,timee:"11h00", temp:12   },
  { id:23 ,timee:"11h30", temp:13   },
  { id:24 ,timee:"12h00", temp:14   },
  { id:25 ,timee:"12h30", temp:15   },
  { id:26 ,timee:"13h00", temp:16   },
  { id:27 ,timee:"13h30", temp:17   },
  { id:28 ,timee:"14h00", temp:18   },
  { id:29 ,timee:"14h30", temp:19   },
  { id:30 ,timee:"15h00", temp:20   },
  { id:31 ,timee:"15h30", temp:21   },
  { id:32 ,timee:"16h00", temp:22   },
  { id:33 ,timee:"16h30", temp:23   },
  { id:34 ,timee:"17h00", temp:24   },
  { id:35 ,timee:"17h30", temp:25   },
  { id:36 ,timee:"18h00", temp:25.5 },
  { id:37 ,timee:"18h30", temp:8    },
  { id:38 ,timee:"19h00", temp:21   },
  { id:39 ,timee:"19h30", temp:19   },
  { id:40 ,timee:"20h00", temp:20   },
  { id:41 ,timee:"20h30", temp:12   },
  { id:42 ,timee:"21h00", temp:25.5 },
  { id:43 ,timee:"21h30", temp:4    },
  { id:44 ,timee:"22h00", temp:0    },
  { id:45 ,timee:"22h30", temp:7    },
  { id:46 ,timee:"23h00", temp:18   },
  { id:47 ,timee:"23h30", temp:8    }
]

// The following code was contained in the callback function.
x.domain(dataJson.map(function(d) { return d.timee; }));
y.domain([0, d3.max(dataJson, function(d) { return d.temp; })]);

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

svg.append("g")
    .attr("class", "y axis")
    .call(yAxis)
    .append("text")
    .attr("transform", "rotate(-90)")
    .attr("y", 6)
    .attr("dy", ".71em")
    .style("text-anchor", "end")
    .text("temp");

var bar = svg.selectAll(".bar")
    .data(dataJson)
    .enter()
    .append("rect")
    .attr("class", "bar")
    .attr("x", function(d) { return x(d.timee); })
    .attr("width", x.rangeBand())
    .attr("y", function(d) { return y(d.temp); })
    .attr("height", function(d) { return height - y(d.temp); })
    // Nuance de couleur de fond des barres :
    .attr("fill", function(d) {
      if(d.temp > 18){
        return "rgb(" + (d.temp * 10) + ", 0 , 5)";
      }else if(d.temp > 12 && d.temp <= 18){
        return "rgb( " + (d.temp * 10) + ", 0, " + (d.temp * 10) + ")";
      }else{
        return "rgb( 5, 0, " + (d.temp * 10) + ")";
      }
     })
    .on('mouseover', tip.show)
    .on('mouseout', tip.hide);

svg.selectAll("text")
   .data(dataJson)
   .enter()
   .append("text")
   .text(function(d) {
    return d;
    })
   .attr("x", function(d, i) {
    return i * (w / dataJson.length) + 5;
   })
   .attr("y", function(d) {
    return h - (d * 4) + 15;
   });

function type(d) {
  d.temp = +d.temp;
  return d;
}

然后我使用输入类型=“数字”来实时更改带有updGraph函数的图形 每个值有1个输入,这个值是0h00值:

<input type="number" onInput="updtGraph(0,this.value);" id="tmpInp0" class="tmpInp" value="18" min="0" max="25.5" step="0.5">

这是updtGraph(0,this.value),(和updtgraph函数使用的setTemp(id,newTemp)函数):

function setTemp(id, newTemp) {
  for (var i=0; i<dataJson.length; i++) {
    if (dataJson[i].id === id) {
      dataJson[i].temp = newTemp;
      return;
    }
  }
}

function updtGraph(id, newTemp){
  var svg = d3.select("svg").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 + ")");

  setTemp(id, newTemp);

  svg.selectAll(".bar")
          .data(dataJson)
          .enter()
          .append("rect")
          .attr("class", "bar")
          .attr("x", function(d) { return x(d.timee); })
          .attr("width", x.rangeBand())
          .attr("y", function(d) { return y(d.temp); })
          .attr("height", function(d) { return height - y(d.temp); })
          // Nuance de couleur de fond des barres :
          .attr("fill", function(d) {
            if(d.temp > 18){
              return "rgb(" + (d.temp * 10) + ", 0 , 5)";
            }else if(d.temp > 12 && d.temp <= 18){
              return "rgb( " + (d.temp * 10) + ", 0, " + (d.temp * 10) + ")";
            }else{
              return "rgb( 5, 0, " + (d.temp * 10) + ")";
            }
           })
          .on('mouseover', tip.show)
          .on('mouseout', tip.hide)
}

它工作正常,如果我用输入更改值,D3会更新:

值:1 enter image description here

值:19 enter image description here

但问题是,如果我输入的值低于前一个值,我会在新的值后面打印旧值。

值5:

enter image description here

正确打印新值(值:深蓝色为5色) 之前的值(值:红色为19)仍显示,但我希望它消失。

我该怎么做?

非常感谢您的帮助,抱歉不要使用JSfiddle我无法使用我的代码。

已解决:__________________________________________________________________

我找到了一个解决方案,只需删除图形容器,每次更改设置时都会更新图形:

document.getElementById("graph").innerHTML = '';
setTemp(id, newTemp);
createD3();

→D3图表被删除 我已经通过将它放在一个函数中来更改创建图形的代码:createD3() 然后我更新新的json值并创建一个新的图形createD3()。

肯定比编辑已更改的栏更慢但是有效。

1 个答案:

答案 0 :(得分:1)

默认情况下,d3不会删除不再位于数据集中的元素。您必须使用d3.selection.exit并编写代码以删除不再需要的元素。我在下面列出了一个基于updtGraph函数的简单示例:

var bars = svg.selectAll(".bar").data(dataJson);
bars.enter().append("rect")... //put your remaining original code here
bars.exit().remove(); //removes all elements from the screen that have "exited" the data-set