examples/website/plot/plot-layer/plot-layer.js (136 lines of code) (raw):

import {CompositeLayer, COORDINATE_SYSTEM} from '@deck.gl/core'; import {scaleLinear} from 'd3-scale'; import AxesLayer from './axes-layer'; import SurfaceLayer from './surface-layer'; const DEFAULT_GET_SCALE = {type: 'function', value: () => scaleLinear()}; const DEFAULT_TICK_FORMAT = {type: 'function', value: x => x.toFixed(2)}; const DEFAULT_TICK_COUNT = 6; const DEFAULT_COLOR = [0, 0, 0, 255]; const defaultProps = { // SurfaceLayer props getPosition: {type: 'accessor', value: (u, v) => [0, 0, 0]}, getColor: {type: 'accessor', value: (x, y, z) => DEFAULT_COLOR}, getXScale: DEFAULT_GET_SCALE, getYScale: DEFAULT_GET_SCALE, getZScale: DEFAULT_GET_SCALE, uCount: 100, vCount: 100, lightStrength: 0.1, // AxesLayer props drawAxes: true, fontSize: 12, xTicks: DEFAULT_TICK_COUNT, yTicks: DEFAULT_TICK_COUNT, zTicks: DEFAULT_TICK_COUNT, xTickFormat: DEFAULT_TICK_FORMAT, yTickFormat: DEFAULT_TICK_FORMAT, zTickFormat: DEFAULT_TICK_FORMAT, xTitle: 'x', yTitle: 'y', zTitle: 'z', axesPadding: 0, axesColor: [0, 0, 0, 255], coordinateSystem: COORDINATE_SYSTEM.CARTESIAN }; /* * @classdesc * A layer that plots a surface based on a z=f(x,y) equation. * * @class * @param {Object} [props] * @param {Function} [props.getPosition] - method called to get [x, y, z] from (u,v) values * @param {Function} [props.getColor] - method called to get color from (x,y,z) returns [r,g,b,a]. * @param {Integer} [props.uCount] - number of samples within x range * @param {Integer} [props.vCount] - number of samples within y range * @param {Number} [props.lightStrength] - front light strength * @param {Boolean} [props.drawAxes] - whether to draw axes * @param {Function} [props.getXScale] - returns a d3 scale from (params = {min, max}) * @param {Function} [props.getYScale] - returns a d3 scale from (params = {min, max}) * @param {Function} [props.getZScale] - returns a d3 scale from (params = {min, max}) * @param {Number | [Number]} [props.xTicks] - either tick counts or an array of tick values * @param {Number | [Number]} [props.yTicks] - either tick counts or an array of tick values * @param {Number | [Number]} [props.zTicks] - either tick counts or an array of tick values * @param {Function} [props.xTickFormat] - returns a string from value * @param {Function} [props.yTickFormat] - returns a string from value * @param {Function} [props.zTickFormat] - returns a string from value * @param {String} [props.xTitle] - x axis title * @param {String} [props.yTitle] - y axis title * @param {String} [props.zTitle] - z axis title * @param {Number} [props.axesPadding] - amount to set back grids from the plot, relative to the size of the bounding box * @param {Number} [props.fontSize] - size of the labels * @param {Array} [props.axesColor] - color of the gridlines, in [r,g,b,a] */ export default class PlotLayer extends CompositeLayer { updateState() { const {uCount, vCount, getPosition, getXScale, getYScale, getZScale} = this.props; // calculate z range let xMin = Infinity; let xMax = -Infinity; let yMin = Infinity; let yMax = -Infinity; let zMin = Infinity; let zMax = -Infinity; for (let vIndex = 0; vIndex < vCount; vIndex++) { for (let uIndex = 0; uIndex < uCount; uIndex++) { const u = uIndex / (uCount - 1); const v = vIndex / (vCount - 1); const [x, y, z] = getPosition(u, v); if (isFinite(x)) { xMin = Math.min(xMin, x); xMax = Math.max(xMax, x); } if (isFinite(y)) { yMin = Math.min(yMin, y); yMax = Math.max(yMax, y); } if (isFinite(z)) { zMin = Math.min(zMin, z); zMax = Math.max(zMax, z); } } } const xScale = getXScale({min: xMin, max: xMax}); const yScale = getYScale({min: yMin, max: yMax}); const zScale = getZScale({min: zMin, max: zMax}); this.setState({xScale, yScale, zScale}); } renderLayers() { const {xScale, yScale, zScale} = this.state; const { getPosition, getColor, uCount, vCount, lightStrength, fontSize, xTicks, yTicks, zTicks, xTickFormat, yTickFormat, zTickFormat, xTitle, yTitle, zTitle, axesPadding, axesColor, drawAxes, updateTriggers } = this.props; return [ new SurfaceLayer( { getPosition, getColor, uCount, vCount, xScale, yScale, zScale, lightStrength }, this.getSubLayerProps({ id: 'surface', updateTriggers }) ), new AxesLayer( { xScale, yScale, zScale, fontSize, xTicks, yTicks, zTicks, xTickFormat, yTickFormat, zTickFormat, xTitle, yTitle, zTitle, padding: axesPadding, color: axesColor }, this.getSubLayerProps({ id: 'axes' }), { visible: drawAxes, pickable: false } ) ]; } } PlotLayer.layerName = 'PlotLayer'; PlotLayer.defaultProps = defaultProps;