4

I have created a scatter chart in NVD3.js with dynamic data, but I cannot manage to prevent points from moving across the screen when the data changes (see 'demo snippet' at the end of this question). I would like these points to appear and disappear instantaneously, without any movement at all. Is this possible?

What I have tried

I have found out that someone else had a similar problem with NVD3's pie chart (https://github.com/novus/nvd3/issues/1474). It turned out that duration is not even used anywhere in the pie chart model. This does not seem to apply to the scatter chart (see https://github.com/novus/nvd3/blob/master/src/models/scatterChart.js#L96-L101, line 96 until 101):

chart.update = function() {
    if (duration === 0)
        container.call(chart);
    else
        container.transition().duration(duration).call(chart);
};

More details

  • I am using:
    • D3.js v3.4.11
    • NVD3.js v1.8.2
  • In case that this turns out the be a bug then I will try to write and commit a bug fix. Nevertheless, it would be nice to have a quick workaround.

Demo snippet

Run the snippet and move the slider to see the problem.

var chart;
var dataset; // All data points
var subset; // Datapoints that are close to 

function randomPoint() {
  return {
    x: Math.random(),
    y: Math.random(),
    time: Math.random()
  }
}

// Calculate the subset
function updateSubset(time) {
  var upperBound = time + 0.1;
  var lowerBound = time - 0.1;

  subset[0].values = dataset[0].values.filter(function(d) {
    return lowerBound < d.time && d.time < upperBound;
  });
}

subset = [{
  key: "Foobar",
  values: []
}];

for (var i = 0; i < 100; i++) {
  subset[0].values.push(randomPoint());
}

// Make a deep copy of the full dataset
dataset = jQuery.extend(true, {}, subset);

chart = nv.models.scatterChart()
  .forceX([0, 1])
  .forceY([0, 1])
  .pointRange([150, 150])
  .duration(0); // This doesn't seem to work?

updateSubset(0.5);

d3.select("#chart svg")
  .datum(subset)
  .call(chart);

// Recalculate subset and update chart when the slider is changed
$("#time").on("input", function() {
  var time = Number($("#time").val());
  updateSubset(time);
  chart.update();
});
#time {
  width: 100%;
}
#chart {
  width: 100%;
  height: 400px;
}
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.2/nv.d3.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.2/nv.d3.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div>
  Time control:
</div>
<div>
  <input id="time" type="range" min="0" max="1" value="0.5" step="0.01" />
</div>
<div>
  Points around that time:
</div>
<div id="chart">
  <svg></svg>
</div>
Community
  • 1
  • 1
Luc
  • 544
  • 3
  • 9

0 Answers0