src/helpers/highlight-layer.js
import Layer from '../core/layer';
import Crosshairs from '../shapes/crosshairs';
/**
* Helper to create a crosshair layer that highlights the value
* reported by an object's describe() method at a time set through the
* currentPosition property. The describingObject must have a
* describe(time) method that takes only a time and returns an array
* of { cx, cy, unit }. An example of such a describingObject might be
* another layer.
*
* [example usage](./examples/layer-highlight.html)
*/
export default class HighlightLayer extends Layer {
/**
* @param {Object} options - An object to configure the layer.
*/
constructor(describingObject, options = {}) {
const defaults = {
color: 'red',
labelOffset: 0,
hittable: false, // kind of pass through layer
};
const data = {
currentPosition: 0,
describing: describingObject,
lastDescribedPosition: 0,
lastDescription: null,
describe: function() {
let pos = this.currentPosition;
if (pos !== this.lastDescribedPosition || this.lastDescription === null) {
this.lastDescription = this.describing.describe(pos);
this.lastDescribedPosition = pos;
console.log("requesting new description for cx = " + pos);
} else {
console.log("reusing last description");
}
return this.lastDescription;
}
};
options = Object.assign(defaults, options);
super('entity', data, options);
this.configureShape(Crosshairs, {
// We have a choice here -- use the x coord of the nearest point
// (the one that is also contributing its y coord) or use the x
// coord of the probe point. The latter looks better when the
// probe point is based on a cursor that is also displayed on
// this track. But it's a bit of a lie. Let's do it anyway
cx: (d) => d.currentPosition,
cy: (d) => d.describe()[0].cy,
unit: (d) => d.describe()[0].unit
}, {
color: options.color,
opacity: options.opacity,
labelOffset: options.labelOffset
});
}
set currentPosition(pos) {
this.data[0].currentPosition = pos;
}
get currentPosition() {
return this.data[0].currentPosition;
}
}