perf: Automatically adjust heatmap update delay.
Closes
This now defaults to having an update delay that is the last render time
plus about one refresh cycle.
MODIFY
src/canvas/heatmapFeature.js
src/canvas/heatmapFeature.js
@@ -39,6 +39,7 @@ var canvas_heatmapFeature = function (arg) {
m_heatMapTransform,
s_init = this._init,
s_update = this._update,
+ m_lastRenderDuration,
m_renderTime = timestamp();
/**
@@ -298,6 +299,7 @@ var canvas_heatmapFeature = function (arg) {
this._renderOnCanvas = function (context2d, map) {
if (m_renderTime.timestamp() < m_this.buildTime().timestamp()) {
+ let starttime = Date.now();
var data = m_this.data() || [],
radius = m_this.style('radius') + m_this.style('blurRadius'),
binned = m_this.binned(),
@@ -350,6 +352,7 @@ var canvas_heatmapFeature = function (arg) {
};
m_renderTime.modified();
layer.renderer().clearCanvas(false);
+ m_lastRenderDuration = Date.now() - starttime;
}
return m_this;
@@ -440,6 +443,14 @@ var canvas_heatmapFeature = function (arg) {
parseFloat((rotation - m_heatMapPosition.rotation).toFixed(4)) !== 0 ||
parseFloat(origin.x.toFixed(1)) !== 0 ||
parseFloat(origin.y.toFixed(1)) !== 0) {
+ let delay = m_this.updateDelay();
+ if (delay < 0 && m_lastRenderDuration) {
+ delay = m_lastRenderDuration - Math.floor(1000 / 60 * delay);
+ } else if (m_lastRenderDuration) {
+ delay = m_lastRenderDuration * 2;
+ } else {
+ delay = 100;
+ }
m_heatMapPosition.timeout = window.setTimeout(function () {
m_heatMapPosition.timeout = undefined;
m_this.buildTime().modified();

MODIFY
src/heatmapFeature.js
src/heatmapFeature.js
@@ -19,8 +19,11 @@ var transform = require('./transform');
* @property {number} [minIntensity=null] Minimum intensity of the data.
* Minimum intensity must be a positive real number and is used to normalize
* all intensities within a dataset. If `null`, it is computed.
- * @property {number} [updateDelay=1000] Delay in milliseconds after a zoom,
- * rotate, or pan event before recomputing the heatmap.
+ * @property {number} [updateDelay=-1] Delay in milliseconds after a zoom,
+ * rotate, or pan event before recomputing the heatmap. If 0, this is double
+ * the last render time. If negative, it is roughly the last render time
+ * plus the absolute value of the specified number of refresh intervals.
+ * compute a delay based on the last heatmap render time.
* @property {boolean|number|'auto'} [binned='auto'] If `true` or a number,
* spatially bin data as part of producing the heatmap. If falsy, each
* datapoint stands on its own. If `'auto'`, bin data if there are more data
@@ -76,7 +79,7 @@ var heatmapFeature = function (arg) {
m_maxIntensity = arg.maxIntensity !== undefined ? arg.maxIntensity : null;
m_minIntensity = arg.minIntensity !== undefined ? arg.minIntensity : null;
m_binned = arg.binned !== undefined ? arg.binned : 'auto';
- m_updateDelay = arg.updateDelay ? parseInt(arg.updateDelay, 10) : 1000;
+ m_updateDelay = (arg.updateDelay || arg.updateDelay === 0) ? parseInt(arg.updateDelay, 10) : -1;
/**
* Get/Set maxIntensity.
@@ -121,7 +124,9 @@ var heatmapFeature = function (arg) {
*
* @param {number} [val] If not specified, return the current update delay.
* If specified, this is the delay in milliseconds after a zoom, rotate,
- * or pan event before recomputing the heatmap.
+ * or pan event before recomputing the heatmap. If 0, this is double the
+ * last render time. If negative, it is roughly the last render time plus
+ * the absolute value of the specified number of refresh intervals.
* @returns {number|this}
*/
this.updateDelay = function (val) {

MODIFY
tests/cases/heatmap.js
tests/cases/heatmap.js
@@ -29,7 +29,7 @@ describe('canvas heatmap', function () {
});
it('Add feature to a layer', function () {
- feature1 = layer.createFeature('heatmap')
+ feature1 = layer.createFeature('heatmap', {updateDelay: 1000})
.data(testData)
.intensity(function (d) {
return d[0];
@@ -204,7 +204,7 @@ describe('canvas heatmap', function () {
});
it('updateDelay', function () {
var heatmap = heatmapFeature({layer: layer});
- expect(heatmap.updateDelay()).toBe(1000);
+ expect(heatmap.updateDelay()).toBe(-1);
expect(heatmap.updateDelay(40)).toBe(heatmap);
expect(heatmap.updateDelay()).toBe(40);
heatmap = heatmapFeature({layer: layer, updateDelay: 50});

perf: Automatically adjust heatmap update delay.

Closes #1087.

This now defaults to having an update delay that is the last render time
plus about one refresh cycle.