D3.js - 动态改变序数尺度

时间:2016-04-16 15:08:01

标签: javascript d3.js svg

我有一段代码可以在SVG容器上移动鼠标,并根据鼠标移动缩小/增加可视化的高度/宽度。当用户在x方向上移动鼠标时,图表上的条形显示抖动:x属性将增加2或3,然后恢复到之前的状态:页面上的rects将向右移动几个像素,然后快速回到原来的位置。

我是如何改变序数量表的?或者我应该使用转换而不是操纵X值?

'use strict';
var d3 = require("d3");


var margin = {top: 20, right: 20, bottom: 30, left: 40},
    width = 960 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;




var chartData;
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 + ")");



let render = (e,data)=>{
  width += d3.event ? d3.event.movementX : 0; //changing x axis here
  var x = d3.scale.ordinal()
      .rangeRoundBands([0, width], .1);

  var y = d3.scale.linear()
      .range([data.height, 0]);
//
x.domain(data.map(function(d) { return d.letter; }));
y.domain([0, d3.max(data, function(d) { return d.frequency; })]);
//
  var xAxis = d3.svg.axis()
      .scale(x)
      .orient("bottom");

  var yAxis = d3.svg.axis()
      .scale(y)
      .orient("left")
      .ticks(10, "%")
      .tickSize(1);

      var yAxisEl = 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("Frequency");

      var bars = svg.selectAll(".bar")
          .data(data)
        .enter().append("rect")
          .attr("class", "bar")
          .attr("x", function(d) {
            console.log(x(d.letter));
            var currX = x(d.letter); //sometimes gives wrong valuse
            return currX;
          })
          .attr("width", function(){
            return x.rangeBand();
          })
          .attr("y", function(d) { return y(d.frequency); })
          .attr("height", function(d) { return Math.abs(height - y(d.frequency)); })


}
let rerender=(data)=>{
  d3.select("svg").select("g").selectAll("*").remove();
  render(null,data);
}
d3.tsv("data.tsv", type, function(error, data) {
  if (error) throw error;
        chartData = data;
        chartData.height = height;
        chartData.width = width;
        render(error,chartData);
  });

d3.selectAll('svg').on('mousemove',function(){
  if(chartData){
    chartData.height += d3.event.movementY;
    rerender(chartData);
  }
});

数据

letter  frequency
A   .08167
B   .01492
C   .02782
D   .04253
E   .12702
F   .02288
G   .02015

1 个答案:

答案 0 :(得分:0)

我在内部制作了rerender函数(希望这可以解决你引用的问题)

var rerender = (data) => {
  if (myVar){
    clearTimeout(myVar);//clear timeout if called before 1 millisecond
  }
  myVar = setTimeout(function(){ 
      d3.select("svg").select("g").selectAll("*").remove();
      render(null, data);

  }, 1);
}

工作代码here