2016-09-09 17 views
1

私はd3で単純な折れ線グラフを作成していますが、データの更新時に線をアニメーション化しようとしていました(今は1行あります)。animate d3.js折れ線グラフのパス出口

// https://bl.ocks.org/mbostock/3883245 
// http://bl.ocks.org/d3noob/7030f35b72de721622b8 
function LineChart(options) { 
    // Mike Bostock margin conventions. 
    // See http://bl.ocks.org/mbostock/3019563 for more info. 
    const margin = this.margin = { 
     top: 20, 
     right: 20, 
     bottom: 30, 
     left: 40 
    }; 

    // Used by some of the functions that get a different context when called by d3. 
    const thisRef = this; 

    this.width = options.width - margin.left - margin.right; 
    this.height = options.height - margin.top - margin.bottom; 

    this.x = d3.time.scale() 
     .range([0, this.width]); 
    this.y = d3.scale.linear() 
     .range([this.height, 0]); 

    this.xAxis = d3.svg.axis() 
     .scale(this.x) 
     .orient('bottom'); 
    this.yAxis = d3.svg.axis() 
     .scale(this.y) 
     .orient('left'); 

    this.line = d3.svg.line() 
     // https://github.com/d3/d3-3.x-api-reference/blob/master/SVG-Shapes#line_interpolate 
     .interpolate(options.interpolate) 
     .x(function(d) { 
      return thisRef.x(d.date); 
     }) 
     .y(function(d) { 
      return thisRef.y(d.value); 
     }); 

    // Create an SVG element (appended to `#chart`): 
    // 1. set size; 
    // 2. add a `g` element (as in a group) - the `svg` variable here is a `g` element now; 
    // 3. set the transform on `<g>` (not on `<svg>`). 
    this.svg = d3.select(options.target) 
     .append('svg') 
     .attr('width', this.width + margin.left + margin.right) 
     .attr('height', this.height + margin.top + margin.bottom) 
     .append('g') 
     .attr('transform', `translate(${margin.left}, ${margin.top})`); 

    // Add x axis. 
    this.svg.append('g') 
     .attr('class', 'x axis') 
     .attr('transform', `translate(0, ${this.height})`) 

    // Add y axis (with a label). 
    this.svg.append('g') 
     .attr('class', 'y axis') 
     // Just for the title (ticks are automatic). 
     .append('text') 
     // Rotate the text. 
     .attr('transform', 'rotate(-90)') 
     .attr('y', 6) 
     .attr('dy', '.71em') 
     .style('text-anchor', 'end') 
     .text('Price ($)'); 
} 

LineChart.prototype.update = function update(data) { 
    const thisRef = this; 

    this.x.domain(d3.extent(data, function(d) { 
     return d.date; 
    })); 
    this.y.domain(d3.extent(data, function(d) { 
     return d.value; 
    })); 

    this.svg.select('.x.axis') 
     .transition() 
     .call(this.xAxis); 
    this.svg.select('.y.axis') 
     .transition() 
     .call(this.yAxis) 

    const lines = this.svg.selectAll('.line') 
     .data(data, function(d) { 
      return d.label; 
     }); 

    lines.enter() 
     .append('path') 
     .attr('class', 'line'); 

    lines.transition() 
     .duration(1500) 
     .attr('d', this.line(data)); 

    lines.exit() 
     .remove(); 
} 

実行中の例hereが表示されます。

この例では、3000ミリ秒の遅延があり、その後にアップデートとアニメーションが表示されます。

しかし、私はちょっとした問題があります。ラインの一部がアニメーションなしで投げ捨てられています。

私がつらい時、私は非常にD3を経験したわけではないとして、何が起こっているかを考え出すを持って、いくつかの助けをいただければ幸いです:)

答えて

1

D3は、DOM要素をアニメーション化します。あなたの例では1つのDOM要素(1行)しかなく、D3はその1行を変更したと考えます(1500ミリ秒間)。投げ捨てられたポイント(またはポイントが追加されたポイント)をどうするかはわかりません。 SVGパスセグメントは単なるアニメーションの単位ではありません。 'enter'と 'exit'の選択は、データを変更すると変更されません(また、 'exit'の選択は空です)。

  1. データの一部を削除する前に、不足しているポイントで余分な行(DOM要素)を作成し、別にそれをアニメーション:

    は、2つのオプションがあります。

  2. その行のセグメントを作成します(したがって、複数の行を作成し、各2点につき1行ずつ)し、アニメートします(http://jsfiddle.net/L1tLot0v/15/を参照)。残念ながら、補間はそれほどクールではありません。

    var segmentedData = segments(data); 
    const lines = this.svg.selectAll('.line') 
        .data(segmentedData, function(d) { 
         return d[0].date; 
    }); 
    
    var lineFunc = this.line; 
    lines.enter() 
        .append('path') 
        .attr('class', 'line') 
        .style("opacity", 0.0) 
        .attr('d', function(d) { 
         return lineFunc(d)}) 
        .transition() 
        .duration(1000) 
        .style("opacity", 1.0); 
    
    lines.exit() 
        .transition() 
        .duration(1000) 
        .style("opacity", 0.0) 
        .remove(); 
    
関連する問題