From 59e3035242c304d2e84efe8db08a39e6b410f27d Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Mon, 7 Oct 2024 14:55:12 -0400 Subject: [PATCH 01/23] drop deprecated gl2d traces: pointcloud & heatmapgl --- lib/heatmapgl.js | 3 - lib/index-gl2d.js | 2 - lib/index-strict.js | 2 - lib/index.js | 2 - lib/pointcloud.js | 3 - src/plots/gl2d/camera.js | 284 -- src/plots/gl2d/convert.js | 232 -- src/plots/gl2d/index.js | 140 - src/plots/gl2d/scene2d.js | 710 ----- src/traces/heatmapgl/attributes.js | 37 - src/traces/heatmapgl/convert.js | 141 - src/traces/heatmapgl/defaults.js | 25 - src/traces/heatmapgl/index.js | 28 - src/traces/pointcloud/attributes.js | 138 - src/traces/pointcloud/convert.js | 193 -- src/traces/pointcloud/defaults.js | 37 - src/traces/pointcloud/index.js | 27 - tasks/test_mock.mjs | 1 - tasks/util/constants.js | 4 - test/image/baselines/gl2d_heatmapgl.png | Bin 62871 -> 0 bytes .../baselines/gl2d_heatmapgl_discrete.png | Bin 19910 -> 0 bytes .../image/baselines/gl2d_pointcloud-basic.png | Bin 31206 -> 0 bytes test/image/make_baseline.py | 26 - test/image/mocks/gl2d_heatmapgl.json | 29 - test/image/mocks/gl2d_heatmapgl_discrete.json | 30 - test/image/mocks/gl2d_pointcloud-basic.json | 66 - test/jasmine/assets/mock_lists.js | 2 - test/jasmine/bundle_tests/no_webgl_test.js | 12 - test/jasmine/bundle_tests/plotschema_test.js | 27 - test/jasmine/tests/gl2d_click_test.js | 107 - test/jasmine/tests/heatmap_test.js | 2 +- test/jasmine/tests/heatmapgl_test.js | 131 - test/jasmine/tests/modebar_test.js | 18 - test/jasmine/tests/pointcloud_test.js | 255 -- test/plot-schema.json | 2637 +++-------------- 35 files changed, 345 insertions(+), 5006 deletions(-) delete mode 100644 lib/heatmapgl.js delete mode 100644 lib/pointcloud.js delete mode 100644 src/plots/gl2d/camera.js delete mode 100644 src/plots/gl2d/convert.js delete mode 100644 src/plots/gl2d/index.js delete mode 100644 src/plots/gl2d/scene2d.js delete mode 100644 src/traces/heatmapgl/attributes.js delete mode 100644 src/traces/heatmapgl/convert.js delete mode 100644 src/traces/heatmapgl/defaults.js delete mode 100644 src/traces/heatmapgl/index.js delete mode 100644 src/traces/pointcloud/attributes.js delete mode 100644 src/traces/pointcloud/convert.js delete mode 100644 src/traces/pointcloud/defaults.js delete mode 100644 src/traces/pointcloud/index.js delete mode 100644 test/image/baselines/gl2d_heatmapgl.png delete mode 100644 test/image/baselines/gl2d_heatmapgl_discrete.png delete mode 100644 test/image/baselines/gl2d_pointcloud-basic.png delete mode 100644 test/image/mocks/gl2d_heatmapgl.json delete mode 100644 test/image/mocks/gl2d_heatmapgl_discrete.json delete mode 100644 test/image/mocks/gl2d_pointcloud-basic.json delete mode 100644 test/jasmine/tests/heatmapgl_test.js delete mode 100644 test/jasmine/tests/pointcloud_test.js diff --git a/lib/heatmapgl.js b/lib/heatmapgl.js deleted file mode 100644 index 04be0e5ad86..00000000000 --- a/lib/heatmapgl.js +++ /dev/null @@ -1,3 +0,0 @@ -'use strict'; - -module.exports = require('../src/traces/heatmapgl'); diff --git a/lib/index-gl2d.js b/lib/index-gl2d.js index 1fd5d28dd5f..1a2410a33b1 100644 --- a/lib/index-gl2d.js +++ b/lib/index-gl2d.js @@ -6,8 +6,6 @@ Plotly.register([ // traces require('./scattergl'), require('./splom'), - require('./pointcloud'), - require('./heatmapgl'), require('./parcoords'), // transforms diff --git a/lib/index-strict.js b/lib/index-strict.js index 97f4fe57440..7a64e10a309 100644 --- a/lib/index-strict.js +++ b/lib/index-strict.js @@ -32,8 +32,6 @@ Plotly.register([ require('./choropleth'), require('../src/traces/scattergl/strict'), require('../src/traces/splom/strict'), - require('./pointcloud'), - require('./heatmapgl'), require('../src/traces/parcoords/strict'), require('./parcats'), require('./scattermapbox'), diff --git a/lib/index.js b/lib/index.js index 18fc6ed35b5..26a2270d8c6 100644 --- a/lib/index.js +++ b/lib/index.js @@ -32,8 +32,6 @@ Plotly.register([ require('./choropleth'), require('./scattergl'), require('./splom'), - require('./pointcloud'), - require('./heatmapgl'), require('./parcoords'), require('./parcats'), require('./scattermapbox'), diff --git a/lib/pointcloud.js b/lib/pointcloud.js deleted file mode 100644 index 295cbe48ed6..00000000000 --- a/lib/pointcloud.js +++ /dev/null @@ -1,3 +0,0 @@ -'use strict'; - -module.exports = require('../src/traces/pointcloud'); diff --git a/src/plots/gl2d/camera.js b/src/plots/gl2d/camera.js deleted file mode 100644 index 522a969f31e..00000000000 --- a/src/plots/gl2d/camera.js +++ /dev/null @@ -1,284 +0,0 @@ -'use strict'; - -var mouseChange = require('mouse-change'); -var mouseWheel = require('mouse-wheel'); -var mouseOffset = require('mouse-event-offset'); -var cartesianConstants = require('../cartesian/constants'); -var hasPassive = require('has-passive-events'); - -module.exports = createCamera; - -function Camera2D(element, plot) { - this.element = element; - this.plot = plot; - this.mouseListener = null; - this.wheelListener = null; - this.lastInputTime = Date.now(); - this.lastPos = [0, 0]; - this.boxEnabled = false; - this.boxInited = false; - this.boxStart = [0, 0]; - this.boxEnd = [0, 0]; - this.dragStart = [0, 0]; -} - - -function createCamera(scene) { - var element = scene.mouseContainer; - var plot = scene.glplot; - var result = new Camera2D(element, plot); - - function unSetAutoRange() { - scene.xaxis.autorange = false; - scene.yaxis.autorange = false; - } - - function getSubplotConstraint() { - // note: this assumes we only have one x and one y axis on this subplot - // when this constraint is lifted this block won't make sense - var constraints = scene.graphDiv._fullLayout._axisConstraintGroups; - var xaId = scene.xaxis._id; - var yaId = scene.yaxis._id; - for(var i = 0; i < constraints.length; i++) { - if(constraints[i][xaId] !== -1) { - if(constraints[i][yaId] !== -1) return true; - break; - } - } - return false; - } - - result.mouseListener = mouseChange(element, handleInteraction); - - // enable simple touch interactions - element.addEventListener('touchstart', function(ev) { - var xy = mouseOffset(ev.changedTouches[0], element); - handleInteraction(0, xy[0], xy[1]); - handleInteraction(1, xy[0], xy[1]); - - ev.preventDefault(); - }, hasPassive ? {passive: false} : false); - element.addEventListener('touchmove', function(ev) { - ev.preventDefault(); - var xy = mouseOffset(ev.changedTouches[0], element); - handleInteraction(1, xy[0], xy[1]); - - ev.preventDefault(); - }, hasPassive ? {passive: false} : false); - element.addEventListener('touchend', function(ev) { - handleInteraction(0, result.lastPos[0], result.lastPos[1]); - - ev.preventDefault(); - }, hasPassive ? {passive: false} : false); - - function handleInteraction(buttons, x, y) { - var dataBox = scene.calcDataBox(); - var viewBox = plot.viewBox; - - var lastX = result.lastPos[0]; - var lastY = result.lastPos[1]; - - var MINDRAG = cartesianConstants.MINDRAG * plot.pixelRatio; - var MINZOOM = cartesianConstants.MINZOOM * plot.pixelRatio; - - var dx, dy; - - x *= plot.pixelRatio; - y *= plot.pixelRatio; - - // mouseChange gives y about top; convert to about bottom - y = (viewBox[3] - viewBox[1]) - y; - - function updateRange(i0, start, end) { - var range0 = Math.min(start, end); - var range1 = Math.max(start, end); - - if(range0 !== range1) { - dataBox[i0] = range0; - dataBox[i0 + 2] = range1; - result.dataBox = dataBox; - scene.setRanges(dataBox); - } else { - scene.selectBox.selectBox = [0, 0, 1, 1]; - scene.glplot.setDirty(); - } - } - - switch(scene.fullLayout.dragmode) { - case 'zoom': - if(buttons) { - var dataX = x / - (viewBox[2] - viewBox[0]) * (dataBox[2] - dataBox[0]) + - dataBox[0]; - var dataY = y / - (viewBox[3] - viewBox[1]) * (dataBox[3] - dataBox[1]) + - dataBox[1]; - - if(!result.boxInited) { - result.boxStart[0] = dataX; - result.boxStart[1] = dataY; - result.dragStart[0] = x; - result.dragStart[1] = y; - } - - result.boxEnd[0] = dataX; - result.boxEnd[1] = dataY; - - // we need to mark the box as initialized right away - // so that we can tell the start and end points apart - result.boxInited = true; - - // but don't actually enable the box until the cursor moves - if(!result.boxEnabled && ( - result.boxStart[0] !== result.boxEnd[0] || - result.boxStart[1] !== result.boxEnd[1]) - ) { - result.boxEnabled = true; - } - - // constrain aspect ratio if the axes require it - var smallDx = Math.abs(result.dragStart[0] - x) < MINZOOM; - var smallDy = Math.abs(result.dragStart[1] - y) < MINZOOM; - if(getSubplotConstraint() && !(smallDx && smallDy)) { - dx = result.boxEnd[0] - result.boxStart[0]; - dy = result.boxEnd[1] - result.boxStart[1]; - var dydx = (dataBox[3] - dataBox[1]) / (dataBox[2] - dataBox[0]); - - if(Math.abs(dx * dydx) > Math.abs(dy)) { - result.boxEnd[1] = result.boxStart[1] + - Math.abs(dx) * dydx * (dy >= 0 ? 1 : -1); - - // gl-select-box clips to the plot area bounds, - // which breaks the axis constraint, so don't allow - // this box to go out of bounds - if(result.boxEnd[1] < dataBox[1]) { - result.boxEnd[1] = dataBox[1]; - result.boxEnd[0] = result.boxStart[0] + - (dataBox[1] - result.boxStart[1]) / Math.abs(dydx); - } else if(result.boxEnd[1] > dataBox[3]) { - result.boxEnd[1] = dataBox[3]; - result.boxEnd[0] = result.boxStart[0] + - (dataBox[3] - result.boxStart[1]) / Math.abs(dydx); - } - } else { - result.boxEnd[0] = result.boxStart[0] + - Math.abs(dy) / dydx * (dx >= 0 ? 1 : -1); - - if(result.boxEnd[0] < dataBox[0]) { - result.boxEnd[0] = dataBox[0]; - result.boxEnd[1] = result.boxStart[1] + - (dataBox[0] - result.boxStart[0]) * Math.abs(dydx); - } else if(result.boxEnd[0] > dataBox[2]) { - result.boxEnd[0] = dataBox[2]; - result.boxEnd[1] = result.boxStart[1] + - (dataBox[2] - result.boxStart[0]) * Math.abs(dydx); - } - } - } else { - // otherwise clamp small changes to the origin so we get 1D zoom - - if(smallDx) result.boxEnd[0] = result.boxStart[0]; - if(smallDy) result.boxEnd[1] = result.boxStart[1]; - } - } else if(result.boxEnabled) { - dx = result.boxStart[0] !== result.boxEnd[0]; - dy = result.boxStart[1] !== result.boxEnd[1]; - if(dx || dy) { - if(dx) { - updateRange(0, result.boxStart[0], result.boxEnd[0]); - scene.xaxis.autorange = false; - } - if(dy) { - updateRange(1, result.boxStart[1], result.boxEnd[1]); - scene.yaxis.autorange = false; - } - scene.relayoutCallback(); - } else { - scene.glplot.setDirty(); - } - result.boxEnabled = false; - result.boxInited = false; - } else if(result.boxInited) { - // if box was inited but button released then - reset the box - - result.boxInited = false; - } - break; - - case 'pan': - result.boxEnabled = false; - result.boxInited = false; - - if(buttons) { - if(!result.panning) { - result.dragStart[0] = x; - result.dragStart[1] = y; - } - - if(Math.abs(result.dragStart[0] - x) < MINDRAG) x = result.dragStart[0]; - if(Math.abs(result.dragStart[1] - y) < MINDRAG) y = result.dragStart[1]; - - dx = (lastX - x) * (dataBox[2] - dataBox[0]) / - (plot.viewBox[2] - plot.viewBox[0]); - dy = (lastY - y) * (dataBox[3] - dataBox[1]) / - (plot.viewBox[3] - plot.viewBox[1]); - - dataBox[0] += dx; - dataBox[2] += dx; - dataBox[1] += dy; - dataBox[3] += dy; - - scene.setRanges(dataBox); - - result.panning = true; - result.lastInputTime = Date.now(); - unSetAutoRange(); - scene.cameraChanged(); - scene.handleAnnotations(); - } else if(result.panning) { - result.panning = false; - scene.relayoutCallback(); - } - break; - } - - result.lastPos[0] = x; - result.lastPos[1] = y; - } - - result.wheelListener = mouseWheel(element, function(dx, dy) { - if(!scene.scrollZoom) return false; - - var dataBox = scene.calcDataBox(); - var viewBox = plot.viewBox; - - var lastX = result.lastPos[0]; - var lastY = result.lastPos[1]; - - var scale = Math.exp(5.0 * dy / (viewBox[3] - viewBox[1])); - - var cx = lastX / - (viewBox[2] - viewBox[0]) * (dataBox[2] - dataBox[0]) + - dataBox[0]; - var cy = lastY / - (viewBox[3] - viewBox[1]) * (dataBox[3] - dataBox[1]) + - dataBox[1]; - - dataBox[0] = (dataBox[0] - cx) * scale + cx; - dataBox[2] = (dataBox[2] - cx) * scale + cx; - dataBox[1] = (dataBox[1] - cy) * scale + cy; - dataBox[3] = (dataBox[3] - cy) * scale + cy; - - scene.setRanges(dataBox); - - result.lastInputTime = Date.now(); - unSetAutoRange(); - scene.cameraChanged(); - scene.handleAnnotations(); - scene.relayoutCallback(); - - return true; - }, true); - - return result; -} diff --git a/src/plots/gl2d/convert.js b/src/plots/gl2d/convert.js deleted file mode 100644 index 34b79d17d6e..00000000000 --- a/src/plots/gl2d/convert.js +++ /dev/null @@ -1,232 +0,0 @@ -'use strict'; - -var Axes = require('../cartesian/axes'); - -var str2RGBArray = require('../../lib/str2rgbarray'); - -function Axes2DOptions(scene) { - this.scene = scene; - this.gl = scene.gl; - this.pixelRatio = scene.pixelRatio; - - this.screenBox = [0, 0, 1, 1]; - this.viewBox = [0, 0, 1, 1]; - this.dataBox = [-1, -1, 1, 1]; - - this.borderLineEnable = [false, false, false, false]; - this.borderLineWidth = [1, 1, 1, 1]; - this.borderLineColor = [ - [0, 0, 0, 1], - [0, 0, 0, 1], - [0, 0, 0, 1], - [0, 0, 0, 1] - ]; - - this.ticks = [[], []]; - this.tickEnable = [true, true, false, false]; - this.tickPad = [15, 15, 15, 15]; - this.tickAngle = [0, 0, 0, 0]; - this.tickColor = [ - [0, 0, 0, 1], - [0, 0, 0, 1], - [0, 0, 0, 1], - [0, 0, 0, 1] - ]; - this.tickMarkLength = [0, 0, 0, 0]; - this.tickMarkWidth = [0, 0, 0, 0]; - this.tickMarkColor = [ - [0, 0, 0, 1], - [0, 0, 0, 1], - [0, 0, 0, 1], - [0, 0, 0, 1] - ]; - - this.labels = ['x', 'y']; - this.labelEnable = [true, true, false, false]; - this.labelAngle = [0, Math.PI / 2, 0, 3.0 * Math.PI / 2]; - this.labelPad = [15, 15, 15, 15]; - this.labelSize = [12, 12]; - this.labelFont = ['sans-serif', 'sans-serif']; - this.labelColor = [ - [0, 0, 0, 1], - [0, 0, 0, 1], - [0, 0, 0, 1], - [0, 0, 0, 1] - ]; - - this.title = ''; - this.titleEnable = true; - this.titleCenter = [0, 0, 0, 0]; - this.titleAngle = 0; - this.titleColor = [0, 0, 0, 1]; - this.titleFont = 'sans-serif'; - this.titleSize = 18; - - this.gridLineEnable = [true, true]; - this.gridLineColor = [ - [0, 0, 0, 0.5], - [0, 0, 0, 0.5] - ]; - this.gridLineWidth = [1, 1]; - - this.zeroLineEnable = [true, true]; - this.zeroLineWidth = [1, 1]; - this.zeroLineColor = [ - [0, 0, 0, 1], - [0, 0, 0, 1] - ]; - - this.borderColor = [0, 0, 0, 0]; - this.backgroundColor = [0, 0, 0, 0]; - - this.static = this.scene.staticPlot; -} - -var proto = Axes2DOptions.prototype; - -var AXES = ['xaxis', 'yaxis']; - -proto.merge = function(options) { - // titles are rendered in SVG - this.titleEnable = false; - this.backgroundColor = str2RGBArray(options.plot_bgcolor); - - var axisName, ax, axTitle, axMirror; - var hasAxisInDfltPos, hasAxisInAltrPos, hasSharedAxis, mirrorLines, mirrorTicks; - var i, j; - - for(i = 0; i < 2; ++i) { - axisName = AXES[i]; - var axisLetter = axisName.charAt(0); - - // get options relevant to this subplot, - // '_name' is e.g. xaxis, xaxis2, yaxis, yaxis4 ... - ax = options[this.scene[axisName]._name]; - - axTitle = ax.title.text === this.scene.fullLayout._dfltTitle[axisLetter] ? '' : ax.title.text; - - for(j = 0; j <= 2; j += 2) { - this.labelEnable[i + j] = false; - this.labels[i + j] = axTitle; - this.labelColor[i + j] = str2RGBArray(ax.title.font.color); - this.labelFont[i + j] = ax.title.font.family; - this.labelSize[i + j] = ax.title.font.size; - this.labelPad[i + j] = this.getLabelPad(axisName, ax); - - this.tickEnable[i + j] = false; - this.tickColor[i + j] = str2RGBArray((ax.tickfont || {}).color); - this.tickAngle[i + j] = (ax.tickangle === 'auto') ? - 0 : - Math.PI * -ax.tickangle / 180; - this.tickPad[i + j] = this.getTickPad(ax); - - this.tickMarkLength[i + j] = 0; - this.tickMarkWidth[i + j] = ax.tickwidth || 0; - this.tickMarkColor[i + j] = str2RGBArray(ax.tickcolor); - - this.borderLineEnable[i + j] = false; - this.borderLineColor[i + j] = str2RGBArray(ax.linecolor); - this.borderLineWidth[i + j] = ax.linewidth || 0; - } - - hasSharedAxis = this.hasSharedAxis(ax); - hasAxisInDfltPos = this.hasAxisInDfltPos(axisName, ax) && !hasSharedAxis; - hasAxisInAltrPos = this.hasAxisInAltrPos(axisName, ax) && !hasSharedAxis; - - axMirror = ax.mirror || false; - mirrorLines = hasSharedAxis ? - (String(axMirror).indexOf('all') !== -1) : // 'all' or 'allticks' - !!axMirror; // all but false - mirrorTicks = hasSharedAxis ? - (axMirror === 'allticks') : - (String(axMirror).indexOf('ticks') !== -1); // 'ticks' or 'allticks' - - // Axis titles and tick labels can only appear of one side of the scene - // and are never show on subplots that share existing axes. - - if(hasAxisInDfltPos) this.labelEnable[i] = true; - else if(hasAxisInAltrPos) this.labelEnable[i + 2] = true; - - if(hasAxisInDfltPos) this.tickEnable[i] = ax.showticklabels; - else if(hasAxisInAltrPos) this.tickEnable[i + 2] = ax.showticklabels; - - // Grid lines and ticks can appear on both sides of the scene - // and can appear on subplot that share existing axes via `ax.mirror`. - - if(hasAxisInDfltPos || mirrorLines) this.borderLineEnable[i] = ax.showline; - if(hasAxisInAltrPos || mirrorLines) this.borderLineEnable[i + 2] = ax.showline; - - if(hasAxisInDfltPos || mirrorTicks) this.tickMarkLength[i] = this.getTickMarkLength(ax); - if(hasAxisInAltrPos || mirrorTicks) this.tickMarkLength[i + 2] = this.getTickMarkLength(ax); - - this.gridLineEnable[i] = ax.showgrid; - this.gridLineColor[i] = str2RGBArray(ax.gridcolor); - this.gridLineWidth[i] = ax.gridwidth; - - this.zeroLineEnable[i] = ax.zeroline; - this.zeroLineColor[i] = str2RGBArray(ax.zerolinecolor); - this.zeroLineWidth[i] = ax.zerolinewidth; - } -}; - -// is an axis shared with an already-drawn subplot ? -proto.hasSharedAxis = function(ax) { - var scene = this.scene; - var subplotIds = scene.fullLayout._subplots.gl2d; - var list = Axes.findSubplotsWithAxis(subplotIds, ax); - - // if index === 0, then the subplot is already drawn as subplots - // are drawn in order. - return (list.indexOf(scene.id) !== 0); -}; - -// has an axis in default position (i.e. bottom/left) ? -proto.hasAxisInDfltPos = function(axisName, ax) { - var axSide = ax.side; - - if(axisName === 'xaxis') return (axSide === 'bottom'); - else if(axisName === 'yaxis') return (axSide === 'left'); -}; - -// has an axis in alternate position (i.e. top/right) ? -proto.hasAxisInAltrPos = function(axisName, ax) { - var axSide = ax.side; - - if(axisName === 'xaxis') return (axSide === 'top'); - else if(axisName === 'yaxis') return (axSide === 'right'); -}; - -proto.getLabelPad = function(axisName, ax) { - var offsetBase = 1.5; - var fontSize = ax.title.font.size; - var showticklabels = ax.showticklabels; - - if(axisName === 'xaxis') { - return (ax.side === 'top') ? - -10 + fontSize * (offsetBase + (showticklabels ? 1 : 0)) : - -10 + fontSize * (offsetBase + (showticklabels ? 0.5 : 0)); - } else if(axisName === 'yaxis') { - return (ax.side === 'right') ? - 10 + fontSize * (offsetBase + (showticklabels ? 1 : 0.5)) : - 10 + fontSize * (offsetBase + (showticklabels ? 0.5 : 0)); - } -}; - -proto.getTickPad = function(ax) { - return (ax.ticks === 'outside') ? 10 + ax.ticklen : 15; -}; - -proto.getTickMarkLength = function(ax) { - if(!ax.ticks) return 0; - - var ticklen = ax.ticklen; - - return (ax.ticks === 'inside') ? -ticklen : ticklen; -}; - - -function createAxes2D(scene) { - return new Axes2DOptions(scene); -} - -module.exports = createAxes2D; diff --git a/src/plots/gl2d/index.js b/src/plots/gl2d/index.js deleted file mode 100644 index efb10fe9045..00000000000 --- a/src/plots/gl2d/index.js +++ /dev/null @@ -1,140 +0,0 @@ -'use strict'; - -var overrideAll = require('../../plot_api/edit_types').overrideAll; - -var Scene2D = require('./scene2d'); -var layoutGlobalAttrs = require('../layout_attributes'); -var xmlnsNamespaces = require('../../constants/xmlns_namespaces'); -var constants = require('../cartesian/constants'); -var Cartesian = require('../cartesian'); -var fxAttrs = require('../../components/fx/layout_attributes'); -var getSubplotData = require('../get_data').getSubplotData; - -exports.name = 'gl2d'; - -exports.attr = ['xaxis', 'yaxis']; - -exports.idRoot = ['x', 'y']; - -exports.idRegex = constants.idRegex; - -exports.attrRegex = constants.attrRegex; - -exports.attributes = require('../cartesian/attributes'); - -exports.supplyLayoutDefaults = function(layoutIn, layoutOut, fullData) { - if(!layoutOut._has('cartesian')) { - Cartesian.supplyLayoutDefaults(layoutIn, layoutOut, fullData); - } -}; - -// gl2d uses svg axis attributes verbatim, but overrides editType -// this could potentially be just `layoutAttributes` but it would -// still need special handling somewhere to give it precedence over -// the svg version when both are in use on one plot -exports.layoutAttrOverrides = overrideAll(Cartesian.layoutAttributes, 'plot', 'from-root'); - -// similar overrides for base plot attributes (and those added by components) -exports.baseLayoutAttrOverrides = overrideAll({ - plot_bgcolor: layoutGlobalAttrs.plot_bgcolor, - hoverlabel: fxAttrs.hoverlabel - // dragmode needs calc but only when transitioning TO lasso or select - // so for now it's left inside _relayout - // dragmode: fxAttrs.dragmode -}, 'plot', 'nested'); - -exports.plot = function plot(gd) { - var fullLayout = gd._fullLayout; - var fullData = gd._fullData; - var subplotIds = fullLayout._subplots.gl2d; - - for(var i = 0; i < subplotIds.length; i++) { - var subplotId = subplotIds[i]; - var subplotObj = fullLayout._plots[subplotId]; - var fullSubplotData = getSubplotData(fullData, 'gl2d', subplotId); - - // ref. to corresp. Scene instance - var scene = subplotObj._scene2d; - - // If Scene is not instantiated, create one! - if(scene === undefined) { - scene = new Scene2D({ - id: subplotId, - graphDiv: gd, - container: gd.querySelector('.gl-container'), - staticPlot: gd._context.staticPlot, - plotGlPixelRatio: gd._context.plotGlPixelRatio - }, - fullLayout - ); - - // set ref to Scene instance - subplotObj._scene2d = scene; - } - - scene.plot(fullSubplotData, gd.calcdata, fullLayout, gd.layout); - } -}; - -exports.clean = function(newFullData, newFullLayout, oldFullData, oldFullLayout) { - var oldSceneKeys = oldFullLayout._subplots.gl2d || []; - - for(var i = 0; i < oldSceneKeys.length; i++) { - var id = oldSceneKeys[i]; - var oldSubplot = oldFullLayout._plots[id]; - - // old subplot wasn't gl2d; nothing to do - if(!oldSubplot._scene2d) continue; - - // if no traces are present, delete gl2d subplot - var subplotData = getSubplotData(newFullData, 'gl2d', id); - if(subplotData.length === 0) { - oldSubplot._scene2d.destroy(); - delete oldFullLayout._plots[id]; - } - } - - // since we use cartesian interactions, do cartesian clean - Cartesian.clean.apply(this, arguments); -}; - -exports.drawFramework = function(gd) { - if(!gd._context.staticPlot) { - Cartesian.drawFramework(gd); - } -}; - -exports.toSVG = function(gd) { - var fullLayout = gd._fullLayout; - var subplotIds = fullLayout._subplots.gl2d; - - for(var i = 0; i < subplotIds.length; i++) { - var subplot = fullLayout._plots[subplotIds[i]]; - var scene = subplot._scene2d; - - var imageData = scene.toImage('png'); - var image = fullLayout._glimages.append('svg:image'); - - image.attr({ - xmlns: xmlnsNamespaces.svg, - 'xlink:href': imageData, - x: 0, - y: 0, - width: '100%', - height: '100%', - preserveAspectRatio: 'none' - }); - - scene.destroy(); - } -}; - -exports.updateFx = function(gd) { - var fullLayout = gd._fullLayout; - var subplotIds = fullLayout._subplots.gl2d; - - for(var i = 0; i < subplotIds.length; i++) { - var subplotObj = fullLayout._plots[subplotIds[i]]._scene2d; - subplotObj.updateFx(fullLayout.dragmode); - } -}; diff --git a/src/plots/gl2d/scene2d.js b/src/plots/gl2d/scene2d.js deleted file mode 100644 index d988b9bbe12..00000000000 --- a/src/plots/gl2d/scene2d.js +++ /dev/null @@ -1,710 +0,0 @@ -'use strict'; - -var Registry = require('../../registry'); -var Axes = require('../../plots/cartesian/axes'); -var Fx = require('../../components/fx'); - -var createPlot2D = require('../../../stackgl_modules').gl_plot2d; -var createSpikes = require('../../../stackgl_modules').gl_spikes2d; -var createSelectBox = require('../../../stackgl_modules').gl_select_box; -var getContext = require('webgl-context'); - -var createOptions = require('./convert'); -var createCamera = require('./camera'); -var showNoWebGlMsg = require('../../lib/show_no_webgl_msg'); -var axisConstraints = require('../cartesian/constraints'); -var enforceAxisConstraints = axisConstraints.enforce; -var cleanAxisConstraints = axisConstraints.clean; -var doAutoRange = require('../cartesian/autorange').doAutoRange; - -var dragHelpers = require('../../components/dragelement/helpers'); -var drawMode = dragHelpers.drawMode; -var selectMode = dragHelpers.selectMode; - -var AXES = ['xaxis', 'yaxis']; -var STATIC_CANVAS, STATIC_CONTEXT; - -var SUBPLOT_PATTERN = require('../cartesian/constants').SUBPLOT_PATTERN; - - -function Scene2D(options, fullLayout) { - this.container = options.container; - this.graphDiv = options.graphDiv; - this.pixelRatio = options.plotGlPixelRatio || window.devicePixelRatio; - this.id = options.id; - this.staticPlot = !!options.staticPlot; - this.scrollZoom = this.graphDiv._context._scrollZoom.cartesian; - - this.fullData = null; - this.updateRefs(fullLayout); - - this.makeFramework(); - if(this.stopped) return; - - // update options - this.glplotOptions = createOptions(this); - this.glplotOptions.merge(fullLayout); - - // create the plot - this.glplot = createPlot2D(this.glplotOptions); - - // create camera - this.camera = createCamera(this); - - // trace set - this.traces = {}; - - // create axes spikes - this.spikes = createSpikes(this.glplot); - - this.selectBox = createSelectBox(this.glplot, { - innerFill: false, - outerFill: true - }); - - // last button state - this.lastButtonState = 0; - - // last pick result - this.pickResult = null; - - // is the mouse over the plot? - // it's OK if this says true when it's not, so long as - // when we get a mouseout we set it to false before handling - this.isMouseOver = true; - - // flag to stop render loop - this.stopped = false; - - // redraw the plot - this.redraw = this.draw.bind(this); - this.redraw(); -} - -module.exports = Scene2D; - -var proto = Scene2D.prototype; - -proto.makeFramework = function() { - // create canvas and gl context - if(this.staticPlot) { - if(!STATIC_CONTEXT) { - STATIC_CANVAS = document.createElement('canvas'); - - STATIC_CONTEXT = getContext({ - canvas: STATIC_CANVAS, - preserveDrawingBuffer: false, - premultipliedAlpha: true, - antialias: true - }); - - if(!STATIC_CONTEXT) { - throw new Error('Error creating static canvas/context for image server'); - } - } - - this.canvas = STATIC_CANVAS; - this.gl = STATIC_CONTEXT; - } else { - var liveCanvas = this.container.querySelector('.gl-canvas-focus'); - - var gl = getContext({ - canvas: liveCanvas, - preserveDrawingBuffer: true, - premultipliedAlpha: true - }); - - if(!gl) { - showNoWebGlMsg(this); - this.stopped = true; - return; - } - - this.canvas = liveCanvas; - this.gl = gl; - } - - // position the canvas - var canvas = this.canvas; - - canvas.style.width = '100%'; - canvas.style.height = '100%'; - canvas.style.position = 'absolute'; - canvas.style.top = '0px'; - canvas.style.left = '0px'; - canvas.style['pointer-events'] = 'none'; - - this.updateSize(canvas); - - // create SVG container for hover text - var svgContainer = this.svgContainer = document.createElementNS( - 'http://www.w3.org/2000/svg', - 'svg'); - svgContainer.style.position = 'absolute'; - svgContainer.style.top = svgContainer.style.left = '0px'; - svgContainer.style.width = svgContainer.style.height = '100%'; - svgContainer.style['z-index'] = 20; - svgContainer.style['pointer-events'] = 'none'; - - // create div to catch the mouse event - var mouseContainer = this.mouseContainer = document.createElement('div'); - mouseContainer.style.position = 'absolute'; - mouseContainer.style['pointer-events'] = 'auto'; - - this.pickCanvas = this.container.querySelector('.gl-canvas-pick'); - - - // append canvas, hover svg and mouse div to container - var container = this.container; - container.appendChild(svgContainer); - container.appendChild(mouseContainer); - - var self = this; - mouseContainer.addEventListener('mouseout', function() { - self.isMouseOver = false; - self.unhover(); - }); - mouseContainer.addEventListener('mouseover', function() { - self.isMouseOver = true; - }); -}; - -proto.toImage = function(format) { - if(!format) format = 'png'; - - this.stopped = true; - - if(this.staticPlot) this.container.appendChild(STATIC_CANVAS); - - // update canvas size - this.updateSize(this.canvas); - - - // grab context and yank out pixels - var gl = this.glplot.gl; - var w = gl.drawingBufferWidth; - var h = gl.drawingBufferHeight; - - // force redraw - gl.clearColor(1, 1, 1, 0); - gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); - this.glplot.setDirty(); - this.glplot.draw(); - - gl.bindFramebuffer(gl.FRAMEBUFFER, null); - - var pixels = new Uint8Array(w * h * 4); - gl.readPixels(0, 0, w, h, gl.RGBA, gl.UNSIGNED_BYTE, pixels); - - // flip pixels - for(var j = 0, k = h - 1; j < k; ++j, --k) { - for(var i = 0; i < w; ++i) { - for(var l = 0; l < 4; ++l) { - var tmp = pixels[4 * (w * j + i) + l]; - pixels[4 * (w * j + i) + l] = pixels[4 * (w * k + i) + l]; - pixels[4 * (w * k + i) + l] = tmp; - } - } - } - - var canvas = document.createElement('canvas'); - canvas.width = w; - canvas.height = h; - - var context = canvas.getContext('2d', {willReadFrequently: true}); - var imageData = context.createImageData(w, h); - imageData.data.set(pixels); - context.putImageData(imageData, 0, 0); - - var dataURL; - - switch(format) { - case 'jpeg': - dataURL = canvas.toDataURL('image/jpeg'); - break; - case 'webp': - dataURL = canvas.toDataURL('image/webp'); - break; - default: - dataURL = canvas.toDataURL('image/png'); - } - - if(this.staticPlot) this.container.removeChild(STATIC_CANVAS); - - return dataURL; -}; - -proto.updateSize = function(canvas) { - if(!canvas) canvas = this.canvas; - - var pixelRatio = this.pixelRatio; - var fullLayout = this.fullLayout; - - var width = fullLayout.width; - var height = fullLayout.height; - var pixelWidth = Math.ceil(pixelRatio * width) |0; - var pixelHeight = Math.ceil(pixelRatio * height) |0; - - // check for resize - if(canvas.width !== pixelWidth || canvas.height !== pixelHeight) { - canvas.width = pixelWidth; - canvas.height = pixelHeight; - } - - return canvas; -}; - -proto.computeTickMarks = function() { - this.xaxis.setScale(); - this.yaxis.setScale(); - - var nextTicks = [ - Axes.calcTicks(this.xaxis), - Axes.calcTicks(this.yaxis) - ]; - - for(var j = 0; j < 2; ++j) { - for(var i = 0; i < nextTicks[j].length; ++i) { - // coercing tick value (may not be a string) to a string - nextTicks[j][i].text = nextTicks[j][i].text + ''; - } - } - - return nextTicks; -}; - -function compareTicks(a, b) { - for(var i = 0; i < 2; ++i) { - var aticks = a[i]; - var bticks = b[i]; - - if(aticks.length !== bticks.length) return true; - - for(var j = 0; j < aticks.length; ++j) { - if(aticks[j].x !== bticks[j].x) return true; - } - } - - return false; -} - -proto.updateRefs = function(newFullLayout) { - this.fullLayout = newFullLayout; - - var spmatch = this.id.match(SUBPLOT_PATTERN); - var xaxisName = 'xaxis' + spmatch[1]; - var yaxisName = 'yaxis' + spmatch[2]; - - this.xaxis = this.fullLayout[xaxisName]; - this.yaxis = this.fullLayout[yaxisName]; -}; - -proto.relayoutCallback = function() { - var graphDiv = this.graphDiv; - var xaxis = this.xaxis; - var yaxis = this.yaxis; - var layout = graphDiv.layout; - - // make a meaningful value to be passed on to possible 'plotly_relayout' subscriber(s) - var update = {}; - var xrange = update[xaxis._name + '.range'] = xaxis.range.slice(); - var yrange = update[yaxis._name + '.range'] = yaxis.range.slice(); - update[xaxis._name + '.autorange'] = xaxis.autorange; - update[yaxis._name + '.autorange'] = yaxis.autorange; - - Registry.call('_storeDirectGUIEdit', graphDiv.layout, graphDiv._fullLayout._preGUI, update); - - // update the input layout - var xaIn = layout[xaxis._name]; - xaIn.range = xrange; - xaIn.autorange = xaxis.autorange; - - var yaIn = layout[yaxis._name]; - yaIn.range = yrange; - yaIn.autorange = yaxis.autorange; - - // lastInputTime helps determine which one is the latest input (if async) - update.lastInputTime = this.camera.lastInputTime; - graphDiv.emit('plotly_relayout', update); -}; - -proto.cameraChanged = function() { - var camera = this.camera; - - this.glplot.setDataBox(this.calcDataBox()); - - var nextTicks = this.computeTickMarks(); - var curTicks = this.glplotOptions.ticks; - - if(compareTicks(nextTicks, curTicks)) { - this.glplotOptions.ticks = nextTicks; - this.glplotOptions.dataBox = camera.dataBox; - this.glplot.update(this.glplotOptions); - this.handleAnnotations(); - } -}; - -proto.handleAnnotations = function() { - var gd = this.graphDiv; - var annotations = this.fullLayout.annotations; - - for(var i = 0; i < annotations.length; i++) { - var ann = annotations[i]; - - if(ann.xref === this.xaxis._id && ann.yref === this.yaxis._id) { - Registry.getComponentMethod('annotations', 'drawOne')(gd, i); - } - } -}; - -proto.destroy = function() { - if(!this.glplot) return; - - var traces = this.traces; - - if(traces) { - Object.keys(traces).map(function(key) { - traces[key].dispose(); - delete traces[key]; - }); - } - - this.glplot.dispose(); - - this.container.removeChild(this.svgContainer); - this.container.removeChild(this.mouseContainer); - - this.fullData = null; - this.glplot = null; - this.stopped = true; - this.camera.mouseListener.enabled = false; - this.mouseContainer.removeEventListener('wheel', this.camera.wheelListener); - this.camera = null; -}; - -proto.plot = function(fullData, calcData, fullLayout) { - var glplot = this.glplot; - - this.updateRefs(fullLayout); - this.xaxis.clearCalc(); - this.yaxis.clearCalc(); - this.updateTraces(fullData, calcData); - this.updateFx(fullLayout.dragmode); - - var width = fullLayout.width; - var height = fullLayout.height; - - this.updateSize(this.canvas); - - var options = this.glplotOptions; - options.merge(fullLayout); - options.screenBox = [0, 0, width, height]; - - var mockGraphDiv = {_fullLayout: { - _axisConstraintGroups: fullLayout._axisConstraintGroups, - xaxis: this.xaxis, - yaxis: this.yaxis, - _size: fullLayout._size - }}; - - cleanAxisConstraints(mockGraphDiv, this.xaxis); - cleanAxisConstraints(mockGraphDiv, this.yaxis); - - var size = fullLayout._size; - var domainX = this.xaxis.domain; - var domainY = this.yaxis.domain; - - options.viewBox = [ - size.l + domainX[0] * size.w, - size.b + domainY[0] * size.h, - (width - size.r) - (1 - domainX[1]) * size.w, - (height - size.t) - (1 - domainY[1]) * size.h - ]; - - this.mouseContainer.style.width = size.w * (domainX[1] - domainX[0]) + 'px'; - this.mouseContainer.style.height = size.h * (domainY[1] - domainY[0]) + 'px'; - this.mouseContainer.height = size.h * (domainY[1] - domainY[0]); - this.mouseContainer.style.left = size.l + domainX[0] * size.w + 'px'; - this.mouseContainer.style.top = size.t + (1 - domainY[1]) * size.h + 'px'; - - var ax, i; - - for(i = 0; i < 2; ++i) { - ax = this[AXES[i]]; - ax._length = options.viewBox[i + 2] - options.viewBox[i]; - - doAutoRange(this.graphDiv, ax); - ax.setScale(); - } - - enforceAxisConstraints(mockGraphDiv); - - options.ticks = this.computeTickMarks(); - - options.dataBox = this.calcDataBox(); - - options.merge(fullLayout); - glplot.update(options); - - // force redraw so that promise is returned when rendering is completed - this.glplot.draw(); -}; - -proto.calcDataBox = function() { - var xaxis = this.xaxis; - var yaxis = this.yaxis; - var xrange = xaxis.range; - var yrange = yaxis.range; - var xr2l = xaxis.r2l; - var yr2l = yaxis.r2l; - - return [xr2l(xrange[0]), yr2l(yrange[0]), xr2l(xrange[1]), yr2l(yrange[1])]; -}; - -proto.setRanges = function(dataBox) { - var xaxis = this.xaxis; - var yaxis = this.yaxis; - var xl2r = xaxis.l2r; - var yl2r = yaxis.l2r; - - xaxis.range = [xl2r(dataBox[0]), xl2r(dataBox[2])]; - yaxis.range = [yl2r(dataBox[1]), yl2r(dataBox[3])]; -}; - -proto.updateTraces = function(fullData, calcData) { - var traceIds = Object.keys(this.traces); - var i, j, fullTrace; - - this.fullData = fullData; - - // remove empty traces - traceIdLoop: - for(i = 0; i < traceIds.length; i++) { - var oldUid = traceIds[i]; - var oldTrace = this.traces[oldUid]; - - for(j = 0; j < fullData.length; j++) { - fullTrace = fullData[j]; - - if(fullTrace.uid === oldUid && fullTrace.type === oldTrace.type) { - continue traceIdLoop; - } - } - - oldTrace.dispose(); - delete this.traces[oldUid]; - } - - // update / create trace objects - for(i = 0; i < fullData.length; i++) { - fullTrace = fullData[i]; - var calcTrace = calcData[i]; - var traceObj = this.traces[fullTrace.uid]; - - if(traceObj) traceObj.update(fullTrace, calcTrace); - else { - traceObj = fullTrace._module.plot(this, fullTrace, calcTrace); - this.traces[fullTrace.uid] = traceObj; - } - } - - // order object per traces - this.glplot.objects.sort(function(a, b) { - return a._trace.index - b._trace.index; - }); -}; - -proto.updateFx = function(dragmode) { - // switch to svg interactions in lasso/select mode & shape drawing - if(selectMode(dragmode) || drawMode(dragmode)) { - this.pickCanvas.style['pointer-events'] = 'none'; - this.mouseContainer.style['pointer-events'] = 'none'; - } else { - this.pickCanvas.style['pointer-events'] = 'auto'; - this.mouseContainer.style['pointer-events'] = 'auto'; - } - - // set proper cursor - if(dragmode === 'pan') { - this.mouseContainer.style.cursor = 'move'; - } else if(dragmode === 'zoom') { - this.mouseContainer.style.cursor = 'crosshair'; - } else { - this.mouseContainer.style.cursor = null; - } -}; - -proto.emitPointAction = function(nextSelection, eventType) { - var uid = nextSelection.trace.uid; - var ptNumber = nextSelection.pointIndex; - var trace; - - for(var i = 0; i < this.fullData.length; i++) { - if(this.fullData[i].uid === uid) { - trace = this.fullData[i]; - } - } - - var pointData = { - x: nextSelection.traceCoord[0], - y: nextSelection.traceCoord[1], - curveNumber: trace.index, - pointNumber: ptNumber, - data: trace._input, - fullData: this.fullData, - xaxis: this.xaxis, - yaxis: this.yaxis - }; - - Fx.appendArrayPointValue(pointData, trace, ptNumber); - - this.graphDiv.emit(eventType, {points: [pointData]}); -}; - -proto.draw = function() { - if(this.stopped) return; - - requestAnimationFrame(this.redraw); - - var glplot = this.glplot; - var camera = this.camera; - var mouseListener = camera.mouseListener; - var mouseUp = this.lastButtonState === 1 && mouseListener.buttons === 0; - var fullLayout = this.fullLayout; - - this.lastButtonState = mouseListener.buttons; - - this.cameraChanged(); - - var x = mouseListener.x * glplot.pixelRatio; - var y = this.canvas.height - glplot.pixelRatio * mouseListener.y; - - var result; - - if(camera.boxEnabled && fullLayout.dragmode === 'zoom') { - this.selectBox.enabled = true; - - var selectBox = this.selectBox.selectBox = [ - Math.min(camera.boxStart[0], camera.boxEnd[0]), - Math.min(camera.boxStart[1], camera.boxEnd[1]), - Math.max(camera.boxStart[0], camera.boxEnd[0]), - Math.max(camera.boxStart[1], camera.boxEnd[1]) - ]; - - // 1D zoom - for(var i = 0; i < 2; i++) { - if(camera.boxStart[i] === camera.boxEnd[i]) { - selectBox[i] = glplot.dataBox[i]; - selectBox[i + 2] = glplot.dataBox[i + 2]; - } - } - - glplot.setDirty(); - } else if(!camera.panning && this.isMouseOver) { - this.selectBox.enabled = false; - - var size = fullLayout._size; - var domainX = this.xaxis.domain; - var domainY = this.yaxis.domain; - - result = glplot.pick( - (x / glplot.pixelRatio) + size.l + domainX[0] * size.w, - (y / glplot.pixelRatio) - (size.t + (1 - domainY[1]) * size.h) - ); - - var nextSelection = result && result.object._trace.handlePick(result); - - if(nextSelection && mouseUp) { - this.emitPointAction(nextSelection, 'plotly_click'); - } - - if(result && result.object._trace.hoverinfo !== 'skip' && fullLayout.hovermode) { - if(nextSelection && ( - !this.lastPickResult || - this.lastPickResult.traceUid !== nextSelection.trace.uid || - this.lastPickResult.dataCoord[0] !== nextSelection.dataCoord[0] || - this.lastPickResult.dataCoord[1] !== nextSelection.dataCoord[1]) - ) { - var selection = nextSelection; - - this.lastPickResult = { - traceUid: nextSelection.trace ? nextSelection.trace.uid : null, - dataCoord: nextSelection.dataCoord.slice() - }; - this.spikes.update({ center: result.dataCoord }); - - selection.screenCoord = [ - ((glplot.viewBox[2] - glplot.viewBox[0]) * - (result.dataCoord[0] - glplot.dataBox[0]) / - (glplot.dataBox[2] - glplot.dataBox[0]) + glplot.viewBox[0]) / - glplot.pixelRatio, - (this.canvas.height - (glplot.viewBox[3] - glplot.viewBox[1]) * - (result.dataCoord[1] - glplot.dataBox[1]) / - (glplot.dataBox[3] - glplot.dataBox[1]) - glplot.viewBox[1]) / - glplot.pixelRatio - ]; - - // this needs to happen before the next block that deletes traceCoord data - // also it's important to copy, otherwise data is lost by the time event data is read - this.emitPointAction(nextSelection, 'plotly_hover'); - - var trace = this.fullData[selection.trace.index] || {}; - var ptNumber = selection.pointIndex; - var hoverinfo = Fx.castHoverinfo(trace, fullLayout, ptNumber); - - if(hoverinfo && hoverinfo !== 'all') { - var parts = hoverinfo.split('+'); - if(parts.indexOf('x') === -1) selection.traceCoord[0] = undefined; - if(parts.indexOf('y') === -1) selection.traceCoord[1] = undefined; - if(parts.indexOf('z') === -1) selection.traceCoord[2] = undefined; - if(parts.indexOf('text') === -1) selection.textLabel = undefined; - if(parts.indexOf('name') === -1) selection.name = undefined; - } - - Fx.loneHover({ - x: selection.screenCoord[0], - y: selection.screenCoord[1], - xLabel: this.hoverFormatter('xaxis', selection.traceCoord[0]), - yLabel: this.hoverFormatter('yaxis', selection.traceCoord[1]), - zLabel: selection.traceCoord[2], - text: selection.textLabel, - name: selection.name, - color: Fx.castHoverOption(trace, ptNumber, 'bgcolor') || selection.color, - borderColor: Fx.castHoverOption(trace, ptNumber, 'bordercolor'), - fontFamily: Fx.castHoverOption(trace, ptNumber, 'font.family'), - fontSize: Fx.castHoverOption(trace, ptNumber, 'font.size'), - fontColor: Fx.castHoverOption(trace, ptNumber, 'font.color'), - nameLength: Fx.castHoverOption(trace, ptNumber, 'namelength'), - textAlign: Fx.castHoverOption(trace, ptNumber, 'align') - }, { - container: this.svgContainer, - gd: this.graphDiv - }); - } - } - } - - // Remove hover effects if we're not over a point OR - // if we're zooming or panning (in which case result is not set) - if(!result) { - this.unhover(); - } - - glplot.draw(); -}; - -proto.unhover = function() { - if(this.lastPickResult) { - this.spikes.update({}); - this.lastPickResult = null; - this.graphDiv.emit('plotly_unhover'); - Fx.loneUnhover(this.svgContainer); - } -}; - -proto.hoverFormatter = function(axisName, val) { - if(val === undefined) return undefined; - - var axis = this[axisName]; - return Axes.tickText(axis, axis.c2l(val), 'hover').text; -}; diff --git a/src/traces/heatmapgl/attributes.js b/src/traces/heatmapgl/attributes.js deleted file mode 100644 index a0ff2331dc6..00000000000 --- a/src/traces/heatmapgl/attributes.js +++ /dev/null @@ -1,37 +0,0 @@ -'use strict'; - -var heatmapAttrs = require('../heatmap/attributes'); -var colorScaleAttrs = require('../../components/colorscale/attributes'); - -var extendFlat = require('../../lib/extend').extendFlat; -var overrideAll = require('../../plot_api/edit_types').overrideAll; - -var commonList = [ - 'z', - 'x', 'x0', 'dx', - 'y', 'y0', 'dy', - 'text', 'transpose', - 'xtype', 'ytype' -]; - -var attrs = {}; - -for(var i = 0; i < commonList.length; i++) { - var k = commonList[i]; - attrs[k] = heatmapAttrs[k]; -} - -attrs.zsmooth = { - valType: 'enumerated', - values: ['fast', false], - dflt: 'fast', - editType: 'calc', - description: 'Picks a smoothing algorithm use to smooth `z` data.' -}; - -extendFlat( - attrs, - colorScaleAttrs('', {cLetter: 'z', autoColorDflt: false}) -); - -module.exports = overrideAll(attrs, 'calc', 'nested'); diff --git a/src/traces/heatmapgl/convert.js b/src/traces/heatmapgl/convert.js deleted file mode 100644 index d2a97fc2e95..00000000000 --- a/src/traces/heatmapgl/convert.js +++ /dev/null @@ -1,141 +0,0 @@ -'use strict'; - -var createHeatmap2D = require('../../../stackgl_modules').gl_heatmap2d; -var Axes = require('../../plots/cartesian/axes'); -var str2RGBArray = require('../../lib/str2rgbarray'); - - -function Heatmap(scene, uid) { - this.scene = scene; - this.uid = uid; - this.type = 'heatmapgl'; - - this.name = ''; - this.hoverinfo = 'all'; - - this.xData = []; - this.yData = []; - this.zData = []; - this.textLabels = []; - - this.idToIndex = []; - this.bounds = [0, 0, 0, 0]; - - this.options = { - zsmooth: 'fast', - z: [], - x: [], - y: [], - shape: [0, 0], - colorLevels: [0], - colorValues: [0, 0, 0, 1] - }; - - this.heatmap = createHeatmap2D(scene.glplot, this.options); - this.heatmap._trace = this; -} - -var proto = Heatmap.prototype; - -proto.handlePick = function(pickResult) { - var options = this.options; - var shape = options.shape; - var index = pickResult.pointId; - var xIndex = index % shape[0]; - var yIndex = Math.floor(index / shape[0]); - var zIndex = index; - - return { - trace: this, - dataCoord: pickResult.dataCoord, - traceCoord: [ - options.x[xIndex], - options.y[yIndex], - options.z[zIndex] - ], - textLabel: this.textLabels[index], - name: this.name, - pointIndex: [yIndex, xIndex], - hoverinfo: this.hoverinfo - }; -}; - -proto.update = function(fullTrace, calcTrace) { - var calcPt = calcTrace[0]; - - this.index = fullTrace.index; - this.name = fullTrace.name; - this.hoverinfo = fullTrace.hoverinfo; - - // convert z from 2D -> 1D - var z = calcPt.z; - this.options.z = [].concat.apply([], z); - - var rowLen = z[0].length; - var colLen = z.length; - this.options.shape = [rowLen, colLen]; - - this.options.x = calcPt.x; - this.options.y = calcPt.y; - this.options.zsmooth = fullTrace.zsmooth; - - var colorOptions = convertColorscale(fullTrace); - this.options.colorLevels = colorOptions.colorLevels; - this.options.colorValues = colorOptions.colorValues; - - // convert text from 2D -> 1D - this.textLabels = [].concat.apply([], fullTrace.text); - - this.heatmap.update(this.options); - - var xa = this.scene.xaxis; - var ya = this.scene.yaxis; - - var xOpts, yOpts; - if(fullTrace.zsmooth === false) { - // increase padding for discretised heatmap as suggested by Louise Ord - xOpts = { ppad: calcPt.x[1] - calcPt.x[0] }; - yOpts = { ppad: calcPt.y[1] - calcPt.y[0] }; - } - - fullTrace._extremes[xa._id] = Axes.findExtremes(xa, calcPt.x, xOpts); - fullTrace._extremes[ya._id] = Axes.findExtremes(ya, calcPt.y, yOpts); -}; - -proto.dispose = function() { - this.heatmap.dispose(); -}; - -function convertColorscale(fullTrace) { - var scl = fullTrace.colorscale; - var zmin = fullTrace.zmin; - var zmax = fullTrace.zmax; - - var N = scl.length; - var domain = new Array(N); - var range = new Array(4 * N); - - for(var i = 0; i < N; i++) { - var si = scl[i]; - var color = str2RGBArray(si[1]); - - domain[i] = zmin + si[0] * (zmax - zmin); - - for(var j = 0; j < 4; j++) { - range[(4 * i) + j] = color[j]; - } - } - - return { - colorLevels: domain, - colorValues: range - }; -} - -function createHeatmap(scene, fullTrace, calcTrace) { - var plot = new Heatmap(scene, fullTrace.uid); - plot.update(fullTrace, calcTrace); - return plot; -} - -module.exports = createHeatmap; diff --git a/src/traces/heatmapgl/defaults.js b/src/traces/heatmapgl/defaults.js deleted file mode 100644 index 7f5f259fd0b..00000000000 --- a/src/traces/heatmapgl/defaults.js +++ /dev/null @@ -1,25 +0,0 @@ -'use strict'; - -var Lib = require('../../lib'); - -var handleXYZDefaults = require('../heatmap/xyz_defaults'); -var colorscaleDefaults = require('../../components/colorscale/defaults'); -var attributes = require('./attributes'); - - -module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) { - function coerce(attr, dflt) { - return Lib.coerce(traceIn, traceOut, attributes, attr, dflt); - } - - var validData = handleXYZDefaults(traceIn, traceOut, coerce, layout); - if(!validData) { - traceOut.visible = false; - return; - } - - coerce('text'); - coerce('zsmooth'); - - colorscaleDefaults(traceIn, traceOut, layout, coerce, {prefix: '', cLetter: 'z'}); -}; diff --git a/src/traces/heatmapgl/index.js b/src/traces/heatmapgl/index.js deleted file mode 100644 index 79fe08b8fb1..00000000000 --- a/src/traces/heatmapgl/index.js +++ /dev/null @@ -1,28 +0,0 @@ -'use strict'; - -var deprecationWarning = [ - '*heatmapgl* trace is deprecated!', - 'Please consider switching to the *heatmap* or *image* trace types.', - 'Alternatively you could contribute/sponsor rewriting this trace type', - 'based on cartesian features and using regl framework.' -].join(' '); - -module.exports = { - attributes: require('./attributes'), - supplyDefaults: require('./defaults'), - colorbar: require('../heatmap/colorbar'), - - calc: require('../heatmap/calc'), - plot: require('./convert'), - - moduleType: 'trace', - name: 'heatmapgl', - basePlotModule: require('../../plots/gl2d'), - categories: ['gl', 'gl2d', '2dMap'], - meta: { - description: [ - deprecationWarning, - 'WebGL version of the heatmap trace type.' - ].join(' ') - } -}; diff --git a/src/traces/pointcloud/attributes.js b/src/traces/pointcloud/attributes.js deleted file mode 100644 index f44593d918a..00000000000 --- a/src/traces/pointcloud/attributes.js +++ /dev/null @@ -1,138 +0,0 @@ -'use strict'; - -var scatterglAttrs = require('../scatter/attributes'); - -module.exports = { - x: scatterglAttrs.x, - y: scatterglAttrs.y, - xy: { - valType: 'data_array', - editType: 'calc', - description: [ - 'Faster alternative to specifying `x` and `y` separately.', - 'If supplied, it must be a typed `Float32Array` array that', - 'represents points such that `xy[i * 2] = x[i]` and `xy[i * 2 + 1] = y[i]`' - ].join(' ') - }, - indices: { - valType: 'data_array', - editType: 'calc', - description: [ - 'A sequential value, 0..n, supply it to avoid creating this array inside plotting.', - 'If specified, it must be a typed `Int32Array` array.', - 'Its length must be equal to or greater than the number of points.', - 'For the best performance and memory use, create one large `indices` typed array', - 'that is guaranteed to be at least as long as the largest number of points during', - 'use, and reuse it on each `Plotly.restyle()` call.' - ].join(' ') - }, - xbounds: { - valType: 'data_array', - editType: 'calc', - description: [ - 'Specify `xbounds` in the shape of `[xMin, xMax] to avoid looping through', - 'the `xy` typed array. Use it in conjunction with `xy` and `ybounds` for the performance benefits.' - ].join(' ') - }, - ybounds: { - valType: 'data_array', - editType: 'calc', - description: [ - 'Specify `ybounds` in the shape of `[yMin, yMax] to avoid looping through', - 'the `xy` typed array. Use it in conjunction with `xy` and `xbounds` for the performance benefits.' - ].join(' ') - }, - text: scatterglAttrs.text, - marker: { - color: { - valType: 'color', - arrayOk: false, - - editType: 'calc', - description: [ - 'Sets the marker fill color. It accepts a specific color.', - 'If the color is not fully opaque and there are hundreds of thousands', - 'of points, it may cause slower zooming and panning.' - ].join(' ') - }, - opacity: { - valType: 'number', - min: 0, - max: 1, - dflt: 1, - arrayOk: false, - - editType: 'calc', - description: [ - 'Sets the marker opacity. The default value is `1` (fully opaque).', - 'If the markers are not fully opaque and there are hundreds of thousands', - 'of points, it may cause slower zooming and panning.', - 'Opacity fades the color even if `blend` is left on `false` even if there', - 'is no translucency effect in that case.' - ].join(' ') - }, - blend: { - valType: 'boolean', - dflt: null, - - editType: 'calc', - description: [ - 'Determines if colors are blended together for a translucency effect', - 'in case `opacity` is specified as a value less then `1`.', - 'Setting `blend` to `true` reduces zoom/pan', - 'speed if used with large numbers of points.' - ].join(' ') - }, - sizemin: { - valType: 'number', - min: 0.1, - max: 2, - dflt: 0.5, - - editType: 'calc', - description: [ - 'Sets the minimum size (in px) of the rendered marker points, effective when', - 'the `pointcloud` shows a million or more points.' - ].join(' ') - }, - sizemax: { - valType: 'number', - min: 0.1, - dflt: 20, - - editType: 'calc', - description: [ - 'Sets the maximum size (in px) of the rendered marker points.', - 'Effective when the `pointcloud` shows only few points.' - ].join(' ') - }, - border: { - color: { - valType: 'color', - arrayOk: false, - - editType: 'calc', - description: [ - 'Sets the stroke color. It accepts a specific color.', - 'If the color is not fully opaque and there are hundreds of thousands', - 'of points, it may cause slower zooming and panning.' - ].join(' ') - }, - arearatio: { - valType: 'number', - min: 0, - max: 1, - dflt: 0, - - editType: 'calc', - description: [ - 'Specifies what fraction of the marker area is covered with the', - 'border.' - ].join(' ') - }, - editType: 'calc' - }, - editType: 'calc' - }, - transforms: undefined -}; diff --git a/src/traces/pointcloud/convert.js b/src/traces/pointcloud/convert.js deleted file mode 100644 index 3f1ebb942f0..00000000000 --- a/src/traces/pointcloud/convert.js +++ /dev/null @@ -1,193 +0,0 @@ -'use strict'; - -var createPointCloudRenderer = require('../../../stackgl_modules').gl_pointcloud2d; - -var isArrayOrTypedArray = require('../../lib').isArrayOrTypedArray; -var str2RGBArray = require('../../lib/str2rgbarray'); -var findExtremes = require('../../plots/cartesian/autorange').findExtremes; -var getTraceColor = require('../scatter/get_trace_color'); - -function Pointcloud(scene, uid) { - this.scene = scene; - this.uid = uid; - this.type = 'pointcloud'; - - this.pickXData = []; - this.pickYData = []; - this.xData = []; - this.yData = []; - this.textLabels = []; - this.color = 'rgb(0, 0, 0)'; - this.name = ''; - this.hoverinfo = 'all'; - - this.idToIndex = new Int32Array(0); - this.bounds = [0, 0, 0, 0]; - - this.pointcloudOptions = { - positions: new Float32Array(0), - idToIndex: this.idToIndex, - sizemin: 0.5, - sizemax: 12, - color: [0, 0, 0, 1], - areaRatio: 1, - borderColor: [0, 0, 0, 1] - }; - this.pointcloud = createPointCloudRenderer(scene.glplot, this.pointcloudOptions); - this.pointcloud._trace = this; // scene2d requires this prop -} - -var proto = Pointcloud.prototype; - -proto.handlePick = function(pickResult) { - var index = this.idToIndex[pickResult.pointId]; - - // prefer the readout from XY, if present - return { - trace: this, - dataCoord: pickResult.dataCoord, - traceCoord: this.pickXYData ? - [this.pickXYData[index * 2], this.pickXYData[index * 2 + 1]] : - [this.pickXData[index], this.pickYData[index]], - textLabel: isArrayOrTypedArray(this.textLabels) ? - this.textLabels[index] : - this.textLabels, - color: this.color, - name: this.name, - pointIndex: index, - hoverinfo: this.hoverinfo - }; -}; - -proto.update = function(options) { - this.index = options.index; - this.textLabels = options.text; - this.name = options.name; - this.hoverinfo = options.hoverinfo; - this.bounds = [Infinity, Infinity, -Infinity, -Infinity]; - - this.updateFast(options); - - this.color = getTraceColor(options, {}); -}; - -proto.updateFast = function(options) { - var x = this.xData = this.pickXData = options.x; - var y = this.yData = this.pickYData = options.y; - var xy = this.pickXYData = options.xy; - - var userBounds = options.xbounds && options.ybounds; - var index = options.indices; - - var len; - var idToIndex; - var positions; - var bounds = this.bounds; - - var xx, yy, i; - - if(xy) { - positions = xy; - - // dividing xy.length by 2 and truncating to integer if xy.length was not even - len = xy.length >>> 1; - - if(userBounds) { - bounds[0] = options.xbounds[0]; - bounds[2] = options.xbounds[1]; - bounds[1] = options.ybounds[0]; - bounds[3] = options.ybounds[1]; - } else { - for(i = 0; i < len; i++) { - xx = positions[i * 2]; - yy = positions[i * 2 + 1]; - - if(xx < bounds[0]) bounds[0] = xx; - if(xx > bounds[2]) bounds[2] = xx; - if(yy < bounds[1]) bounds[1] = yy; - if(yy > bounds[3]) bounds[3] = yy; - } - } - - if(index) { - idToIndex = index; - } else { - idToIndex = new Int32Array(len); - - for(i = 0; i < len; i++) { - idToIndex[i] = i; - } - } - } else { - len = x.length; - - positions = new Float32Array(2 * len); - idToIndex = new Int32Array(len); - - for(i = 0; i < len; i++) { - xx = x[i]; - yy = y[i]; - - idToIndex[i] = i; - - positions[i * 2] = xx; - positions[i * 2 + 1] = yy; - - if(xx < bounds[0]) bounds[0] = xx; - if(xx > bounds[2]) bounds[2] = xx; - if(yy < bounds[1]) bounds[1] = yy; - if(yy > bounds[3]) bounds[3] = yy; - } - } - - this.idToIndex = idToIndex; - this.pointcloudOptions.idToIndex = idToIndex; - - this.pointcloudOptions.positions = positions; - - var markerColor = str2RGBArray(options.marker.color); - var borderColor = str2RGBArray(options.marker.border.color); - var opacity = options.opacity * options.marker.opacity; - - markerColor[3] *= opacity; - this.pointcloudOptions.color = markerColor; - - // detect blending from the number of points, if undefined - // because large data with blending hits performance - var blend = options.marker.blend; - if(blend === null) { - var maxPoints = 100; - blend = x.length < maxPoints || y.length < maxPoints; - } - this.pointcloudOptions.blend = blend; - - borderColor[3] *= opacity; - this.pointcloudOptions.borderColor = borderColor; - - var markerSizeMin = options.marker.sizemin; - var markerSizeMax = Math.max(options.marker.sizemax, options.marker.sizemin); - this.pointcloudOptions.sizeMin = markerSizeMin; - this.pointcloudOptions.sizeMax = markerSizeMax; - this.pointcloudOptions.areaRatio = options.marker.border.arearatio; - - this.pointcloud.update(this.pointcloudOptions); - - // add item for autorange routine - var xa = this.scene.xaxis; - var ya = this.scene.yaxis; - var pad = markerSizeMax / 2 || 0.5; - options._extremes[xa._id] = findExtremes(xa, [bounds[0], bounds[2]], {ppad: pad}); - options._extremes[ya._id] = findExtremes(ya, [bounds[1], bounds[3]], {ppad: pad}); -}; - -proto.dispose = function() { - this.pointcloud.dispose(); -}; - -function createPointcloud(scene, data) { - var plot = new Pointcloud(scene, data.uid); - plot.update(data); - return plot; -} - -module.exports = createPointcloud; diff --git a/src/traces/pointcloud/defaults.js b/src/traces/pointcloud/defaults.js deleted file mode 100644 index 0fcd7a84cf9..00000000000 --- a/src/traces/pointcloud/defaults.js +++ /dev/null @@ -1,37 +0,0 @@ -'use strict'; - -var Lib = require('../../lib'); - -var attributes = require('./attributes'); - -module.exports = function supplyDefaults(traceIn, traceOut, defaultColor) { - function coerce(attr, dflt) { - return Lib.coerce(traceIn, traceOut, attributes, attr, dflt); - } - - coerce('x'); - coerce('y'); - - coerce('xbounds'); - coerce('ybounds'); - - if(traceIn.xy && traceIn.xy instanceof Float32Array) { - traceOut.xy = traceIn.xy; - } - - if(traceIn.indices && traceIn.indices instanceof Int32Array) { - traceOut.indices = traceIn.indices; - } - - coerce('text'); - coerce('marker.color', defaultColor); - coerce('marker.opacity'); - coerce('marker.blend'); - coerce('marker.sizemin'); - coerce('marker.sizemax'); - coerce('marker.border.color', defaultColor); - coerce('marker.border.arearatio'); - - // disable 1D transforms - that would defeat the purpose of this trace type, performance! - traceOut._length = null; -}; diff --git a/src/traces/pointcloud/index.js b/src/traces/pointcloud/index.js deleted file mode 100644 index 19b776a0d55..00000000000 --- a/src/traces/pointcloud/index.js +++ /dev/null @@ -1,27 +0,0 @@ -'use strict'; - -var deprecationWarning = [ - '*pointcloud* trace is deprecated!', - 'Please consider switching to the *scattergl* trace type.' -].join(' '); - -module.exports = { - attributes: require('./attributes'), - supplyDefaults: require('./defaults'), - - // reuse the Scatter3D 'dummy' calc step so that legends know what to do - calc: require('../scatter3d/calc'), - plot: require('./convert'), - - moduleType: 'trace', - name: 'pointcloud', - basePlotModule: require('../../plots/gl2d'), - categories: ['gl', 'gl2d', 'showLegend'], - meta: { - description: [ - deprecationWarning, - 'The data visualized as a point cloud set in `x` and `y`', - 'using the WebGl plotting engine.' - ].join(' ') - } -}; diff --git a/tasks/test_mock.mjs b/tasks/test_mock.mjs index 92153111437..bf8a1f9939d 100644 --- a/tasks/test_mock.mjs +++ b/tasks/test_mock.mjs @@ -169,7 +169,6 @@ function notBlackListed(name) { 'gl2d_fonts', 'gl2d_layout_image', 'gl2d_marker_coloraxis', - 'gl2d_pointcloud-basic', 'gl2d_rgb_dont_accept_alpha_scattergl', 'gl2d_scatter-marker-line-colorscales', 'gl2d_scatter-subplot-panel', diff --git a/tasks/util/constants.js b/tasks/util/constants.js index cc29bd49276..f58d36ce92e 100644 --- a/tasks/util/constants.js +++ b/tasks/util/constants.js @@ -87,9 +87,7 @@ var partialBundleTraces = { 'scattergeo' ], gl2d: [ - 'heatmapgl', 'parcoords', - 'pointcloud', 'scatter', 'scattergl', 'splom' @@ -125,7 +123,6 @@ var partialBundleTraces = { 'funnel', 'funnelarea', 'heatmap', - 'heatmapgl', 'histogram', 'histogram2d', 'histogram2dcontour', @@ -138,7 +135,6 @@ var partialBundleTraces = { 'parcats', 'parcoords', 'pie', - 'pointcloud', 'sankey', 'scatter', 'scattergl', diff --git a/test/image/baselines/gl2d_heatmapgl.png b/test/image/baselines/gl2d_heatmapgl.png deleted file mode 100644 index c97da230e396e1f4cfc2cd295ce3a684e7f0d54a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 62871 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

AaQhlkau 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 R0!9KJFc}r;N=cK@{{_vp!D9db diff --git a/test/image/baselines/gl2d_heatmapgl_discrete.png b/test/image/baselines/gl2d_heatmapgl_discrete.png deleted file mode 100644 index a767ae4c14bc21fed7cb5aeff62ed8989864fcdb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19910 zcmeHvS3nb6_q|~60s=NV1ZiSGKsq9bfe1?PVCenQO9bo?P!JG^R7IpWX`y2YV5o}p zD!sSR`|nKfs^9&%5C6CS!^eY#OwOE{*=O&y*IH*Vw-x1%A31kq&z?QU5jSO&_v|5u z?b$>2>Cgf2o6dQ1r9FEX_aJ1hsk-S;MIUyf9xANrrOMADq$t0;wD?ey3pK>4U9tbo zP5=8xWmzx1z8EQ*-sC_Lu8^7cnvwCMJekJD)VTZ1)jb{L+FXo>vcH_WdH=XL&wSRtXGl^8KD_Kzhs0p{e2ku8>ai%$1v(+`~IE~ z{_(k=he@`BYy86pf6wne_V(Vt2YLK-4~jBE_428|uk93-<<3Pi?s@R_loV1r z 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%0Ab+f8BMsKF~#Hf+6p%5p(QmrW0UjQG&e65fgru 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 W5-a-FH1u!Yp{c5)l6CplNB;*V)Vcfs diff --git a/test/image/make_baseline.py b/test/image/make_baseline.py index 3782a48d2a0..8c260fb658a 100644 --- a/test/image/make_baseline.py +++ b/test/image/make_baseline.py @@ -67,32 +67,6 @@ else : allNames = ALL_MOCKS -# gl2d pointcloud and other non-regl gl2d mock(s) -# must be tested in certain order to work on CircleCI; -# -# gl-shader appears to conflict with regl. -# We suspect that the lone gl context on CircleCI is -# having issues with dealing with the two different -# program binding algorithm. -# -# The problem will be solved by switching all our -# WebGL-based trace types to regl. -# -# More info here: -# https://github.com/plotly/plotly.js/pull/1037 - -LAST = [ - 'gl2d_pointcloud-basic', - 'gl2d_heatmapgl', - 'gl2d_heatmapgl_discrete' -] - -HAD = [item in allNames for item in LAST] - -allNames = [a for a in allNames if a not in LAST] - -allNames += [item for item, had_item in zip(LAST, HAD) if had_item] - # unable to generate baselines for the following mocks blacklist = [ 'map_stamen-style', diff --git a/test/image/mocks/gl2d_heatmapgl.json b/test/image/mocks/gl2d_heatmapgl.json deleted file mode 100644 index ecb95125b69..00000000000 --- a/test/image/mocks/gl2d_heatmapgl.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "data": [ - { - "type": "heatmapgl", - "z": [ - [125, 106, 89, 74, 61, 50, 41, 34, 29, 26], - [116, 97, 80, 65, 52, 41, 32, 25, 20, 17], - [109, 90, 73, 58, 45, 34, 25, 18, 13, 10], - [104, 85, 68, 53, 40, 29, 20, 13, 8, 5], - [101, 82, 65, 50, 37, 26, 17, 10, 5, 2], - [100, 81, 64, 49, 36, 25, 16, 9, 4, 1], - [101, 82, 65, 50, 37, 26, 17, 10, 5, 2], - [104, 85, 68, 53, 40, 29, 20, 13, 8, 5], - [109, 90, 73, 58, 45, 34, 25, 18, 13, 10], - [116, 97, 80, 65, 52, 41, 32, 25, 20, 17] - ], - "colorscale": "Viridis" - } - ], - "layout": { - "font": { - "weight": "bold", - "style": "italic", - "variant": "small-caps" - }, - "height": 450, - "width": 550 - } -} diff --git a/test/image/mocks/gl2d_heatmapgl_discrete.json b/test/image/mocks/gl2d_heatmapgl_discrete.json deleted file mode 100644 index f88b1cdbf4a..00000000000 --- a/test/image/mocks/gl2d_heatmapgl_discrete.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "data": [ - { - "type": "heatmapgl", - "zsmooth": false, - "z": [ - [125, 106, 89, 74, 61, 50, 41, 34, 29, 26], - [116, 97, 80, 65, 52, 41, 32, 25, 20, 17], - [109, 90, 73, 58, 45, 34, 25, 18, 13, 10], - [104, 85, 68, 53, 40, 29, 20, 13, 8, 5], - [101, 82, 65, 50, 37, 26, 17, 10, 5, 2], - [100, 81, 64, 49, 36, 25, 16, 9, 4, 1], - [101, 82, 65, 50, 37, 26, 17, 10, 5, 2], - [104, 85, 68, 53, 40, 29, 20, 13, 8, 5], - [109, 90, 73, 58, 45, 34, 25, 18, 13, 10], - [116, 97, 80, 65, 52, 41, 32, 25, 20, 17] - ], - "colorscale": "Viridis" - } - ], - "layout": { - "font": { - "weight": 700, - "style": "italic", - "variant": "small-caps" - }, - "height": 450, - "width": 550 - } -} diff --git a/test/image/mocks/gl2d_pointcloud-basic.json b/test/image/mocks/gl2d_pointcloud-basic.json deleted file mode 100644 index 95b004528d2..00000000000 --- a/test/image/mocks/gl2d_pointcloud-basic.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "data": [ - { - "type": "pointcloud", - "mode": "markers", - "marker": { - "sizemin": 0.5, - "sizemax": 100, - "arearatio": 0, - "color": "rgba(255, 0, 0, 0.6)" - }, - "x": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], - "y": [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] - }, - { - "type": "pointcloud", - "mode": "markers", - "marker": { - "sizemin": 0.5, - "sizemax": 100, - "arearatio": 0, - "color": "rgba(0, 0, 255, 0.9)", - "opacity": 0.8, - "blend": true - }, - "opacity": 0.7, - "x": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9], - "y": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] - }, - { - "type": "pointcloud", - "mode": "markers", - "marker": { - "sizemin": 0.5, - "sizemax": 100, - "border": { - "color": "rgb(0, 0, 0)", - "arearatio": 0.7071 - }, - "color": "green", - "opacity": 0.8, - "blend": true - }, - "opacity": 0.7, - "x": [3, 4.5, 6], - "y": [9, 9, 9] - } - ], - "layout": { - "title": { "text": "Point Cloud - basic" }, - "xaxis": { - "type": "linear", - "range": [-2.501411175139456, 43.340777299865266], - "autorange": true - }, - "yaxis": { - "type": "linear", - "range": [4, 6], - "autorange": true - }, - "height": 598, - "width": 1080, - "autosize": true, - "showlegend": false - } -} diff --git a/test/jasmine/assets/mock_lists.js b/test/jasmine/assets/mock_lists.js index 27a09b99770..fc6e76c3346 100644 --- a/test/jasmine/assets/mock_lists.js +++ b/test/jasmine/assets/mock_lists.js @@ -57,10 +57,8 @@ var svgMockList = [ ]; var glMockList = [ - ['gl2d_heatmapgl', require('../../image/mocks/gl2d_heatmapgl.json')], ['gl2d_line_dash', require('../../image/mocks/gl2d_line_dash.json')], ['gl2d_parcoords_2', require('../../image/mocks/gl2d_parcoords_2.json')], - ['gl2d_pointcloud-basic', require('../../image/mocks/gl2d_pointcloud-basic.json')], ['gl3d_annotations', require('../../image/mocks/gl3d_annotations.json')], ['gl3d_set-ranges', require('../../image/mocks/gl3d_set-ranges.json')], ['gl3d_world-cals', require('../../image/mocks/gl3d_world-cals.json')], diff --git a/test/jasmine/bundle_tests/no_webgl_test.js b/test/jasmine/bundle_tests/no_webgl_test.js index a76ea25fec8..88d599b4142 100644 --- a/test/jasmine/bundle_tests/no_webgl_test.js +++ b/test/jasmine/bundle_tests/no_webgl_test.js @@ -37,18 +37,6 @@ describe('Plotly w/o WebGL support:', function() { .then(done, done.fail); }); - it('gl2d subplots', function(done) { - Plotly.react(gd, require('../../image/mocks/gl2d_pointcloud-basic.json')) - .then(function() { - checkNoWebGLMsg(true); - return Plotly.react(gd, require('../../image/mocks/10.json')); - }) - .then(function() { - checkNoWebGLMsg(false); - }) - .then(done, done.fail); - }); - it('scattergl subplots', function(done) { Plotly.react(gd, require('../../image/mocks/gl2d_12.json')) .then(function() { diff --git a/test/jasmine/bundle_tests/plotschema_test.js b/test/jasmine/bundle_tests/plotschema_test.js index 82afaf4cd54..7ce54c5771c 100644 --- a/test/jasmine/bundle_tests/plotschema_test.js +++ b/test/jasmine/bundle_tests/plotschema_test.js @@ -578,33 +578,6 @@ describe('getLayoutValObject', function() { expect(getLayoutValObject(layout3D, ['scene1', 'bgcolor'])).toBe(false); expect(getLayoutValObject(layout3D, ['scene2k', 'bgcolor'])).toBe(false); }); - - it('lets gl2d override cartesian & global attrs', function() { - var svgModule = Registry.subplotsRegistry.cartesian; - var gl2dModule = Registry.subplotsRegistry.gl2d; - var layoutSVG = {_basePlotModules: [svgModule]}; - var layoutGL2D = {_basePlotModules: [gl2dModule]}; - var combinedLayout1 = {_basePlotModules: [svgModule, gl2dModule]}; - var combinedLayout2 = {_basePlotModules: [gl2dModule, svgModule]}; - - var bgParts = ['plot_bgcolor']; - var baseBG = baseLayoutAttrs.plot_bgcolor; - var gl2dBG = gl2dModule.baseLayoutAttrOverrides.plot_bgcolor; - expect(getLayoutValObject(blankLayout, bgParts)).toBe(baseBG); - expect(getLayoutValObject(layoutSVG, bgParts)).toBe(baseBG); - expect(getLayoutValObject(layoutGL2D, bgParts)).toBe(gl2dBG); - expect(getLayoutValObject(combinedLayout1, bgParts)).toBe(gl2dBG); - expect(getLayoutValObject(combinedLayout2, bgParts)).toBe(gl2dBG); - - var ticklenParts = ['xaxis4', 'ticklen']; - var svgTicklen = svgModule.layoutAttributes.ticklen; - var gl2dTicklen = gl2dModule.layoutAttrOverrides.ticklen; - expect(getLayoutValObject(blankLayout, ticklenParts)).toBe(false); - expect(getLayoutValObject(layoutSVG, ticklenParts)).toBe(svgTicklen); - expect(getLayoutValObject(layoutGL2D, ticklenParts)).toBe(gl2dTicklen); - expect(getLayoutValObject(combinedLayout1, ticklenParts)).toBe(gl2dTicklen); - expect(getLayoutValObject(combinedLayout2, ticklenParts)).toBe(gl2dTicklen); - }); }); describe('component schemas', function() { diff --git a/test/jasmine/tests/gl2d_click_test.js b/test/jasmine/tests/gl2d_click_test.js index e724cad09fe..18f76a098f5 100644 --- a/test/jasmine/tests/gl2d_click_test.js +++ b/test/jasmine/tests/gl2d_click_test.js @@ -387,33 +387,6 @@ describe('Test hover and click interactions', function() { .then(done, done.fail); }); - it('@gl should output correct event data for pointcloud', function(done) { - var _mock = Lib.extendDeep({}, require('../../image/mocks/gl2d_pointcloud-basic.json')); - - _mock.layout.hoverlabel = { font: {size: 8} }; - _mock.data[2].hoverlabel = { - bgcolor: ['red', 'green', 'blue'] - }; - - var run = makeRunner([540, 150], { - x: 4.5, - y: 9, - curveNumber: 2, - pointNumber: 1, - bgcolor: 'rgb(0, 128, 0)', - bordercolor: 'rgb(255, 255, 255)', - fontSize: 8, - fontFamily: 'Arial', - fontColor: 'rgb(255, 255, 255)' - }, { - msg: 'pointcloud' - }); - - Plotly.newPlot(gd, _mock) - .then(run) - .then(done, done.fail); - }); - it('@gl scattergl should propagate marker colors to hover labels', function(done) { var _mock = Lib.extendDeep({}, mock0); _mock.layout.hovermode = 'x'; @@ -439,86 +412,6 @@ describe('Test hover and click interactions', function() { .then(done, done.fail); }); - it('@gl should output correct event data for heatmapgl', function(done) { - var z = [ - [10, 10.625, 12.5, 15.625, 20], - [5.625, 6.25, 8.125, 11.25, 15.625], - [2.5, 3.125, 5, 8.125, 12.5], - [0.625, 1.25, 3.125, 20, 10.625], - [0, 0.625, 2.5, 5.625, 10] - ]; - - var _mock = { - data: [{ - type: 'heatmapgl', - z: z, - hoverlabel: { - font: { size: z } - }, - colorscale: 'Jet', - // contours: { start: 2, end: 10, size: 1 }, - zmin: 0, - zmax: 20 - }], - layout: { - hoverlabel: { - font: { family: 'Roboto' } - } - } - }; - - var run = makeRunner([540, 150], { - x: 3, - y: 3, - curveNumber: 0, - pointNumber: [3, 3], - bgcolor: 'rgb(68, 68, 68)', - bordercolor: 'rgb(255, 255, 255)', - fontSize: 20, - fontFamily: 'Roboto', - fontColor: 'rgb(255, 255, 255)' - }, { - noUnHover: true, - msg: 'heatmapgl' - }); - - Plotly.newPlot(gd, _mock) - .then(run) - .then(done, done.fail); - }); - - it('@gl should output correct event data for heatmapgl (asymmetric case) ', function(done) { - var _mock = { - data: [{ - type: 'heatmapgl', - z: [[1, 2, 0], [2, 3, 1]], - text: [['a', 'b', 'c'], ['D', 'E', 'F']], - hoverlabel: { - bgcolor: [['red', 'blue', 'green'], ['cyan', 'pink', 'black']] - } - }] - }; - - var run = makeRunner([540, 150], { - x: 2, - y: 1, - curveNumber: 0, - pointNumber: [1, 2], - bgcolor: 'rgb(0, 0, 0)', - bordercolor: 'rgb(255, 255, 255)', - fontSize: 13, - fontFamily: 'Arial', - fontColor: 'rgb(255, 255, 255)' - }, { - noUnHover: true, - msg: 'heatmapgl' - }); - - Plotly.newPlot(gd, _mock) - .then(run) - .then(done, done.fail); - }); - it('@gl should output correct event data for scattergl after visibility restyle', function(done) { var _mock = Lib.extendDeep({}, mock2); diff --git a/test/jasmine/tests/heatmap_test.js b/test/jasmine/tests/heatmap_test.js index 1f85965cdbd..ceb527f4132 100644 --- a/test/jasmine/tests/heatmap_test.js +++ b/test/jasmine/tests/heatmap_test.js @@ -528,7 +528,7 @@ describe('heatmap calc', function() { expect(out.z).toBeCloseTo2DArray([[1, 2, 3], [3, 1, 2]]); }); - ['heatmap', 'heatmapgl'].forEach(function(traceType) { + ['heatmap'].forEach(function(traceType) { it('should sort z data based on axis categoryorder for ' + traceType, function() { var mock = require('../../image/mocks/heatmap_categoryorder'); var mockCopy = Lib.extendDeep({}, mock); diff --git a/test/jasmine/tests/heatmapgl_test.js b/test/jasmine/tests/heatmapgl_test.js deleted file mode 100644 index 2c35bdedb5e..00000000000 --- a/test/jasmine/tests/heatmapgl_test.js +++ /dev/null @@ -1,131 +0,0 @@ -var supplyDefaults = require('../../../src/traces/heatmapgl').supplyDefaults; -var Plots = require('../../../src/plots/plots'); -var Plotly = require('../../../lib/index'); -var schema = Plotly.PlotSchema.get(); -var attributeList = Object.getOwnPropertyNames(schema.traces.heatmapgl.attributes); - -var createGraphDiv = require('../assets/create_graph_div'); -var destroyGraphDiv = require('../assets/destroy_graph_div'); - -describe('heatmapgl supplyDefaults', function() { - 'use strict'; - - var traceIn; - var traceOut; - - var defaultColor = '#444'; - var layout = { - font: Plots.layoutAttributes.font, - _dfltTitle: {colorbar: 'cb'}, - _subplots: {cartesian: ['xy'], xaxis: ['x'], yaxis: ['y']} - }; - - beforeEach(function() { - traceOut = {}; - }); - - it('should set visible to false when z is empty', function() { - traceIn = { - z: [] - }; - supplyDefaults(traceIn, traceOut, defaultColor, layout); - expect(traceOut.visible).toBe(false); - - traceIn = { - z: [[]] - }; - supplyDefaults(traceIn, traceOut, defaultColor, layout); - expect(traceOut.visible).toBe(false); - - traceIn = { - z: [[], [], []] - }; - supplyDefaults(traceIn, traceOut, defaultColor, layout); - expect(traceOut.visible).toBe(false); - - traceIn = { - type: 'heatmapgl', - z: [[1, 2], []] - }; - supplyDefaults(traceIn, traceOut, defaultColor, layout); - expect(traceOut.visible).toBe(false); - - traceIn = { - type: 'heatmapgl', - z: [[], [1, 2], [1, 2, 3]] - }; - supplyDefaults(traceIn, traceOut, defaultColor, layout); - expect(traceOut.visible).toBe(false); - }); - - it('should set visible to false when z is non-numeric', function() { - traceIn = { - type: 'heatmapgl', - z: [['a', 'b'], ['c', 'd']] - }; - supplyDefaults(traceIn, traceOut, defaultColor, layout); - expect(traceOut.visible).toBe(false); - }); - - it('should set visible to false when z isn\'t column not a 2d array', function() { - traceIn = { - x: [1, 1, 1, 2, 2], - y: [1, 2, 3, 1, 2], - z: [1, ['this is considered a column'], 1, 2, 3] - }; - supplyDefaults(traceIn, traceOut, defaultColor, layout); - expect(traceOut.visible).not.toBe(false); - - traceIn = { - x: [1, 1, 1, 2, 2], - y: [1, 2, 3, 1, 2], - z: [[0], ['this is not considered a column'], 1, ['nor 2d']] - }; - supplyDefaults(traceIn, traceOut, defaultColor, layout); - expect(traceOut.visible).toBe(false); - }); - - it('should only coerce attributes that are part of scheme', function() { - traceIn = { - type: 'heatmapgl', - z: [[0, 1], [1, 0]] - }; - - supplyDefaults(traceIn, traceOut, defaultColor, layout); - var allKeys = Object.getOwnPropertyNames(traceOut); - allKeys.forEach(function(key) { - if(key[0] !== '_') { - expect(attributeList.indexOf(key)).not.toBe(-1, key); - } - }); - }); -}); - -describe('heatmapgl plotting', function() { - var gd; - - beforeEach(function() { - gd = createGraphDiv(); - }); - - afterEach(destroyGraphDiv); - - it('can do scaleanchor', function(done) { - var data = [{ - z: [[1, 2, 3], [4, 5, 6], [7, 8, 9]], - type: 'heatmapgl', - showscale: false - }]; - var layout = { - xaxis: {scaleanchor: 'y'}, - width: 500, - height: 300, - margin: {l: 50, r: 50, t: 50, b: 50} - }; - Plotly.newPlot(gd, data, layout) - .then(function() { - expect(layout.xaxis.range).toBeCloseToArray([-1, 3], 3); - }) - .then(done, done.fail); - }); -}); diff --git a/test/jasmine/tests/modebar_test.js b/test/jasmine/tests/modebar_test.js index deb96e5ab9d..e3e5a8ef97e 100644 --- a/test/jasmine/tests/modebar_test.js +++ b/test/jasmine/tests/modebar_test.js @@ -553,24 +553,6 @@ describe('ModeBar', function() { checkButtons(modeBar, buttons, 1); }); - it('creates mode bar (gl2d version)', function() { - var buttons = getButtons([ - ['toImage'], - ['zoom2d', 'pan2d'], - ['zoomIn2d', 'zoomOut2d', 'autoScale2d', 'resetScale2d'] - ]); - - var gd = getMockGraphInfo(['x'], ['y']); - gd._fullLayout._basePlotModules = [{ name: 'gl2d' }]; - gd._fullLayout.xaxis = {fixedrange: false}; - gd._fullData = [{type: 'scattergl'}]; - - manageModeBar(gd); - var modeBar = gd._fullLayout._modeBar; - - checkButtons(modeBar, buttons, 1); - }); - it('creates mode bar (pie version)', function() { var buttons = getButtons([ ['toImage'] diff --git a/test/jasmine/tests/pointcloud_test.js b/test/jasmine/tests/pointcloud_test.js deleted file mode 100644 index 7018629f915..00000000000 --- a/test/jasmine/tests/pointcloud_test.js +++ /dev/null @@ -1,255 +0,0 @@ -'use strict'; - -var Plotly = require('../../../lib/index'); -var Lib = require('../../../src/lib'); -var d3Select = require('../../strict-d3').select; - -// Test utilities -var createGraphDiv = require('../assets/create_graph_div'); -var destroyGraphDiv = require('../assets/destroy_graph_div'); - -var delay = require('../assets/delay'); -var mouseEvent = require('../assets/mouse_event'); -var readPixel = require('../assets/read_pixel'); - -var multipleScatter2dMock = require('../../image/mocks/gl2d_scatter2d-multiple-colors.json'); - -var plotData = { - data: [ - { - type: 'pointcloud', - mode: 'markers', - marker: { - sizemin: 0.5, - sizemax: 100, - arearatio: 0, - color: 'rgba(255, 0, 0, 0.6)' - }, - x: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], - y: [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] - }, - { - type: 'pointcloud', - mode: 'markers', - marker: { - sizemin: 0.5, - sizemax: 100, - arearatio: 0, - color: 'rgba(0, 0, 255, 0.9)', - opacity: 0.8, - blend: true - }, - opacity: 0.7, - x: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9], - y: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] - }, - { - type: 'pointcloud', - mode: 'markers', - marker: { - sizemin: 0.5, - sizemax: 100, - border: { - color: 'rgb(0, 0, 0)', - arearatio: 0.7071 - }, - color: 'green', - opacity: 0.8, - blend: true - }, - opacity: 0.7, - x: [3, 4.5, 6], - y: [9, 9, 9] - }, - { - type: 'pointcloud', - mode: 'markers', - marker: { - sizemin: 0.5, - sizemax: 100, - color: 'yellow', - opacity: 0.8, - blend: true - }, - opacity: 0.7, - xy: new Float32Array([1, 3, 9, 3]), - indices: new Int32Array([0, 1]), - xbounds: [1, 9], - ybounds: [3, 3] - }, - { - type: 'pointcloud', - mode: 'markers', - marker: { - sizemin: 0.5, - sizemax: 100, - color: 'orange', - opacity: 0.8, - blend: true - }, - opacity: 0.7, - xy: new Float32Array([1, 4, 9, 4]), - indices: new Int32Array([0, 1]) - }, - { - type: 'pointcloud', - mode: 'markers', - marker: { - sizemin: 0.5, - sizemax: 100, - color: 'darkorange', - opacity: 0.8, - blend: true - }, - opacity: 0.7, - xy: new Float32Array([1, 5, 9, 5]), - xbounds: [1, 9], - ybounds: [5, 5] - }, - { - type: 'pointcloud', - mode: 'markers', - marker: { - sizemin: 0.5, - sizemax: 100, - color: 'red', - opacity: 0.8, - blend: true - }, - opacity: 0.7, - xy: new Float32Array([1, 6, 9, 6]) - } - ], - layout: { - title: 'Point Cloud - basic', - xaxis: { - type: 'linear', - range: [ - -2.501411175139456, - 43.340777299865266 - ], - autorange: true - }, - yaxis: { - type: 'linear', - range: [ - 4, - 6 - ], - autorange: true - }, - height: 598, - width: 1080, - autosize: true, - showlegend: false - } -}; - -describe('pointcloud traces', function() { - var gd; - - beforeEach(function() { - gd = createGraphDiv(); - }); - - afterEach(function() { - Plotly.purge(gd); - destroyGraphDiv(); - }); - - it('@gl renders without raising an error', function(done) { - Plotly.newPlot(gd, Lib.extendDeep({}, plotData)) - .then(done, done.fail); - }); - - it('@gl should update properly', function(done) { - var scene2d; - - Plotly.newPlot(gd, Lib.extendDeep({}, plotData)) - .then(function() { - scene2d = gd._fullLayout._plots.xy._scene2d; - expect(scene2d.traces[gd._fullData[0].uid].type).toBe('pointcloud'); - - return Plotly.relayout(gd, 'xaxis.range', [3, 6]); - }).then(function() { - expect(scene2d.xaxis.range).toEqual([3, 6]); - expect(scene2d.yaxis.range).toBeCloseToArray([-1.415, 10.415], 2); - return Plotly.relayout(gd, 'xaxis.autorange', true); - }).then(function() { - expect(scene2d.xaxis.range).toBeCloseToArray([-0.548, 9.548], 2); - expect(scene2d.yaxis.range).toBeCloseToArray([-1.415, 10.415], 2); - return Plotly.relayout(gd, 'yaxis.range', [8, 20]); - }).then(function() { - expect(scene2d.xaxis.range).toBeCloseToArray([-0.548, 9.548], 2); - expect(scene2d.yaxis.range).toEqual([8, 20]); - return Plotly.relayout(gd, 'yaxis.autorange', true); - }).then(function() { - expect(scene2d.xaxis.range).toBeCloseToArray([-0.548, 9.548], 2); - expect(scene2d.yaxis.range).toBeCloseToArray([-1.415, 10.415], 2); - }) - .then(done, done.fail); - }); - - it('@gl should not change other traces colors', function(done) { - var _mock = Lib.extendDeep({}, multipleScatter2dMock); - Plotly.newPlot(gd, _mock) - .then(delay(20)) - .then(function() { - var canvas = d3Select('.gl-canvas-context').node(); - - var RGBA = readPixel(canvas, canvas.width / 2 - 1, canvas.height / 2 - 1, 1, 1); - - expect(RGBA[0] === 255).toBe(true, 'be red'); - expect(RGBA[1] === 0).toBe(true, 'no green'); - expect(RGBA[2] === 0).toBe(true, 'no blue'); - expect(RGBA[3] === 255).toBe(true, 'no transparent'); - }) - .then(done, done.fail); - }); - - it('@gl should respond to drag', function(done) { - function _drag(p0, p1) { - mouseEvent('mousemove', p0[0], p0[1], {buttons: 1}); - mouseEvent('mousedown', p0[0], p0[1], {buttons: 1}); - mouseEvent('mousemove', (p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2, {buttons: 1}); - mouseEvent('mousemove', p1[0], p1[1], {buttons: 0}); - mouseEvent('mouseup', p1[0], p1[1], {buttons: 0}); - } - - function _assertRange(msg, xrng, yrng) { - expect(gd._fullLayout.xaxis.range).toBeCloseToArray(xrng, 2, msg); - expect(gd._fullLayout.yaxis.range).toBeCloseToArray(yrng, 2, msg); - } - - Plotly.newPlot(gd, Lib.extendDeep({}, plotData)) - .then(delay(20)) - .then(function() { - _assertRange('base', [-0.548, 9.548], [-1.415, 10.415]); - }) - .then(delay(20)) - .then(function() { _drag([200, 200], [350, 350]); }) - .then(delay(20)) - .then(function() { - _assertRange('after zoombox drag', [0.768, 1.591], [5.462, 7.584]); - }) - .then(function() { - return Plotly.relayout(gd, { - 'xaxis.autorange': true, - 'yaxis.autorange': true - }); - }) - .then(function() { - _assertRange('back to base', [-0.548, 9.548], [-1.415, 10.415]); - }) - .then(function() { - return Plotly.relayout(gd, 'dragmode', 'pan'); - }) - .then(delay(20)) - .then(function() { _drag([200, 200], [350, 350]); }) - .then(delay(20)) - .then(function() { - _assertRange('after pan drag', [0.2743, 10.3719], [-3.537, 8.292]); - }) - .then(done, done.fail); - }); -}); diff --git a/test/plot-schema.json b/test/plot-schema.json index b2f43d0245d..e19c404a3cf 100644 --- a/test/plot-schema.json +++ b/test/plot-schema.json @@ -42341,1362 +42341,6 @@ }, "type": "heatmap" }, - "heatmapgl": { - "animatable": false, - "attributes": { - "autocolorscale": { - "description": "Determines whether the colorscale is a default palette (`autocolorscale: true`) or the palette determined by `colorscale`. In case `colorscale` is unspecified or `autocolorscale` is true, the default palette will be chosen according to whether numbers in the `color` array are all positive, all negative or mixed.", - "dflt": false, - "editType": "calc", - "impliedEdits": {}, - "valType": "boolean" - }, - "coloraxis": { - "description": "Sets a reference to a shared color axis. References to these shared color axes are *coloraxis*, *coloraxis2*, *coloraxis3*, etc. Settings for these shared color axes are set in the layout, under `layout.coloraxis`, `layout.coloraxis2`, etc. Note that multiple color scales can be linked to the same color axis.", - "dflt": null, - "editType": "calc", - "regex": "/^coloraxis([2-9]|[1-9][0-9]+)?$/", - "valType": "subplotid" - }, - "colorbar": { - "_deprecated": { - "title": { - "description": "Deprecated in favor of color bar's `title.text`. Note that value of color bar's `title` is no longer a simple *string* but a set of sub-attributes.", - "editType": "calc", - "valType": "string" - }, - "titlefont": { - "color": { - "editType": "calc", - "valType": "color" - }, - "description": "Deprecated in favor of color bar's `title.font`.", - "editType": "calc", - "family": { - "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The Chart Studio Cloud (at https://chart-studio.plotly.com or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", - "editType": "calc", - "noBlank": true, - "strict": true, - "valType": "string" - }, - "lineposition": { - "description": "Sets the kind of decoration line(s) with text, such as an *under*, *over* or *through* as well as combinations e.g. *under+over*, etc.", - "dflt": "none", - "editType": "calc", - "extras": [ - "none" - ], - "flags": [ - "under", - "over", - "through" - ], - "valType": "flaglist" - }, - "shadow": { - "description": "Sets the shape and color of the shadow behind text. *auto* places minimal shadow and applies contrast text font color. See https://developer.mozilla.org/en-US/docs/Web/CSS/text-shadow for additional options.", - "dflt": "none", - "editType": "calc", - "valType": "string" - }, - "size": { - "editType": "calc", - "min": 1, - "valType": "number" - }, - "style": { - "description": "Sets whether a font should be styled with a normal or italic face from its family.", - "dflt": "normal", - "editType": "calc", - "valType": "enumerated", - "values": [ - "normal", - "italic" - ] - }, - "textcase": { - "description": "Sets capitalization of text. It can be used to make text appear in all-uppercase or all-lowercase, or with each word capitalized.", - "dflt": "normal", - "editType": "calc", - "valType": "enumerated", - "values": [ - "normal", - "word caps", - "upper", - "lower" - ] - }, - "variant": { - "description": "Sets the variant of the font.", - "dflt": "normal", - "editType": "calc", - "valType": "enumerated", - "values": [ - "normal", - "small-caps", - "all-small-caps", - "all-petite-caps", - "petite-caps", - "unicase" - ] - }, - "weight": { - "description": "Sets the weight (or boldness) of the font.", - "dflt": "normal", - "editType": "calc", - "extras": [ - "normal", - "bold" - ], - "max": 1000, - "min": 1, - "valType": "integer" - } - }, - "titleside": { - "description": "Deprecated in favor of color bar's `title.side`.", - "dflt": "top", - "editType": "calc", - "valType": "enumerated", - "values": [ - "right", - "top", - "bottom" - ] - } - }, - "bgcolor": { - "description": "Sets the color of padded area.", - "dflt": "rgba(0,0,0,0)", - "editType": "calc", - "valType": "color" - }, - "bordercolor": { - "description": "Sets the axis line color.", - "dflt": "#444", - "editType": "calc", - "valType": "color" - }, - "borderwidth": { - "description": "Sets the width (in px) or the border enclosing this color bar.", - "dflt": 0, - "editType": "calc", - "min": 0, - "valType": "number" - }, - "dtick": { - "description": "Sets the step in-between ticks on this axis. Use with `tick0`. Must be a positive number, or special strings available to *log* and *date* axes. If the axis `type` is *log*, then ticks are set every 10^(n*dtick) where n is the tick number. For example, to set a tick mark at 1, 10, 100, 1000, ... set dtick to 1. To set tick marks at 1, 100, 10000, ... set dtick to 2. To set tick marks at 1, 5, 25, 125, 625, 3125, ... set dtick to log_10(5), or 0.69897000433. *log* has several special values; *L*, where `f` is a positive number, gives ticks linearly spaced in value (but not position). For example `tick0` = 0.1, `dtick` = *L0.5* will put ticks at 0.1, 0.6, 1.1, 1.6 etc. To show powers of 10 plus small digits between, use *D1* (all digits) or *D2* (only 2 and 5). `tick0` is ignored for *D1* and *D2*. If the axis `type` is *date*, then you must convert the time to milliseconds. For example, to set the interval between ticks to one day, set `dtick` to 86400000.0. *date* also has special values *M* gives ticks spaced by a number of months. `n` must be a positive integer. To set ticks on the 15th of every third month, set `tick0` to *2000-01-15* and `dtick` to *M3*. To set ticks every 4 years, set `dtick` to *M48*", - "editType": "calc", - "impliedEdits": { - "tickmode": "linear" - }, - "valType": "any" - }, - "editType": "calc", - "exponentformat": { - "description": "Determines a formatting rule for the tick exponents. For example, consider the number 1,000,000,000. If *none*, it appears as 1,000,000,000. If *e*, 1e+9. If *E*, 1E+9. If *power*, 1x10^9 (with 9 in a super script). If *SI*, 1G. If *B*, 1B.", - "dflt": "B", - "editType": "calc", - "valType": "enumerated", - "values": [ - "none", - "e", - "E", - "power", - "SI", - "B" - ] - }, - "labelalias": { - "description": "Replacement text for specific tick or hover labels. For example using {US: 'USA', CA: 'Canada'} changes US to USA and CA to Canada. The labels we would have shown must match the keys exactly, after adding any tickprefix or ticksuffix. For negative numbers the minus sign symbol used (U+2212) is wider than the regular ascii dash. That means you need to use −1 instead of -1. labelalias can be used with any axis type, and both keys (if needed) and values (if desired) can include html-like tags or MathJax.", - "dflt": false, - "editType": "calc", - "valType": "any" - }, - "len": { - "description": "Sets the length of the color bar This measure excludes the padding of both ends. That is, the color bar length is this length minus the padding on both ends.", - "dflt": 1, - "editType": "calc", - "min": 0, - "valType": "number" - }, - "lenmode": { - "description": "Determines whether this color bar's length (i.e. the measure in the color variation direction) is set in units of plot *fraction* or in *pixels. Use `len` to set the value.", - "dflt": "fraction", - "editType": "calc", - "valType": "enumerated", - "values": [ - "fraction", - "pixels" - ] - }, - "minexponent": { - "description": "Hide SI prefix for 10^n if |n| is below this number. This only has an effect when `tickformat` is *SI* or *B*.", - "dflt": 3, - "editType": "calc", - "min": 0, - "valType": "number" - }, - "nticks": { - "description": "Specifies the maximum number of ticks for the particular axis. The actual number of ticks will be chosen automatically to be less than or equal to `nticks`. Has an effect only if `tickmode` is set to *auto*.", - "dflt": 0, - "editType": "calc", - "min": 0, - "valType": "integer" - }, - "orientation": { - "description": "Sets the orientation of the colorbar.", - "dflt": "v", - "editType": "calc", - "valType": "enumerated", - "values": [ - "h", - "v" - ] - }, - "outlinecolor": { - "description": "Sets the axis line color.", - "dflt": "#444", - "editType": "calc", - "valType": "color" - }, - "outlinewidth": { - "description": "Sets the width (in px) of the axis line.", - "dflt": 1, - "editType": "calc", - "min": 0, - "valType": "number" - }, - "role": "object", - "separatethousands": { - "description": "If \"true\", even 4-digit integers are separated", - "dflt": false, - "editType": "calc", - "valType": "boolean" - }, - "showexponent": { - "description": "If *all*, all exponents are shown besides their significands. If *first*, only the exponent of the first tick is shown. If *last*, only the exponent of the last tick is shown. If *none*, no exponents appear.", - "dflt": "all", - "editType": "calc", - "valType": "enumerated", - "values": [ - "all", - "first", - "last", - "none" - ] - }, - "showticklabels": { - "description": "Determines whether or not the tick labels are drawn.", - "dflt": true, - "editType": "calc", - "valType": "boolean" - }, - "showtickprefix": { - "description": "If *all*, all tick labels are displayed with a prefix. If *first*, only the first tick is displayed with a prefix. If *last*, only the last tick is displayed with a suffix. If *none*, tick prefixes are hidden.", - "dflt": "all", - "editType": "calc", - "valType": "enumerated", - "values": [ - "all", - "first", - "last", - "none" - ] - }, - "showticksuffix": { - "description": "Same as `showtickprefix` but for tick suffixes.", - "dflt": "all", - "editType": "calc", - "valType": "enumerated", - "values": [ - "all", - "first", - "last", - "none" - ] - }, - "thickness": { - "description": "Sets the thickness of the color bar This measure excludes the size of the padding, ticks and labels.", - "dflt": 30, - "editType": "calc", - "min": 0, - "valType": "number" - }, - "thicknessmode": { - "description": "Determines whether this color bar's thickness (i.e. the measure in the constant color direction) is set in units of plot *fraction* or in *pixels*. Use `thickness` to set the value.", - "dflt": "pixels", - "editType": "calc", - "valType": "enumerated", - "values": [ - "fraction", - "pixels" - ] - }, - "tick0": { - "description": "Sets the placement of the first tick on this axis. Use with `dtick`. If the axis `type` is *log*, then you must take the log of your starting tick (e.g. to set the starting tick to 100, set the `tick0` to 2) except when `dtick`=*L* (see `dtick` for more info). If the axis `type` is *date*, it should be a date string, like date data. If the axis `type` is *category*, it should be a number, using the scale where each category is assigned a serial number from zero in the order it appears.", - "editType": "calc", - "impliedEdits": { - "tickmode": "linear" - }, - "valType": "any" - }, - "tickangle": { - "description": "Sets the angle of the tick labels with respect to the horizontal. For example, a `tickangle` of -90 draws the tick labels vertically.", - "dflt": "auto", - "editType": "calc", - "valType": "angle" - }, - "tickcolor": { - "description": "Sets the tick color.", - "dflt": "#444", - "editType": "calc", - "valType": "color" - }, - "tickfont": { - "color": { - "editType": "calc", - "valType": "color" - }, - "description": "Sets the color bar's tick label font", - "editType": "calc", - "family": { - "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The Chart Studio Cloud (at https://chart-studio.plotly.com or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", - "editType": "calc", - "noBlank": true, - "strict": true, - "valType": "string" - }, - "lineposition": { - "description": "Sets the kind of decoration line(s) with text, such as an *under*, *over* or *through* as well as combinations e.g. *under+over*, etc.", - "dflt": "none", - "editType": "calc", - "extras": [ - "none" - ], - "flags": [ - "under", - "over", - "through" - ], - "valType": "flaglist" - }, - "role": "object", - "shadow": { - "description": "Sets the shape and color of the shadow behind text. *auto* places minimal shadow and applies contrast text font color. See https://developer.mozilla.org/en-US/docs/Web/CSS/text-shadow for additional options.", - "dflt": "none", - "editType": "calc", - "valType": "string" - }, - "size": { - "editType": "calc", - "min": 1, - "valType": "number" - }, - "style": { - "description": "Sets whether a font should be styled with a normal or italic face from its family.", - "dflt": "normal", - "editType": "calc", - "valType": "enumerated", - "values": [ - "normal", - "italic" - ] - }, - "textcase": { - "description": "Sets capitalization of text. It can be used to make text appear in all-uppercase or all-lowercase, or with each word capitalized.", - "dflt": "normal", - "editType": "calc", - "valType": "enumerated", - "values": [ - "normal", - "word caps", - "upper", - "lower" - ] - }, - "variant": { - "description": "Sets the variant of the font.", - "dflt": "normal", - "editType": "calc", - "valType": "enumerated", - "values": [ - "normal", - "small-caps", - "all-small-caps", - "all-petite-caps", - "petite-caps", - "unicase" - ] - }, - "weight": { - "description": "Sets the weight (or boldness) of the font.", - "dflt": "normal", - "editType": "calc", - "extras": [ - "normal", - "bold" - ], - "max": 1000, - "min": 1, - "valType": "integer" - } - }, - "tickformat": { - "description": "Sets the tick label formatting rule using d3 formatting mini-languages which are very similar to those in Python. For numbers, see: https://github.com/d3/d3-format/tree/v1.4.5#d3-format. And for dates see: https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format. We add two items to d3's date formatter: *%h* for half of the year as a decimal number as well as *%{n}f* for fractional seconds with n digits. For example, *2016-10-13 09:15:23.456* with tickformat *%H~%M~%S.%2f* would display *09~15~23.46*", - "dflt": "", - "editType": "calc", - "valType": "string" - }, - "tickformatstops": { - "items": { - "tickformatstop": { - "dtickrange": { - "description": "range [*min*, *max*], where *min*, *max* - dtick values which describe some zoom level, it is possible to omit *min* or *max* value by passing *null*", - "editType": "calc", - "items": [ - { - "editType": "calc", - "valType": "any" - }, - { - "editType": "calc", - "valType": "any" - } - ], - "valType": "info_array" - }, - "editType": "calc", - "enabled": { - "description": "Determines whether or not this stop is used. If `false`, this stop is ignored even within its `dtickrange`.", - "dflt": true, - "editType": "calc", - "valType": "boolean" - }, - "name": { - "description": "When used in a template, named items are created in the output figure in addition to any items the figure already has in this array. You can modify these items in the output figure by making your own item with `templateitemname` matching this `name` alongside your modifications (including `visible: false` or `enabled: false` to hide it). Has no effect outside of a template.", - "editType": "calc", - "valType": "string" - }, - "role": "object", - "templateitemname": { - "description": "Used to refer to a named item in this array in the template. Named items from the template will be created even without a matching item in the input figure, but you can modify one by making an item with `templateitemname` matching its `name`, alongside your modifications (including `visible: false` or `enabled: false` to hide it). If there is no template or no matching item, this item will be hidden unless you explicitly show it with `visible: true`.", - "editType": "calc", - "valType": "string" - }, - "value": { - "description": "string - dtickformat for described zoom level, the same as *tickformat*", - "dflt": "", - "editType": "calc", - "valType": "string" - } - } - }, - "role": "object" - }, - "ticklabeloverflow": { - "description": "Determines how we handle tick labels that would overflow either the graph div or the domain of the axis. The default value for inside tick labels is *hide past domain*. In other cases the default is *hide past div*.", - "editType": "calc", - "valType": "enumerated", - "values": [ - "allow", - "hide past div", - "hide past domain" - ] - }, - "ticklabelposition": { - "description": "Determines where tick labels are drawn relative to the ticks. Left and right options are used when `orientation` is *h*, top and bottom when `orientation` is *v*.", - "dflt": "outside", - "editType": "calc", - "valType": "enumerated", - "values": [ - "outside", - "inside", - "outside top", - "inside top", - "outside left", - "inside left", - "outside right", - "inside right", - "outside bottom", - "inside bottom" - ] - }, - "ticklabelstep": { - "description": "Sets the spacing between tick labels as compared to the spacing between ticks. A value of 1 (default) means each tick gets a label. A value of 2 means shows every 2nd label. A larger value n means only every nth tick is labeled. `tick0` determines which labels are shown. Not implemented for axes with `type` *log* or *multicategory*, or when `tickmode` is *array*.", - "dflt": 1, - "editType": "calc", - "min": 1, - "valType": "integer" - }, - "ticklen": { - "description": "Sets the tick length (in px).", - "dflt": 5, - "editType": "calc", - "min": 0, - "valType": "number" - }, - "tickmode": { - "description": "Sets the tick mode for this axis. If *auto*, the number of ticks is set via `nticks`. If *linear*, the placement of the ticks is determined by a starting position `tick0` and a tick step `dtick` (*linear* is the default value if `tick0` and `dtick` are provided). If *array*, the placement of the ticks is set via `tickvals` and the tick text is `ticktext`. (*array* is the default value if `tickvals` is provided).", - "editType": "calc", - "impliedEdits": {}, - "valType": "enumerated", - "values": [ - "auto", - "linear", - "array" - ] - }, - "tickprefix": { - "description": "Sets a tick label prefix.", - "dflt": "", - "editType": "calc", - "valType": "string" - }, - "ticks": { - "description": "Determines whether ticks are drawn or not. If **, this axis' ticks are not drawn. If *outside* (*inside*), this axis' are drawn outside (inside) the axis lines.", - "dflt": "", - "editType": "calc", - "valType": "enumerated", - "values": [ - "outside", - "inside", - "" - ] - }, - "ticksuffix": { - "description": "Sets a tick label suffix.", - "dflt": "", - "editType": "calc", - "valType": "string" - }, - "ticktext": { - "description": "Sets the text displayed at the ticks position via `tickvals`. Only has an effect if `tickmode` is set to *array*. Used with `tickvals`.", - "editType": "calc", - "valType": "data_array" - }, - "ticktextsrc": { - "description": "Sets the source reference on Chart Studio Cloud for `ticktext`.", - "editType": "none", - "valType": "string" - }, - "tickvals": { - "description": "Sets the values at which ticks on this axis appear. Only has an effect if `tickmode` is set to *array*. Used with `ticktext`.", - "editType": "calc", - "valType": "data_array" - }, - "tickvalssrc": { - "description": "Sets the source reference on Chart Studio Cloud for `tickvals`.", - "editType": "none", - "valType": "string" - }, - "tickwidth": { - "description": "Sets the tick width (in px).", - "dflt": 1, - "editType": "calc", - "min": 0, - "valType": "number" - }, - "title": { - "editType": "calc", - "font": { - "color": { - "editType": "calc", - "valType": "color" - }, - "description": "Sets this color bar's title font. Note that the title's font used to be set by the now deprecated `titlefont` attribute.", - "editType": "calc", - "family": { - "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The Chart Studio Cloud (at https://chart-studio.plotly.com or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", - "editType": "calc", - "noBlank": true, - "strict": true, - "valType": "string" - }, - "lineposition": { - "description": "Sets the kind of decoration line(s) with text, such as an *under*, *over* or *through* as well as combinations e.g. *under+over*, etc.", - "dflt": "none", - "editType": "calc", - "extras": [ - "none" - ], - "flags": [ - "under", - "over", - "through" - ], - "valType": "flaglist" - }, - "role": "object", - "shadow": { - "description": "Sets the shape and color of the shadow behind text. *auto* places minimal shadow and applies contrast text font color. See https://developer.mozilla.org/en-US/docs/Web/CSS/text-shadow for additional options.", - "dflt": "none", - "editType": "calc", - "valType": "string" - }, - "size": { - "editType": "calc", - "min": 1, - "valType": "number" - }, - "style": { - "description": "Sets whether a font should be styled with a normal or italic face from its family.", - "dflt": "normal", - "editType": "calc", - "valType": "enumerated", - "values": [ - "normal", - "italic" - ] - }, - "textcase": { - "description": "Sets capitalization of text. It can be used to make text appear in all-uppercase or all-lowercase, or with each word capitalized.", - "dflt": "normal", - "editType": "calc", - "valType": "enumerated", - "values": [ - "normal", - "word caps", - "upper", - "lower" - ] - }, - "variant": { - "description": "Sets the variant of the font.", - "dflt": "normal", - "editType": "calc", - "valType": "enumerated", - "values": [ - "normal", - "small-caps", - "all-small-caps", - "all-petite-caps", - "petite-caps", - "unicase" - ] - }, - "weight": { - "description": "Sets the weight (or boldness) of the font.", - "dflt": "normal", - "editType": "calc", - "extras": [ - "normal", - "bold" - ], - "max": 1000, - "min": 1, - "valType": "integer" - } - }, - "role": "object", - "side": { - "description": "Determines the location of color bar's title with respect to the color bar. Defaults to *top* when `orientation` if *v* and defaults to *right* when `orientation` if *h*. Note that the title's location used to be set by the now deprecated `titleside` attribute.", - "editType": "calc", - "valType": "enumerated", - "values": [ - "right", - "top", - "bottom" - ] - }, - "text": { - "description": "Sets the title of the color bar. Note that before the existence of `title.text`, the title's contents used to be defined as the `title` attribute itself. This behavior has been deprecated.", - "editType": "calc", - "valType": "string" - } - }, - "x": { - "description": "Sets the x position with respect to `xref` of the color bar (in plot fraction). When `xref` is *paper*, defaults to 1.02 when `orientation` is *v* and 0.5 when `orientation` is *h*. When `xref` is *container*, defaults to *1* when `orientation` is *v* and 0.5 when `orientation` is *h*. Must be between *0* and *1* if `xref` is *container* and between *-2* and *3* if `xref` is *paper*.", - "editType": "calc", - "valType": "number" - }, - "xanchor": { - "description": "Sets this color bar's horizontal position anchor. This anchor binds the `x` position to the *left*, *center* or *right* of the color bar. Defaults to *left* when `orientation` is *v* and *center* when `orientation` is *h*.", - "editType": "calc", - "valType": "enumerated", - "values": [ - "left", - "center", - "right" - ] - }, - "xpad": { - "description": "Sets the amount of padding (in px) along the x direction.", - "dflt": 10, - "editType": "calc", - "min": 0, - "valType": "number" - }, - "xref": { - "description": "Sets the container `x` refers to. *container* spans the entire `width` of the plot. *paper* refers to the width of the plotting area only.", - "dflt": "paper", - "editType": "calc", - "valType": "enumerated", - "values": [ - "container", - "paper" - ] - }, - "y": { - "description": "Sets the y position with respect to `yref` of the color bar (in plot fraction). When `yref` is *paper*, defaults to 0.5 when `orientation` is *v* and 1.02 when `orientation` is *h*. When `yref` is *container*, defaults to 0.5 when `orientation` is *v* and 1 when `orientation` is *h*. Must be between *0* and *1* if `yref` is *container* and between *-2* and *3* if `yref` is *paper*.", - "editType": "calc", - "valType": "number" - }, - "yanchor": { - "description": "Sets this color bar's vertical position anchor This anchor binds the `y` position to the *top*, *middle* or *bottom* of the color bar. Defaults to *middle* when `orientation` is *v* and *bottom* when `orientation` is *h*.", - "editType": "calc", - "valType": "enumerated", - "values": [ - "top", - "middle", - "bottom" - ] - }, - "ypad": { - "description": "Sets the amount of padding (in px) along the y direction.", - "dflt": 10, - "editType": "calc", - "min": 0, - "valType": "number" - }, - "yref": { - "description": "Sets the container `y` refers to. *container* spans the entire `height` of the plot. *paper* refers to the height of the plotting area only.", - "dflt": "paper", - "editType": "calc", - "valType": "enumerated", - "values": [ - "container", - "paper" - ] - } - }, - "colorscale": { - "description": "Sets the colorscale. The colorscale must be an array containing arrays mapping a normalized value to an rgb, rgba, hex, hsl, hsv, or named color string. At minimum, a mapping for the lowest (0) and highest (1) values are required. For example, `[[0, 'rgb(0,0,255)'], [1, 'rgb(255,0,0)']]`. To control the bounds of the colorscale in color space, use `zmin` and `zmax`. Alternatively, `colorscale` may be a palette name string of the following list: Blackbody,Bluered,Blues,Cividis,Earth,Electric,Greens,Greys,Hot,Jet,Picnic,Portland,Rainbow,RdBu,Reds,Viridis,YlGnBu,YlOrRd.", - "dflt": null, - "editType": "calc", - "impliedEdits": { - "autocolorscale": false - }, - "valType": "colorscale" - }, - "customdata": { - "description": "Assigns extra data each datum. This may be useful when listening to hover, click and selection events. Note that, *scatter* traces also appends customdata items in the markers DOM elements", - "editType": "calc", - "valType": "data_array" - }, - "customdatasrc": { - "description": "Sets the source reference on Chart Studio Cloud for `customdata`.", - "editType": "none", - "valType": "string" - }, - "dx": { - "description": "Sets the x coordinate step. See `x0` for more info.", - "dflt": 1, - "editType": "calc", - "impliedEdits": { - "xtype": "scaled" - }, - "valType": "number" - }, - "dy": { - "description": "Sets the y coordinate step. See `y0` for more info.", - "dflt": 1, - "editType": "calc", - "impliedEdits": { - "ytype": "scaled" - }, - "valType": "number" - }, - "hoverinfo": { - "arrayOk": true, - "description": "Determines which trace information appear on hover. If `none` or `skip` are set, no information is displayed upon hovering. But, if `none` is set, click and hover events are still fired.", - "dflt": "all", - "editType": "none", - "extras": [ - "all", - "none", - "skip" - ], - "flags": [ - "x", - "y", - "z", - "text", - "name" - ], - "valType": "flaglist" - }, - "hoverinfosrc": { - "description": "Sets the source reference on Chart Studio Cloud for `hoverinfo`.", - "editType": "none", - "valType": "string" - }, - "hoverlabel": { - "align": { - "arrayOk": true, - "description": "Sets the horizontal alignment of the text content within hover label box. Has an effect only if the hover label text spans more two or more lines", - "dflt": "auto", - "editType": "none", - "valType": "enumerated", - "values": [ - "left", - "right", - "auto" - ] - }, - "alignsrc": { - "description": "Sets the source reference on Chart Studio Cloud for `align`.", - "editType": "none", - "valType": "string" - }, - "bgcolor": { - "arrayOk": true, - "description": "Sets the background color of the hover labels for this trace", - "editType": "none", - "valType": "color" - }, - "bgcolorsrc": { - "description": "Sets the source reference on Chart Studio Cloud for `bgcolor`.", - "editType": "none", - "valType": "string" - }, - "bordercolor": { - "arrayOk": true, - "description": "Sets the border color of the hover labels for this trace.", - "editType": "none", - "valType": "color" - }, - "bordercolorsrc": { - "description": "Sets the source reference on Chart Studio Cloud for `bordercolor`.", - "editType": "none", - "valType": "string" - }, - "editType": "none", - "font": { - "color": { - "arrayOk": true, - "editType": "none", - "valType": "color" - }, - "colorsrc": { - "description": "Sets the source reference on Chart Studio Cloud for `color`.", - "editType": "none", - "valType": "string" - }, - "description": "Sets the font used in hover labels.", - "editType": "none", - "family": { - "arrayOk": true, - "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The Chart Studio Cloud (at https://chart-studio.plotly.com or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", - "editType": "none", - "noBlank": true, - "strict": true, - "valType": "string" - }, - "familysrc": { - "description": "Sets the source reference on Chart Studio Cloud for `family`.", - "editType": "none", - "valType": "string" - }, - "lineposition": { - "arrayOk": true, - "description": "Sets the kind of decoration line(s) with text, such as an *under*, *over* or *through* as well as combinations e.g. *under+over*, etc.", - "dflt": "none", - "editType": "none", - "extras": [ - "none" - ], - "flags": [ - "under", - "over", - "through" - ], - "valType": "flaglist" - }, - "linepositionsrc": { - "description": "Sets the source reference on Chart Studio Cloud for `lineposition`.", - "editType": "none", - "valType": "string" - }, - "role": "object", - "shadow": { - "arrayOk": true, - "description": "Sets the shape and color of the shadow behind text. *auto* places minimal shadow and applies contrast text font color. See https://developer.mozilla.org/en-US/docs/Web/CSS/text-shadow for additional options.", - "dflt": "none", - "editType": "none", - "valType": "string" - }, - "shadowsrc": { - "description": "Sets the source reference on Chart Studio Cloud for `shadow`.", - "editType": "none", - "valType": "string" - }, - "size": { - "arrayOk": true, - "editType": "none", - "min": 1, - "valType": "number" - }, - "sizesrc": { - "description": "Sets the source reference on Chart Studio Cloud for `size`.", - "editType": "none", - "valType": "string" - }, - "style": { - "arrayOk": true, - "description": "Sets whether a font should be styled with a normal or italic face from its family.", - "dflt": "normal", - "editType": "none", - "valType": "enumerated", - "values": [ - "normal", - "italic" - ] - }, - "stylesrc": { - "description": "Sets the source reference on Chart Studio Cloud for `style`.", - "editType": "none", - "valType": "string" - }, - "textcase": { - "arrayOk": true, - "description": "Sets capitalization of text. It can be used to make text appear in all-uppercase or all-lowercase, or with each word capitalized.", - "dflt": "normal", - "editType": "none", - "valType": "enumerated", - "values": [ - "normal", - "word caps", - "upper", - "lower" - ] - }, - "textcasesrc": { - "description": "Sets the source reference on Chart Studio Cloud for `textcase`.", - "editType": "none", - "valType": "string" - }, - "variant": { - "arrayOk": true, - "description": "Sets the variant of the font.", - "dflt": "normal", - "editType": "none", - "valType": "enumerated", - "values": [ - "normal", - "small-caps", - "all-small-caps", - "all-petite-caps", - "petite-caps", - "unicase" - ] - }, - "variantsrc": { - "description": "Sets the source reference on Chart Studio Cloud for `variant`.", - "editType": "none", - "valType": "string" - }, - "weight": { - "arrayOk": true, - "description": "Sets the weight (or boldness) of the font.", - "dflt": "normal", - "editType": "none", - "extras": [ - "normal", - "bold" - ], - "max": 1000, - "min": 1, - "valType": "integer" - }, - "weightsrc": { - "description": "Sets the source reference on Chart Studio Cloud for `weight`.", - "editType": "none", - "valType": "string" - } - }, - "namelength": { - "arrayOk": true, - "description": "Sets the default length (in number of characters) of the trace name in the hover labels for all traces. -1 shows the whole name regardless of length. 0-3 shows the first 0-3 characters, and an integer >3 will show the whole name if it is less than that many characters, but if it is longer, will truncate to `namelength - 3` characters and add an ellipsis.", - "dflt": 15, - "editType": "none", - "min": -1, - "valType": "integer" - }, - "namelengthsrc": { - "description": "Sets the source reference on Chart Studio Cloud for `namelength`.", - "editType": "none", - "valType": "string" - }, - "role": "object" - }, - "ids": { - "description": "Assigns id labels to each datum. These ids for object constancy of data points during animation. Should be an array of strings, not numbers or any other type.", - "editType": "calc", - "valType": "data_array" - }, - "idssrc": { - "description": "Sets the source reference on Chart Studio Cloud for `ids`.", - "editType": "none", - "valType": "string" - }, - "legend": { - "description": "Sets the reference to a legend to show this trace in. References to these legends are *legend*, *legend2*, *legend3*, etc. Settings for these legends are set in the layout, under `layout.legend`, `layout.legend2`, etc.", - "dflt": "legend", - "editType": "style", - "valType": "subplotid" - }, - "legendgrouptitle": { - "editType": "style", - "font": { - "color": { - "editType": "style", - "valType": "color" - }, - "description": "Sets this legend group's title font.", - "editType": "style", - "family": { - "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The Chart Studio Cloud (at https://chart-studio.plotly.com or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", - "editType": "style", - "noBlank": true, - "strict": true, - "valType": "string" - }, - "lineposition": { - "description": "Sets the kind of decoration line(s) with text, such as an *under*, *over* or *through* as well as combinations e.g. *under+over*, etc.", - "dflt": "none", - "editType": "style", - "extras": [ - "none" - ], - "flags": [ - "under", - "over", - "through" - ], - "valType": "flaglist" - }, - "role": "object", - "shadow": { - "description": "Sets the shape and color of the shadow behind text. *auto* places minimal shadow and applies contrast text font color. See https://developer.mozilla.org/en-US/docs/Web/CSS/text-shadow for additional options.", - "dflt": "none", - "editType": "style", - "valType": "string" - }, - "size": { - "editType": "style", - "min": 1, - "valType": "number" - }, - "style": { - "description": "Sets whether a font should be styled with a normal or italic face from its family.", - "dflt": "normal", - "editType": "style", - "valType": "enumerated", - "values": [ - "normal", - "italic" - ] - }, - "textcase": { - "description": "Sets capitalization of text. It can be used to make text appear in all-uppercase or all-lowercase, or with each word capitalized.", - "dflt": "normal", - "editType": "style", - "valType": "enumerated", - "values": [ - "normal", - "word caps", - "upper", - "lower" - ] - }, - "variant": { - "description": "Sets the variant of the font.", - "dflt": "normal", - "editType": "style", - "valType": "enumerated", - "values": [ - "normal", - "small-caps", - "all-small-caps", - "all-petite-caps", - "petite-caps", - "unicase" - ] - }, - "weight": { - "description": "Sets the weight (or boldness) of the font.", - "dflt": "normal", - "editType": "style", - "extras": [ - "normal", - "bold" - ], - "max": 1000, - "min": 1, - "valType": "integer" - } - }, - "role": "object", - "text": { - "description": "Sets the title of the legend group.", - "dflt": "", - "editType": "style", - "valType": "string" - } - }, - "legendrank": { - "description": "Sets the legend rank for this trace. Items and groups with smaller ranks are presented on top/left side while with *reversed* `legend.traceorder` they are on bottom/right side. The default legendrank is 1000, so that you can use ranks less than 1000 to place certain items before all unranked items, and ranks greater than 1000 to go after all unranked items. When having unranked or equal rank items shapes would be displayed after traces i.e. according to their order in data and layout.", - "dflt": 1000, - "editType": "style", - "valType": "number" - }, - "legendwidth": { - "description": "Sets the width (in px or fraction) of the legend for this trace.", - "editType": "style", - "min": 0, - "valType": "number" - }, - "meta": { - "arrayOk": true, - "description": "Assigns extra meta information associated with this trace that can be used in various text attributes. Attributes such as trace `name`, graph, axis and colorbar `title.text`, annotation `text` `rangeselector`, `updatemenues` and `sliders` `label` text all support `meta`. To access the trace `meta` values in an attribute in the same trace, simply use `%{meta[i]}` where `i` is the index or key of the `meta` item in question. To access trace `meta` in layout attributes, use `%{data[n[.meta[i]}` where `i` is the index or key of the `meta` and `n` is the trace index.", - "editType": "plot", - "valType": "any" - }, - "metasrc": { - "description": "Sets the source reference on Chart Studio Cloud for `meta`.", - "editType": "none", - "valType": "string" - }, - "name": { - "description": "Sets the trace name. The trace name appears as the legend item and on hover.", - "editType": "style", - "valType": "string" - }, - "opacity": { - "description": "Sets the opacity of the trace.", - "dflt": 1, - "editType": "style", - "max": 1, - "min": 0, - "valType": "number" - }, - "reversescale": { - "description": "Reverses the color mapping if true. If true, `zmin` will correspond to the last color in the array and `zmax` will correspond to the first color.", - "dflt": false, - "editType": "calc", - "valType": "boolean" - }, - "showscale": { - "description": "Determines whether or not a colorbar is displayed for this trace.", - "dflt": true, - "editType": "calc", - "valType": "boolean" - }, - "stream": { - "editType": "calc", - "maxpoints": { - "description": "Sets the maximum number of points to keep on the plots from an incoming stream. If `maxpoints` is set to *50*, only the newest 50 points will be displayed on the plot.", - "dflt": 500, - "editType": "calc", - "max": 10000, - "min": 0, - "valType": "number" - }, - "role": "object", - "token": { - "description": "The stream id number links a data trace on a plot with a stream. See https://chart-studio.plotly.com/settings for more details.", - "editType": "calc", - "noBlank": true, - "strict": true, - "valType": "string" - } - }, - "text": { - "description": "Sets the text elements associated with each z value.", - "editType": "calc", - "valType": "data_array" - }, - "textsrc": { - "description": "Sets the source reference on Chart Studio Cloud for `text`.", - "editType": "none", - "valType": "string" - }, - "transforms": { - "items": { - "transform": { - "description": "WARNING: All transforms are deprecated and may be removed from the API in next major version. An array of operations that manipulate the trace data, for example filtering or sorting the data arrays.", - "editType": "calc", - "role": "object" - } - }, - "role": "object" - }, - "transpose": { - "description": "Transposes the z data.", - "dflt": false, - "editType": "calc", - "valType": "boolean" - }, - "type": "heatmapgl", - "uid": { - "description": "Assign an id to this trace, Use this to provide object constancy between traces during animations and transitions.", - "editType": "plot", - "valType": "string" - }, - "uirevision": { - "description": "Controls persistence of some user-driven changes to the trace: `constraintrange` in `parcoords` traces, as well as some `editable: true` modifications such as `name` and `colorbar.title`. Defaults to `layout.uirevision`. Note that other user-driven trace attribute changes are controlled by `layout` attributes: `trace.visible` is controlled by `layout.legend.uirevision`, `selectedpoints` is controlled by `layout.selectionrevision`, and `colorbar.(x|y)` (accessible with `config: {editable: true}`) is controlled by `layout.editrevision`. Trace changes are tracked by `uid`, which only falls back on trace index if no `uid` is provided. So if your app can add/remove traces before the end of the `data` array, such that the same trace has a different index, you can still preserve user-driven changes if you give each trace a `uid` that stays with it as it moves.", - "editType": "none", - "valType": "any" - }, - "visible": { - "description": "Determines whether or not this trace is visible. If *legendonly*, the trace is not drawn, but can appear as a legend item (provided that the legend itself is visible).", - "dflt": true, - "editType": "calc", - "valType": "enumerated", - "values": [ - true, - false, - "legendonly" - ] - }, - "x": { - "description": "Sets the x coordinates.", - "editType": "calc", - "impliedEdits": { - "xtype": "array" - }, - "valType": "data_array" - }, - "x0": { - "description": "Alternate to `x`. Builds a linear space of x coordinates. Use with `dx` where `x0` is the starting coordinate and `dx` the step.", - "dflt": 0, - "editType": "calc", - "impliedEdits": { - "xtype": "scaled" - }, - "valType": "any" - }, - "xaxis": { - "description": "Sets a reference between this trace's x coordinates and a 2D cartesian x axis. If *x* (the default value), the x coordinates refer to `layout.xaxis`. If *x2*, the x coordinates refer to `layout.xaxis2`, and so on.", - "dflt": "x", - "editType": "calc+clearAxisTypes", - "valType": "subplotid" - }, - "xsrc": { - "description": "Sets the source reference on Chart Studio Cloud for `x`.", - "editType": "none", - "valType": "string" - }, - "xtype": { - "description": "If *array*, the heatmap's x coordinates are given by *x* (the default behavior when `x` is provided). If *scaled*, the heatmap's x coordinates are given by *x0* and *dx* (the default behavior when `x` is not provided).", - "editType": "calc", - "valType": "enumerated", - "values": [ - "array", - "scaled" - ] - }, - "y": { - "description": "Sets the y coordinates.", - "editType": "calc", - "impliedEdits": { - "ytype": "array" - }, - "valType": "data_array" - }, - "y0": { - "description": "Alternate to `y`. Builds a linear space of y coordinates. Use with `dy` where `y0` is the starting coordinate and `dy` the step.", - "dflt": 0, - "editType": "calc", - "impliedEdits": { - "ytype": "scaled" - }, - "valType": "any" - }, - "yaxis": { - "description": "Sets a reference between this trace's y coordinates and a 2D cartesian y axis. If *y* (the default value), the y coordinates refer to `layout.yaxis`. If *y2*, the y coordinates refer to `layout.yaxis2`, and so on.", - "dflt": "y", - "editType": "calc+clearAxisTypes", - "valType": "subplotid" - }, - "ysrc": { - "description": "Sets the source reference on Chart Studio Cloud for `y`.", - "editType": "none", - "valType": "string" - }, - "ytype": { - "description": "If *array*, the heatmap's y coordinates are given by *y* (the default behavior when `y` is provided) If *scaled*, the heatmap's y coordinates are given by *y0* and *dy* (the default behavior when `y` is not provided)", - "editType": "calc", - "valType": "enumerated", - "values": [ - "array", - "scaled" - ] - }, - "z": { - "description": "Sets the z data.", - "editType": "calc", - "valType": "data_array" - }, - "zauto": { - "description": "Determines whether or not the color domain is computed with respect to the input data (here in `z`) or the bounds set in `zmin` and `zmax` Defaults to `false` when `zmin` and `zmax` are set by the user.", - "dflt": true, - "editType": "calc", - "impliedEdits": {}, - "valType": "boolean" - }, - "zmax": { - "description": "Sets the upper bound of the color domain. Value should have the same units as in `z` and if set, `zmin` must be set as well.", - "dflt": null, - "editType": "calc", - "impliedEdits": { - "zauto": false - }, - "valType": "number" - }, - "zmid": { - "description": "Sets the mid-point of the color domain by scaling `zmin` and/or `zmax` to be equidistant to this point. Value should have the same units as in `z`. Has no effect when `zauto` is `false`.", - "dflt": null, - "editType": "calc", - "impliedEdits": {}, - "valType": "number" - }, - "zmin": { - "description": "Sets the lower bound of the color domain. Value should have the same units as in `z` and if set, `zmax` must be set as well.", - "dflt": null, - "editType": "calc", - "impliedEdits": { - "zauto": false - }, - "valType": "number" - }, - "zsmooth": { - "description": "Picks a smoothing algorithm use to smooth `z` data.", - "dflt": "fast", - "editType": "calc", - "valType": "enumerated", - "values": [ - "fast", - false - ] - }, - "zsrc": { - "description": "Sets the source reference on Chart Studio Cloud for `z`.", - "editType": "none", - "valType": "string" - } - }, - "categories": [ - "gl", - "gl2d", - "2dMap" - ], - "meta": { - "description": "*heatmapgl* trace is deprecated! Please consider switching to the *heatmap* or *image* trace types. Alternatively you could contribute/sponsor rewriting this trace type based on cartesian features and using regl framework. WebGL version of the heatmap trace type." - }, - "type": "heatmapgl" - }, "histogram": { "animatable": false, "attributes": { @@ -61425,232 +60069,27 @@ "arrayOk": true, "description": "Assigns extra meta information associated with this trace that can be used in various text attributes. Attributes such as trace `name`, graph, axis and colorbar `title.text`, annotation `text` `rangeselector`, `updatemenues` and `sliders` `label` text all support `meta`. To access the trace `meta` values in an attribute in the same trace, simply use `%{meta[i]}` where `i` is the index or key of the `meta` item in question. To access trace `meta` in layout attributes, use `%{data[n[.meta[i]}` where `i` is the index or key of the `meta` and `n` is the trace index.", "editType": "plot", - "valType": "any" - }, - "metasrc": { - "description": "Sets the source reference on Chart Studio Cloud for `meta`.", - "editType": "none", - "valType": "string" - }, - "name": { - "description": "Sets the trace name. The trace name appears as the legend item and on hover.", - "editType": "style", - "valType": "string" - }, - "opacity": { - "description": "Sets the opacity of the trace.", - "dflt": 1, - "editType": "style", - "max": 1, - "min": 0, - "valType": "number" - }, - "outsidetextfont": { - "color": { - "arrayOk": true, - "editType": "plot", - "valType": "color" - }, - "colorsrc": { - "description": "Sets the source reference on Chart Studio Cloud for `color`.", - "editType": "none", - "valType": "string" - }, - "description": "Sets the font used for `textinfo` lying outside the sector.", - "editType": "plot", - "family": { - "arrayOk": true, - "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The Chart Studio Cloud (at https://chart-studio.plotly.com or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", - "editType": "plot", - "noBlank": true, - "strict": true, - "valType": "string" - }, - "familysrc": { - "description": "Sets the source reference on Chart Studio Cloud for `family`.", - "editType": "none", - "valType": "string" - }, - "lineposition": { - "arrayOk": true, - "description": "Sets the kind of decoration line(s) with text, such as an *under*, *over* or *through* as well as combinations e.g. *under+over*, etc.", - "dflt": "none", - "editType": "plot", - "extras": [ - "none" - ], - "flags": [ - "under", - "over", - "through" - ], - "valType": "flaglist" - }, - "linepositionsrc": { - "description": "Sets the source reference on Chart Studio Cloud for `lineposition`.", - "editType": "none", - "valType": "string" - }, - "role": "object", - "shadow": { - "arrayOk": true, - "description": "Sets the shape and color of the shadow behind text. *auto* places minimal shadow and applies contrast text font color. See https://developer.mozilla.org/en-US/docs/Web/CSS/text-shadow for additional options.", - "dflt": "none", - "editType": "plot", - "valType": "string" - }, - "shadowsrc": { - "description": "Sets the source reference on Chart Studio Cloud for `shadow`.", - "editType": "none", - "valType": "string" - }, - "size": { - "arrayOk": true, - "editType": "plot", - "min": 1, - "valType": "number" - }, - "sizesrc": { - "description": "Sets the source reference on Chart Studio Cloud for `size`.", - "editType": "none", - "valType": "string" - }, - "style": { - "arrayOk": true, - "description": "Sets whether a font should be styled with a normal or italic face from its family.", - "dflt": "normal", - "editType": "plot", - "valType": "enumerated", - "values": [ - "normal", - "italic" - ] - }, - "stylesrc": { - "description": "Sets the source reference on Chart Studio Cloud for `style`.", - "editType": "none", - "valType": "string" - }, - "textcase": { - "arrayOk": true, - "description": "Sets capitalization of text. It can be used to make text appear in all-uppercase or all-lowercase, or with each word capitalized.", - "dflt": "normal", - "editType": "plot", - "valType": "enumerated", - "values": [ - "normal", - "word caps", - "upper", - "lower" - ] - }, - "textcasesrc": { - "description": "Sets the source reference on Chart Studio Cloud for `textcase`.", - "editType": "none", - "valType": "string" - }, - "variant": { - "arrayOk": true, - "description": "Sets the variant of the font.", - "dflt": "normal", - "editType": "plot", - "valType": "enumerated", - "values": [ - "normal", - "small-caps", - "all-small-caps", - "all-petite-caps", - "petite-caps", - "unicase" - ] - }, - "variantsrc": { - "description": "Sets the source reference on Chart Studio Cloud for `variant`.", - "editType": "none", - "valType": "string" - }, - "weight": { - "arrayOk": true, - "description": "Sets the weight (or boldness) of the font.", - "dflt": "normal", - "editType": "plot", - "extras": [ - "normal", - "bold" - ], - "max": 1000, - "min": 1, - "valType": "integer" - }, - "weightsrc": { - "description": "Sets the source reference on Chart Studio Cloud for `weight`.", - "editType": "none", - "valType": "string" - } - }, - "pull": { - "arrayOk": true, - "description": "Sets the fraction of larger radius to pull the sectors out from the center. This can be a constant to pull all slices apart from each other equally or an array to highlight one or more slices.", - "dflt": 0, - "editType": "calc", - "max": 1, - "min": 0, - "valType": "number" - }, - "pullsrc": { - "description": "Sets the source reference on Chart Studio Cloud for `pull`.", - "editType": "none", - "valType": "string" - }, - "rotation": { - "description": "Instead of the first slice starting at 12 o'clock, rotate to some other angle.", - "dflt": 0, - "editType": "calc", - "valType": "angle" - }, - "scalegroup": { - "description": "If there are multiple pie charts that should be sized according to their totals, link them by providing a non-empty group id here shared by every trace in the same group.", - "dflt": "", - "editType": "calc", - "valType": "string" - }, - "showlegend": { - "description": "Determines whether or not an item corresponding to this trace is shown in the legend.", - "dflt": true, - "editType": "style", - "valType": "boolean" - }, - "sort": { - "description": "Determines whether or not the sectors are reordered from largest to smallest.", - "dflt": true, - "editType": "calc", - "valType": "boolean" - }, - "stream": { - "editType": "calc", - "maxpoints": { - "description": "Sets the maximum number of points to keep on the plots from an incoming stream. If `maxpoints` is set to *50*, only the newest 50 points will be displayed on the plot.", - "dflt": 500, - "editType": "calc", - "max": 10000, - "min": 0, - "valType": "number" - }, - "role": "object", - "token": { - "description": "The stream id number links a data trace on a plot with a stream. See https://chart-studio.plotly.com/settings for more details.", - "editType": "calc", - "noBlank": true, - "strict": true, - "valType": "string" - } - }, - "text": { - "description": "Sets text elements associated with each sector. If trace `textinfo` contains a *text* flag, these elements will be seen on the chart. If trace `hoverinfo` contains a *text* flag and *hovertext* is not set, these elements will be seen in the hover labels.", - "editType": "plot", - "valType": "data_array" + "valType": "any" }, - "textfont": { + "metasrc": { + "description": "Sets the source reference on Chart Studio Cloud for `meta`.", + "editType": "none", + "valType": "string" + }, + "name": { + "description": "Sets the trace name. The trace name appears as the legend item and on hover.", + "editType": "style", + "valType": "string" + }, + "opacity": { + "description": "Sets the opacity of the trace.", + "dflt": 1, + "editType": "style", + "max": 1, + "min": 0, + "valType": "number" + }, + "outsidetextfont": { "color": { "arrayOk": true, "editType": "plot", @@ -61661,7 +60100,7 @@ "editType": "none", "valType": "string" }, - "description": "Sets the font used for `textinfo`.", + "description": "Sets the font used for `textinfo` lying outside the sector.", "editType": "plot", "family": { "arrayOk": true, @@ -61784,389 +60223,275 @@ "bold" ], "max": 1000, - "min": 1, - "valType": "integer" - }, - "weightsrc": { - "description": "Sets the source reference on Chart Studio Cloud for `weight`.", - "editType": "none", - "valType": "string" - } - }, - "textinfo": { - "description": "Determines which trace information appear on the graph.", - "editType": "calc", - "extras": [ - "none" - ], - "flags": [ - "label", - "text", - "value", - "percent" - ], - "valType": "flaglist" - }, - "textposition": { - "arrayOk": true, - "description": "Specifies the location of the `textinfo`.", - "dflt": "auto", - "editType": "plot", - "valType": "enumerated", - "values": [ - "inside", - "outside", - "auto", - "none" - ] - }, - "textpositionsrc": { - "description": "Sets the source reference on Chart Studio Cloud for `textposition`.", - "editType": "none", - "valType": "string" - }, - "textsrc": { - "description": "Sets the source reference on Chart Studio Cloud for `text`.", - "editType": "none", - "valType": "string" - }, - "texttemplate": { - "arrayOk": true, - "description": "Template string used for rendering the information text that appear on points. Note that this will override `textinfo`. Variables are inserted using %{variable}, for example \"y: %{y}\". Numbers are formatted using d3-format's syntax %{variable:d3-format}, for example \"Price: %{y:$.2f}\". https://github.com/d3/d3-format/tree/v1.4.5#d3-format for details on the formatting syntax. Dates are formatted using d3-time-format's syntax %{variable|d3-time-format}, for example \"Day: %{2019-01-01|%A}\". https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format for details on the date formatting syntax. Every attributes that can be specified per-point (the ones that are `arrayOk: true`) are available. Finally, the template string has access to variables `label`, `color`, `value`, `percent` and `text`.", - "dflt": "", - "editType": "plot", - "valType": "string" - }, - "texttemplatesrc": { - "description": "Sets the source reference on Chart Studio Cloud for `texttemplate`.", - "editType": "none", - "valType": "string" - }, - "title": { - "editType": "plot", - "font": { - "color": { - "arrayOk": true, - "editType": "plot", - "valType": "color" - }, - "colorsrc": { - "description": "Sets the source reference on Chart Studio Cloud for `color`.", - "editType": "none", - "valType": "string" - }, - "description": "Sets the font used for `title`. Note that the title's font used to be set by the now deprecated `titlefont` attribute.", - "editType": "plot", - "family": { - "arrayOk": true, - "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The Chart Studio Cloud (at https://chart-studio.plotly.com or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", - "editType": "plot", - "noBlank": true, - "strict": true, - "valType": "string" - }, - "familysrc": { - "description": "Sets the source reference on Chart Studio Cloud for `family`.", - "editType": "none", - "valType": "string" - }, - "lineposition": { - "arrayOk": true, - "description": "Sets the kind of decoration line(s) with text, such as an *under*, *over* or *through* as well as combinations e.g. *under+over*, etc.", - "dflt": "none", - "editType": "plot", - "extras": [ - "none" - ], - "flags": [ - "under", - "over", - "through" - ], - "valType": "flaglist" - }, - "linepositionsrc": { - "description": "Sets the source reference on Chart Studio Cloud for `lineposition`.", - "editType": "none", - "valType": "string" - }, - "role": "object", - "shadow": { - "arrayOk": true, - "description": "Sets the shape and color of the shadow behind text. *auto* places minimal shadow and applies contrast text font color. See https://developer.mozilla.org/en-US/docs/Web/CSS/text-shadow for additional options.", - "dflt": "none", - "editType": "plot", - "valType": "string" - }, - "shadowsrc": { - "description": "Sets the source reference on Chart Studio Cloud for `shadow`.", - "editType": "none", - "valType": "string" - }, - "size": { - "arrayOk": true, - "editType": "plot", - "min": 1, - "valType": "number" - }, - "sizesrc": { - "description": "Sets the source reference on Chart Studio Cloud for `size`.", - "editType": "none", - "valType": "string" - }, - "style": { - "arrayOk": true, - "description": "Sets whether a font should be styled with a normal or italic face from its family.", - "dflt": "normal", - "editType": "plot", - "valType": "enumerated", - "values": [ - "normal", - "italic" - ] - }, - "stylesrc": { - "description": "Sets the source reference on Chart Studio Cloud for `style`.", - "editType": "none", - "valType": "string" - }, - "textcase": { - "arrayOk": true, - "description": "Sets capitalization of text. It can be used to make text appear in all-uppercase or all-lowercase, or with each word capitalized.", - "dflt": "normal", - "editType": "plot", - "valType": "enumerated", - "values": [ - "normal", - "word caps", - "upper", - "lower" - ] - }, - "textcasesrc": { - "description": "Sets the source reference on Chart Studio Cloud for `textcase`.", - "editType": "none", - "valType": "string" - }, - "variant": { - "arrayOk": true, - "description": "Sets the variant of the font.", - "dflt": "normal", - "editType": "plot", - "valType": "enumerated", - "values": [ - "normal", - "small-caps", - "all-small-caps", - "all-petite-caps", - "petite-caps", - "unicase" - ] - }, - "variantsrc": { - "description": "Sets the source reference on Chart Studio Cloud for `variant`.", - "editType": "none", - "valType": "string" - }, - "weight": { - "arrayOk": true, - "description": "Sets the weight (or boldness) of the font.", - "dflt": "normal", - "editType": "plot", - "extras": [ - "normal", - "bold" - ], - "max": 1000, - "min": 1, - "valType": "integer" - }, - "weightsrc": { - "description": "Sets the source reference on Chart Studio Cloud for `weight`.", - "editType": "none", - "valType": "string" - } - }, - "position": { - "description": "Specifies the location of the `title`. Note that the title's position used to be set by the now deprecated `titleposition` attribute.", - "editType": "plot", - "valType": "enumerated", - "values": [ - "top left", - "top center", - "top right", - "middle center", - "bottom left", - "bottom center", - "bottom right" - ] - }, - "role": "object", - "text": { - "description": "Sets the title of the chart. If it is empty, no title is displayed. Note that before the existence of `title.text`, the title's contents used to be defined as the `title` attribute itself. This behavior has been deprecated.", - "dflt": "", - "editType": "plot", - "valType": "string" - } - }, - "transforms": { - "items": { - "transform": { - "description": "WARNING: All transforms are deprecated and may be removed from the API in next major version. An array of operations that manipulate the trace data, for example filtering or sorting the data arrays.", - "editType": "calc", - "role": "object" - } + "min": 1, + "valType": "integer" }, - "role": "object" + "weightsrc": { + "description": "Sets the source reference on Chart Studio Cloud for `weight`.", + "editType": "none", + "valType": "string" + } }, - "type": "pie", - "uid": { - "description": "Assign an id to this trace, Use this to provide object constancy between traces during animations and transitions.", - "editType": "plot", - "valType": "string" + "pull": { + "arrayOk": true, + "description": "Sets the fraction of larger radius to pull the sectors out from the center. This can be a constant to pull all slices apart from each other equally or an array to highlight one or more slices.", + "dflt": 0, + "editType": "calc", + "max": 1, + "min": 0, + "valType": "number" }, - "uirevision": { - "description": "Controls persistence of some user-driven changes to the trace: `constraintrange` in `parcoords` traces, as well as some `editable: true` modifications such as `name` and `colorbar.title`. Defaults to `layout.uirevision`. Note that other user-driven trace attribute changes are controlled by `layout` attributes: `trace.visible` is controlled by `layout.legend.uirevision`, `selectedpoints` is controlled by `layout.selectionrevision`, and `colorbar.(x|y)` (accessible with `config: {editable: true}`) is controlled by `layout.editrevision`. Trace changes are tracked by `uid`, which only falls back on trace index if no `uid` is provided. So if your app can add/remove traces before the end of the `data` array, such that the same trace has a different index, you can still preserve user-driven changes if you give each trace a `uid` that stays with it as it moves.", + "pullsrc": { + "description": "Sets the source reference on Chart Studio Cloud for `pull`.", "editType": "none", - "valType": "any" + "valType": "string" }, - "values": { - "description": "Sets the values of the sectors. If omitted, we count occurrences of each label.", + "rotation": { + "description": "Instead of the first slice starting at 12 o'clock, rotate to some other angle.", + "dflt": 0, "editType": "calc", - "valType": "data_array" + "valType": "angle" }, - "valuessrc": { - "description": "Sets the source reference on Chart Studio Cloud for `values`.", - "editType": "none", + "scalegroup": { + "description": "If there are multiple pie charts that should be sized according to their totals, link them by providing a non-empty group id here shared by every trace in the same group.", + "dflt": "", + "editType": "calc", "valType": "string" }, - "visible": { - "description": "Determines whether or not this trace is visible. If *legendonly*, the trace is not drawn, but can appear as a legend item (provided that the legend itself is visible).", + "showlegend": { + "description": "Determines whether or not an item corresponding to this trace is shown in the legend.", "dflt": true, - "editType": "calc", - "valType": "enumerated", - "values": [ - true, - false, - "legendonly" - ] - } - }, - "categories": [ - "pie-like", - "pie", - "showLegend" - ], - "layoutAttributes": { - "extendpiecolors": { - "description": "If `true`, the pie slice colors (whether given by `piecolorway` or inherited from `colorway`) will be extended to three times its original length by first repeating every color 20% lighter then each color 20% darker. This is intended to reduce the likelihood of reusing the same color when you have many slices, but you can set `false` to disable. Colors provided in the trace, using `marker.colors`, are never extended.", + "editType": "style", + "valType": "boolean" + }, + "sort": { + "description": "Determines whether or not the sectors are reordered from largest to smallest.", "dflt": true, "editType": "calc", "valType": "boolean" }, - "hiddenlabels": { - "description": "hiddenlabels is the funnelarea & pie chart analog of visible:'legendonly' but it can contain many labels, and can simultaneously hide slices from several pies/funnelarea charts", + "stream": { "editType": "calc", - "valType": "data_array" - }, - "hiddenlabelssrc": { - "description": "Sets the source reference on Chart Studio Cloud for `hiddenlabels`.", - "editType": "none", - "valType": "string" + "maxpoints": { + "description": "Sets the maximum number of points to keep on the plots from an incoming stream. If `maxpoints` is set to *50*, only the newest 50 points will be displayed on the plot.", + "dflt": 500, + "editType": "calc", + "max": 10000, + "min": 0, + "valType": "number" + }, + "role": "object", + "token": { + "description": "The stream id number links a data trace on a plot with a stream. See https://chart-studio.plotly.com/settings for more details.", + "editType": "calc", + "noBlank": true, + "strict": true, + "valType": "string" + } }, - "piecolorway": { - "description": "Sets the default pie slice colors. Defaults to the main `colorway` used for trace colors. If you specify a new list here it can still be extended with lighter and darker colors, see `extendpiecolors`.", - "editType": "calc", - "valType": "colorlist" - } - }, - "meta": { - "description": "A data visualized by the sectors of the pie is set in `values`. The sector labels are set in `labels`. The sector colors are set in `marker.colors`" - }, - "type": "pie" - }, - "pointcloud": { - "animatable": false, - "attributes": { - "customdata": { - "description": "Assigns extra data each datum. This may be useful when listening to hover, click and selection events. Note that, *scatter* traces also appends customdata items in the markers DOM elements", - "editType": "calc", + "text": { + "description": "Sets text elements associated with each sector. If trace `textinfo` contains a *text* flag, these elements will be seen on the chart. If trace `hoverinfo` contains a *text* flag and *hovertext* is not set, these elements will be seen in the hover labels.", + "editType": "plot", "valType": "data_array" }, - "customdatasrc": { - "description": "Sets the source reference on Chart Studio Cloud for `customdata`.", - "editType": "none", - "valType": "string" - }, - "hoverinfo": { - "arrayOk": true, - "description": "Determines which trace information appear on hover. If `none` or `skip` are set, no information is displayed upon hovering. But, if `none` is set, click and hover events are still fired.", - "dflt": "all", - "editType": "none", - "extras": [ - "all", - "none", - "skip" - ], - "flags": [ - "x", - "y", - "z", - "text", - "name" - ], - "valType": "flaglist" - }, - "hoverinfosrc": { - "description": "Sets the source reference on Chart Studio Cloud for `hoverinfo`.", - "editType": "none", - "valType": "string" - }, - "hoverlabel": { - "align": { + "textfont": { + "color": { "arrayOk": true, - "description": "Sets the horizontal alignment of the text content within hover label box. Has an effect only if the hover label text spans more two or more lines", - "dflt": "auto", + "editType": "plot", + "valType": "color" + }, + "colorsrc": { + "description": "Sets the source reference on Chart Studio Cloud for `color`.", + "editType": "none", + "valType": "string" + }, + "description": "Sets the font used for `textinfo`.", + "editType": "plot", + "family": { + "arrayOk": true, + "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The Chart Studio Cloud (at https://chart-studio.plotly.com or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", + "editType": "plot", + "noBlank": true, + "strict": true, + "valType": "string" + }, + "familysrc": { + "description": "Sets the source reference on Chart Studio Cloud for `family`.", + "editType": "none", + "valType": "string" + }, + "lineposition": { + "arrayOk": true, + "description": "Sets the kind of decoration line(s) with text, such as an *under*, *over* or *through* as well as combinations e.g. *under+over*, etc.", + "dflt": "none", + "editType": "plot", + "extras": [ + "none" + ], + "flags": [ + "under", + "over", + "through" + ], + "valType": "flaglist" + }, + "linepositionsrc": { + "description": "Sets the source reference on Chart Studio Cloud for `lineposition`.", + "editType": "none", + "valType": "string" + }, + "role": "object", + "shadow": { + "arrayOk": true, + "description": "Sets the shape and color of the shadow behind text. *auto* places minimal shadow and applies contrast text font color. See https://developer.mozilla.org/en-US/docs/Web/CSS/text-shadow for additional options.", + "dflt": "none", + "editType": "plot", + "valType": "string" + }, + "shadowsrc": { + "description": "Sets the source reference on Chart Studio Cloud for `shadow`.", + "editType": "none", + "valType": "string" + }, + "size": { + "arrayOk": true, + "editType": "plot", + "min": 1, + "valType": "number" + }, + "sizesrc": { + "description": "Sets the source reference on Chart Studio Cloud for `size`.", "editType": "none", + "valType": "string" + }, + "style": { + "arrayOk": true, + "description": "Sets whether a font should be styled with a normal or italic face from its family.", + "dflt": "normal", + "editType": "plot", "valType": "enumerated", "values": [ - "left", - "right", - "auto" + "normal", + "italic" ] }, - "alignsrc": { - "description": "Sets the source reference on Chart Studio Cloud for `align`.", + "stylesrc": { + "description": "Sets the source reference on Chart Studio Cloud for `style`.", "editType": "none", "valType": "string" }, - "bgcolor": { + "textcase": { "arrayOk": true, - "description": "Sets the background color of the hover labels for this trace", + "description": "Sets capitalization of text. It can be used to make text appear in all-uppercase or all-lowercase, or with each word capitalized.", + "dflt": "normal", + "editType": "plot", + "valType": "enumerated", + "values": [ + "normal", + "word caps", + "upper", + "lower" + ] + }, + "textcasesrc": { + "description": "Sets the source reference on Chart Studio Cloud for `textcase`.", "editType": "none", - "valType": "color" + "valType": "string" + }, + "variant": { + "arrayOk": true, + "description": "Sets the variant of the font.", + "dflt": "normal", + "editType": "plot", + "valType": "enumerated", + "values": [ + "normal", + "small-caps", + "all-small-caps", + "all-petite-caps", + "petite-caps", + "unicase" + ] }, - "bgcolorsrc": { - "description": "Sets the source reference on Chart Studio Cloud for `bgcolor`.", + "variantsrc": { + "description": "Sets the source reference on Chart Studio Cloud for `variant`.", "editType": "none", "valType": "string" }, - "bordercolor": { + "weight": { "arrayOk": true, - "description": "Sets the border color of the hover labels for this trace.", - "editType": "none", - "valType": "color" + "description": "Sets the weight (or boldness) of the font.", + "dflt": "normal", + "editType": "plot", + "extras": [ + "normal", + "bold" + ], + "max": 1000, + "min": 1, + "valType": "integer" }, - "bordercolorsrc": { - "description": "Sets the source reference on Chart Studio Cloud for `bordercolor`.", + "weightsrc": { + "description": "Sets the source reference on Chart Studio Cloud for `weight`.", "editType": "none", "valType": "string" - }, + } + }, + "textinfo": { + "description": "Determines which trace information appear on the graph.", + "editType": "calc", + "extras": [ + "none" + ], + "flags": [ + "label", + "text", + "value", + "percent" + ], + "valType": "flaglist" + }, + "textposition": { + "arrayOk": true, + "description": "Specifies the location of the `textinfo`.", + "dflt": "auto", + "editType": "plot", + "valType": "enumerated", + "values": [ + "inside", + "outside", + "auto", + "none" + ] + }, + "textpositionsrc": { + "description": "Sets the source reference on Chart Studio Cloud for `textposition`.", + "editType": "none", + "valType": "string" + }, + "textsrc": { + "description": "Sets the source reference on Chart Studio Cloud for `text`.", + "editType": "none", + "valType": "string" + }, + "texttemplate": { + "arrayOk": true, + "description": "Template string used for rendering the information text that appear on points. Note that this will override `textinfo`. Variables are inserted using %{variable}, for example \"y: %{y}\". Numbers are formatted using d3-format's syntax %{variable:d3-format}, for example \"Price: %{y:$.2f}\". https://github.com/d3/d3-format/tree/v1.4.5#d3-format for details on the formatting syntax. Dates are formatted using d3-time-format's syntax %{variable|d3-time-format}, for example \"Day: %{2019-01-01|%A}\". https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format for details on the date formatting syntax. Every attributes that can be specified per-point (the ones that are `arrayOk: true`) are available. Finally, the template string has access to variables `label`, `color`, `value`, `percent` and `text`.", + "dflt": "", + "editType": "plot", + "valType": "string" + }, + "texttemplatesrc": { + "description": "Sets the source reference on Chart Studio Cloud for `texttemplate`.", "editType": "none", + "valType": "string" + }, + "title": { + "editType": "plot", "font": { "color": { "arrayOk": true, - "editType": "none", + "editType": "plot", "valType": "color" }, "colorsrc": { @@ -62174,12 +60499,12 @@ "editType": "none", "valType": "string" }, - "description": "Sets the font used in hover labels.", - "editType": "none", + "description": "Sets the font used for `title`. Note that the title's font used to be set by the now deprecated `titlefont` attribute.", + "editType": "plot", "family": { "arrayOk": true, "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The Chart Studio Cloud (at https://chart-studio.plotly.com or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", - "editType": "none", + "editType": "plot", "noBlank": true, "strict": true, "valType": "string" @@ -62193,7 +60518,7 @@ "arrayOk": true, "description": "Sets the kind of decoration line(s) with text, such as an *under*, *over* or *through* as well as combinations e.g. *under+over*, etc.", "dflt": "none", - "editType": "none", + "editType": "plot", "extras": [ "none" ], @@ -62214,7 +60539,7 @@ "arrayOk": true, "description": "Sets the shape and color of the shadow behind text. *auto* places minimal shadow and applies contrast text font color. See https://developer.mozilla.org/en-US/docs/Web/CSS/text-shadow for additional options.", "dflt": "none", - "editType": "none", + "editType": "plot", "valType": "string" }, "shadowsrc": { @@ -62223,192 +60548,37 @@ "valType": "string" }, "size": { - "arrayOk": true, - "editType": "none", - "min": 1, - "valType": "number" - }, - "sizesrc": { - "description": "Sets the source reference on Chart Studio Cloud for `size`.", - "editType": "none", - "valType": "string" - }, - "style": { - "arrayOk": true, - "description": "Sets whether a font should be styled with a normal or italic face from its family.", - "dflt": "normal", - "editType": "none", - "valType": "enumerated", - "values": [ - "normal", - "italic" - ] - }, - "stylesrc": { - "description": "Sets the source reference on Chart Studio Cloud for `style`.", - "editType": "none", - "valType": "string" - }, - "textcase": { - "arrayOk": true, - "description": "Sets capitalization of text. It can be used to make text appear in all-uppercase or all-lowercase, or with each word capitalized.", - "dflt": "normal", - "editType": "none", - "valType": "enumerated", - "values": [ - "normal", - "word caps", - "upper", - "lower" - ] - }, - "textcasesrc": { - "description": "Sets the source reference on Chart Studio Cloud for `textcase`.", - "editType": "none", - "valType": "string" - }, - "variant": { - "arrayOk": true, - "description": "Sets the variant of the font.", - "dflt": "normal", - "editType": "none", - "valType": "enumerated", - "values": [ - "normal", - "small-caps", - "all-small-caps", - "all-petite-caps", - "petite-caps", - "unicase" - ] - }, - "variantsrc": { - "description": "Sets the source reference on Chart Studio Cloud for `variant`.", - "editType": "none", - "valType": "string" - }, - "weight": { - "arrayOk": true, - "description": "Sets the weight (or boldness) of the font.", - "dflt": "normal", - "editType": "none", - "extras": [ - "normal", - "bold" - ], - "max": 1000, - "min": 1, - "valType": "integer" - }, - "weightsrc": { - "description": "Sets the source reference on Chart Studio Cloud for `weight`.", - "editType": "none", - "valType": "string" - } - }, - "namelength": { - "arrayOk": true, - "description": "Sets the default length (in number of characters) of the trace name in the hover labels for all traces. -1 shows the whole name regardless of length. 0-3 shows the first 0-3 characters, and an integer >3 will show the whole name if it is less than that many characters, but if it is longer, will truncate to `namelength - 3` characters and add an ellipsis.", - "dflt": 15, - "editType": "none", - "min": -1, - "valType": "integer" - }, - "namelengthsrc": { - "description": "Sets the source reference on Chart Studio Cloud for `namelength`.", - "editType": "none", - "valType": "string" - }, - "role": "object" - }, - "ids": { - "description": "Assigns id labels to each datum. These ids for object constancy of data points during animation. Should be an array of strings, not numbers or any other type.", - "editType": "calc", - "valType": "data_array" - }, - "idssrc": { - "description": "Sets the source reference on Chart Studio Cloud for `ids`.", - "editType": "none", - "valType": "string" - }, - "indices": { - "description": "A sequential value, 0..n, supply it to avoid creating this array inside plotting. If specified, it must be a typed `Int32Array` array. Its length must be equal to or greater than the number of points. For the best performance and memory use, create one large `indices` typed array that is guaranteed to be at least as long as the largest number of points during use, and reuse it on each `Plotly.restyle()` call.", - "editType": "calc", - "valType": "data_array" - }, - "indicessrc": { - "description": "Sets the source reference on Chart Studio Cloud for `indices`.", - "editType": "none", - "valType": "string" - }, - "legend": { - "description": "Sets the reference to a legend to show this trace in. References to these legends are *legend*, *legend2*, *legend3*, etc. Settings for these legends are set in the layout, under `layout.legend`, `layout.legend2`, etc.", - "dflt": "legend", - "editType": "style", - "valType": "subplotid" - }, - "legendgroup": { - "description": "Sets the legend group for this trace. Traces and shapes part of the same legend group hide/show at the same time when toggling legend items.", - "dflt": "", - "editType": "style", - "valType": "string" - }, - "legendgrouptitle": { - "editType": "style", - "font": { - "color": { - "editType": "style", - "valType": "color" - }, - "description": "Sets this legend group's title font.", - "editType": "style", - "family": { - "description": "HTML font family - the typeface that will be applied by the web browser. The web browser will only be able to apply a font if it is available on the system which it operates. Provide multiple font families, separated by commas, to indicate the preference in which to apply fonts if they aren't available on the system. The Chart Studio Cloud (at https://chart-studio.plotly.com or on-premise) generates images on a server, where only a select number of fonts are installed and supported. These include *Arial*, *Balto*, *Courier New*, *Droid Sans*, *Droid Serif*, *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, *PT Sans Narrow*, *Raleway*, *Times New Roman*.", - "editType": "style", - "noBlank": true, - "strict": true, - "valType": "string" - }, - "lineposition": { - "description": "Sets the kind of decoration line(s) with text, such as an *under*, *over* or *through* as well as combinations e.g. *under+over*, etc.", - "dflt": "none", - "editType": "style", - "extras": [ - "none" - ], - "flags": [ - "under", - "over", - "through" - ], - "valType": "flaglist" - }, - "role": "object", - "shadow": { - "description": "Sets the shape and color of the shadow behind text. *auto* places minimal shadow and applies contrast text font color. See https://developer.mozilla.org/en-US/docs/Web/CSS/text-shadow for additional options.", - "dflt": "none", - "editType": "style", - "valType": "string" - }, - "size": { - "editType": "style", + "arrayOk": true, + "editType": "plot", "min": 1, "valType": "number" }, + "sizesrc": { + "description": "Sets the source reference on Chart Studio Cloud for `size`.", + "editType": "none", + "valType": "string" + }, "style": { + "arrayOk": true, "description": "Sets whether a font should be styled with a normal or italic face from its family.", "dflt": "normal", - "editType": "style", + "editType": "plot", "valType": "enumerated", "values": [ "normal", "italic" ] }, + "stylesrc": { + "description": "Sets the source reference on Chart Studio Cloud for `style`.", + "editType": "none", + "valType": "string" + }, "textcase": { + "arrayOk": true, "description": "Sets capitalization of text. It can be used to make text appear in all-uppercase or all-lowercase, or with each word capitalized.", "dflt": "normal", - "editType": "style", + "editType": "plot", "valType": "enumerated", "values": [ "normal", @@ -62417,10 +60587,16 @@ "lower" ] }, + "textcasesrc": { + "description": "Sets the source reference on Chart Studio Cloud for `textcase`.", + "editType": "none", + "valType": "string" + }, "variant": { + "arrayOk": true, "description": "Sets the variant of the font.", "dflt": "normal", - "editType": "style", + "editType": "plot", "valType": "enumerated", "values": [ "normal", @@ -62431,10 +60607,16 @@ "unicase" ] }, + "variantsrc": { + "description": "Sets the source reference on Chart Studio Cloud for `variant`.", + "editType": "none", + "valType": "string" + }, "weight": { + "arrayOk": true, "description": "Sets the weight (or boldness) of the font.", "dflt": "normal", - "editType": "style", + "editType": "plot", "extras": [ "normal", "bold" @@ -62442,148 +60624,46 @@ "max": 1000, "min": 1, "valType": "integer" + }, + "weightsrc": { + "description": "Sets the source reference on Chart Studio Cloud for `weight`.", + "editType": "none", + "valType": "string" } }, + "position": { + "description": "Specifies the location of the `title`. Note that the title's position used to be set by the now deprecated `titleposition` attribute.", + "editType": "plot", + "valType": "enumerated", + "values": [ + "top left", + "top center", + "top right", + "middle center", + "bottom left", + "bottom center", + "bottom right" + ] + }, "role": "object", "text": { - "description": "Sets the title of the legend group.", + "description": "Sets the title of the chart. If it is empty, no title is displayed. Note that before the existence of `title.text`, the title's contents used to be defined as the `title` attribute itself. This behavior has been deprecated.", "dflt": "", - "editType": "style", + "editType": "plot", "valType": "string" } }, - "legendrank": { - "description": "Sets the legend rank for this trace. Items and groups with smaller ranks are presented on top/left side while with *reversed* `legend.traceorder` they are on bottom/right side. The default legendrank is 1000, so that you can use ranks less than 1000 to place certain items before all unranked items, and ranks greater than 1000 to go after all unranked items. When having unranked or equal rank items shapes would be displayed after traces i.e. according to their order in data and layout.", - "dflt": 1000, - "editType": "style", - "valType": "number" - }, - "legendwidth": { - "description": "Sets the width (in px or fraction) of the legend for this trace.", - "editType": "style", - "min": 0, - "valType": "number" - }, - "marker": { - "blend": { - "description": "Determines if colors are blended together for a translucency effect in case `opacity` is specified as a value less then `1`. Setting `blend` to `true` reduces zoom/pan speed if used with large numbers of points.", - "dflt": null, - "editType": "calc", - "valType": "boolean" - }, - "border": { - "arearatio": { - "description": "Specifies what fraction of the marker area is covered with the border.", - "dflt": 0, - "editType": "calc", - "max": 1, - "min": 0, - "valType": "number" - }, - "color": { - "arrayOk": false, - "description": "Sets the stroke color. It accepts a specific color. If the color is not fully opaque and there are hundreds of thousands of points, it may cause slower zooming and panning.", + "transforms": { + "items": { + "transform": { + "description": "WARNING: All transforms are deprecated and may be removed from the API in next major version. An array of operations that manipulate the trace data, for example filtering or sorting the data arrays.", "editType": "calc", - "valType": "color" - }, - "editType": "calc", - "role": "object" - }, - "color": { - "arrayOk": false, - "description": "Sets the marker fill color. It accepts a specific color. If the color is not fully opaque and there are hundreds of thousands of points, it may cause slower zooming and panning.", - "editType": "calc", - "valType": "color" - }, - "editType": "calc", - "opacity": { - "arrayOk": false, - "description": "Sets the marker opacity. The default value is `1` (fully opaque). If the markers are not fully opaque and there are hundreds of thousands of points, it may cause slower zooming and panning. Opacity fades the color even if `blend` is left on `false` even if there is no translucency effect in that case.", - "dflt": 1, - "editType": "calc", - "max": 1, - "min": 0, - "valType": "number" - }, - "role": "object", - "sizemax": { - "description": "Sets the maximum size (in px) of the rendered marker points. Effective when the `pointcloud` shows only few points.", - "dflt": 20, - "editType": "calc", - "min": 0.1, - "valType": "number" - }, - "sizemin": { - "description": "Sets the minimum size (in px) of the rendered marker points, effective when the `pointcloud` shows a million or more points.", - "dflt": 0.5, - "editType": "calc", - "max": 2, - "min": 0.1, - "valType": "number" - } - }, - "meta": { - "arrayOk": true, - "description": "Assigns extra meta information associated with this trace that can be used in various text attributes. Attributes such as trace `name`, graph, axis and colorbar `title.text`, annotation `text` `rangeselector`, `updatemenues` and `sliders` `label` text all support `meta`. To access the trace `meta` values in an attribute in the same trace, simply use `%{meta[i]}` where `i` is the index or key of the `meta` item in question. To access trace `meta` in layout attributes, use `%{data[n[.meta[i]}` where `i` is the index or key of the `meta` and `n` is the trace index.", - "editType": "plot", - "valType": "any" - }, - "metasrc": { - "description": "Sets the source reference on Chart Studio Cloud for `meta`.", - "editType": "none", - "valType": "string" - }, - "name": { - "description": "Sets the trace name. The trace name appears as the legend item and on hover.", - "editType": "style", - "valType": "string" - }, - "opacity": { - "description": "Sets the opacity of the trace.", - "dflt": 1, - "editType": "style", - "max": 1, - "min": 0, - "valType": "number" - }, - "showlegend": { - "description": "Determines whether or not an item corresponding to this trace is shown in the legend.", - "dflt": true, - "editType": "style", - "valType": "boolean" - }, - "stream": { - "editType": "calc", - "maxpoints": { - "description": "Sets the maximum number of points to keep on the plots from an incoming stream. If `maxpoints` is set to *50*, only the newest 50 points will be displayed on the plot.", - "dflt": 500, - "editType": "calc", - "max": 10000, - "min": 0, - "valType": "number" + "role": "object" + } }, - "role": "object", - "token": { - "description": "The stream id number links a data trace on a plot with a stream. See https://chart-studio.plotly.com/settings for more details.", - "editType": "calc", - "noBlank": true, - "strict": true, - "valType": "string" - } - }, - "text": { - "arrayOk": true, - "description": "Sets text elements associated with each (x,y) pair. If a single string, the same string appears over all the data points. If an array of string, the items are mapped in order to the this trace's (x,y) coordinates. If trace `hoverinfo` contains a *text* flag and *hovertext* is not set, these elements will be seen in the hover labels.", - "dflt": "", - "editType": "calc", - "valType": "string" - }, - "textsrc": { - "description": "Sets the source reference on Chart Studio Cloud for `text`.", - "editType": "none", - "valType": "string" + "role": "object" }, - "type": "pointcloud", + "type": "pie", "uid": { "description": "Assign an id to this trace, Use this to provide object constancy between traces during animations and transitions.", "editType": "plot", @@ -62594,6 +60674,16 @@ "editType": "none", "valType": "any" }, + "values": { + "description": "Sets the values of the sectors. If omitted, we count occurrences of each label.", + "editType": "calc", + "valType": "data_array" + }, + "valuessrc": { + "description": "Sets the source reference on Chart Studio Cloud for `values`.", + "editType": "none", + "valType": "string" + }, "visible": { "description": "Determines whether or not this trace is visible. If *legendonly*, the trace is not drawn, but can appear as a legend item (provided that the legend itself is visible).", "dflt": true, @@ -62604,79 +60694,40 @@ false, "legendonly" ] - }, - "x": { - "description": "Sets the x coordinates.", - "editType": "calc+clearAxisTypes", - "valType": "data_array" - }, - "xaxis": { - "description": "Sets a reference between this trace's x coordinates and a 2D cartesian x axis. If *x* (the default value), the x coordinates refer to `layout.xaxis`. If *x2*, the x coordinates refer to `layout.xaxis2`, and so on.", - "dflt": "x", - "editType": "calc+clearAxisTypes", - "valType": "subplotid" - }, - "xbounds": { - "description": "Specify `xbounds` in the shape of `[xMin, xMax] to avoid looping through the `xy` typed array. Use it in conjunction with `xy` and `ybounds` for the performance benefits.", + } + }, + "categories": [ + "pie-like", + "pie", + "showLegend" + ], + "layoutAttributes": { + "extendpiecolors": { + "description": "If `true`, the pie slice colors (whether given by `piecolorway` or inherited from `colorway`) will be extended to three times its original length by first repeating every color 20% lighter then each color 20% darker. This is intended to reduce the likelihood of reusing the same color when you have many slices, but you can set `false` to disable. Colors provided in the trace, using `marker.colors`, are never extended.", + "dflt": true, "editType": "calc", - "valType": "data_array" - }, - "xboundssrc": { - "description": "Sets the source reference on Chart Studio Cloud for `xbounds`.", - "editType": "none", - "valType": "string" - }, - "xsrc": { - "description": "Sets the source reference on Chart Studio Cloud for `x`.", - "editType": "none", - "valType": "string" + "valType": "boolean" }, - "xy": { - "description": "Faster alternative to specifying `x` and `y` separately. If supplied, it must be a typed `Float32Array` array that represents points such that `xy[i * 2] = x[i]` and `xy[i * 2 + 1] = y[i]`", + "hiddenlabels": { + "description": "hiddenlabels is the funnelarea & pie chart analog of visible:'legendonly' but it can contain many labels, and can simultaneously hide slices from several pies/funnelarea charts", "editType": "calc", "valType": "data_array" }, - "xysrc": { - "description": "Sets the source reference on Chart Studio Cloud for `xy`.", + "hiddenlabelssrc": { + "description": "Sets the source reference on Chart Studio Cloud for `hiddenlabels`.", "editType": "none", "valType": "string" }, - "y": { - "description": "Sets the y coordinates.", - "editType": "calc+clearAxisTypes", - "valType": "data_array" - }, - "yaxis": { - "description": "Sets a reference between this trace's y coordinates and a 2D cartesian y axis. If *y* (the default value), the y coordinates refer to `layout.yaxis`. If *y2*, the y coordinates refer to `layout.yaxis2`, and so on.", - "dflt": "y", - "editType": "calc+clearAxisTypes", - "valType": "subplotid" - }, - "ybounds": { - "description": "Specify `ybounds` in the shape of `[yMin, yMax] to avoid looping through the `xy` typed array. Use it in conjunction with `xy` and `xbounds` for the performance benefits.", + "piecolorway": { + "description": "Sets the default pie slice colors. Defaults to the main `colorway` used for trace colors. If you specify a new list here it can still be extended with lighter and darker colors, see `extendpiecolors`.", "editType": "calc", - "valType": "data_array" - }, - "yboundssrc": { - "description": "Sets the source reference on Chart Studio Cloud for `ybounds`.", - "editType": "none", - "valType": "string" - }, - "ysrc": { - "description": "Sets the source reference on Chart Studio Cloud for `y`.", - "editType": "none", - "valType": "string" + "valType": "colorlist" } }, - "categories": [ - "gl", - "gl2d", - "showLegend" - ], "meta": { - "description": "*pointcloud* trace is deprecated! Please consider switching to the *scattergl* trace type. The data visualized as a point cloud set in `x` and `y` using the WebGl plotting engine." + "description": "A data visualized by the sectors of the pie is set in `values`. The sector labels are set in `labels`. The sector colors are set in `marker.colors`" }, - "type": "pointcloud" + "type": "pie" }, "sankey": { "animatable": false, From b973055e472cedab891b9b1abd627af1eafc890c Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Mon, 7 Oct 2024 15:32:13 -0400 Subject: [PATCH 02/23] update baselines with new order on CI --- test/image/baselines/icicle_textposition.png | Bin 192793 -> 192801 bytes test/image/baselines/pattern_bars.png | Bin 156189 -> 156236 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/test/image/baselines/icicle_textposition.png b/test/image/baselines/icicle_textposition.png index 1c1fbfc12a890bf8347ce82711ddacc36882e3b0..57f5c6e3ca62c60583e53f8aad7b73f0fa1ff929 100644 GIT binary patch delta 23461 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 BT5FZPo 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 OgGf)yShGR{75P6gA`fH$ delta 23435 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⪙b|Al2vlerXHz=Sqvcz=F4JiaC2 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 delta 83308 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 From c8771798c5bf533f753e0e9ad9f3a24f1cc3e79d Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Mon, 7 Oct 2024 15:59:38 -0400 Subject: [PATCH 03/23] draft log --- draftlogs/7213_change.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 draftlogs/7213_change.md diff --git a/draftlogs/7213_change.md b/draftlogs/7213_change.md new file mode 100644 index 00000000000..6d6ebeb5414 --- /dev/null +++ b/draftlogs/7213_change.md @@ -0,0 +1 @@ + - Drop deprecated pointcloud and heatmapgl traces and gl2d subplots [[#7213](https://github.com/plotly/plotly.js/pull/7213)] From fce04c90af86c4f376f443a8204d904359a10b6a Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Mon, 7 Oct 2024 16:17:38 -0400 Subject: [PATCH 04/23] uninstall unused stackgl packages --- stackgl_modules/main.js | 5 -- stackgl_modules/package-lock.json | 137 ------------------------------ stackgl_modules/package.json | 5 -- 3 files changed, 147 deletions(-) diff --git a/stackgl_modules/main.js b/stackgl_modules/main.js index 35eb932315d..fdf37ac4dc8 100644 --- a/stackgl_modules/main.js +++ b/stackgl_modules/main.js @@ -4,15 +4,10 @@ module.exports = { delaunay_triangulate: require('delaunay-triangulate'), gl_cone3d: require('gl-cone3d'), gl_error3d: require('gl-error3d'), - gl_heatmap2d: require('gl-heatmap2d'), gl_line3d: require('gl-line3d'), gl_mesh3d: require('gl-mesh3d'), - gl_plot2d: require('gl-plot2d'), gl_plot3d: require('gl-plot3d'), - gl_pointcloud2d: require('gl-pointcloud2d'), gl_scatter3d: require('gl-scatter3d'), - gl_select_box: require('gl-select-box'), - gl_spikes2d: require('gl-spikes2d'), gl_streamtube3d: require('gl-streamtube3d'), gl_surface3d: require('gl-surface3d'), ndarray: require('ndarray'), diff --git a/stackgl_modules/package-lock.json b/stackgl_modules/package-lock.json index ca7058ead56..36a0e2eced6 100644 --- a/stackgl_modules/package-lock.json +++ b/stackgl_modules/package-lock.json @@ -13,16 +13,11 @@ "gl-axes3d": "^1.7.1", "gl-cone3d": "^1.6.1", "gl-error3d": "^1.0.17", - "gl-heatmap2d": "^1.1.1", "gl-line3d": "^1.2.2", "gl-mesh3d": "^2.3.2", - "gl-plot2d": "^1.5.0", "gl-plot3d": "^2.4.7", - "gl-pointcloud2d": "^1.0.3", "gl-scatter3d": "^1.4.1", - "gl-select-box": "^1.0.4", "gl-shader": "4.3.1", - "gl-spikes2d": "^1.0.2", "gl-spikes3d": "^1.0.11", "gl-streamtube3d": "^1.4.2", "gl-surface3d": "^1.6.2", @@ -3775,19 +3770,6 @@ "sprintf-js": "^1.0.3" } }, - "node_modules/gl-heatmap2d": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/gl-heatmap2d/-/gl-heatmap2d-1.1.1.tgz", - "integrity": "sha512-6Vo1fPIB1vQFWBA/MR6JAA16XuQuhwvZRbSjYEq++m4QV33iqjGS2HcVIRfJGX+fomd5eiz6bwkVZcKm69zQPw==", - "dependencies": { - "binary-search-bounds": "^2.0.4", - "gl-buffer": "^2.1.2", - "gl-shader": "^4.2.1", - "glslify": "^7.0.0", - "iota-array": "^1.0.0", - "typedarray-pool": "^1.2.0" - } - }, "node_modules/gl-line3d": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/gl-line3d/-/gl-line3d-1.2.2.tgz", @@ -3835,20 +3817,6 @@ "typedarray-pool": "^1.1.0" } }, - "node_modules/gl-plot2d": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/gl-plot2d/-/gl-plot2d-1.5.0.tgz", - "integrity": "sha512-zOv9CU+Gm8vPSUM8Rm/9Ymzuk9RUMfk0ol0ewe6TUF83rGCN/ZRr+xTHoXigI1N0lQ7nfnj+m1raPn7VFTu2IA==", - "dependencies": { - "binary-search-bounds": "^2.0.4", - "gl-buffer": "^2.1.2", - "gl-select-static": "^2.0.7", - "gl-shader": "^4.2.1", - "glsl-inverse": "^1.0.0", - "glslify": "^7.0.0", - "text-cache": "^4.3.0" - } - }, "node_modules/gl-plot3d": { "version": "2.4.7", "resolved": "https://registry.npmjs.org/gl-plot3d/-/gl-plot3d-2.4.7.tgz", @@ -3872,17 +3840,6 @@ "right-now": "^1.0.0" } }, - "node_modules/gl-pointcloud2d": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/gl-pointcloud2d/-/gl-pointcloud2d-1.0.3.tgz", - "integrity": "sha512-OS2e1irvJXVRpg/GziXj10xrFJm9kkRfFoB6BLUvkjCQV7ZRNNcs2CD+YSK1r0gvMwTg2T3lfLM3UPwNtz+4Xw==", - "dependencies": { - "gl-buffer": "^2.1.2", - "gl-shader": "^4.2.1", - "glslify": "^7.0.0", - "typedarray-pool": "^1.1.0" - } - }, "node_modules/gl-quat": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/gl-quat/-/gl-quat-1.0.0.tgz", @@ -3909,16 +3866,6 @@ "vectorize-text": "^3.2.1" } }, - "node_modules/gl-select-box": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/gl-select-box/-/gl-select-box-1.0.4.tgz", - "integrity": "sha512-mKsCnglraSKyBbQiGq0Ila0WF+m6Tr+EWT2yfaMn/Sh9aMHq5Wt0F/l6Cf/Ed3CdERq5jHWAY5yxLviZteYu2w==", - "dependencies": { - "gl-buffer": "^2.1.2", - "gl-shader": "^4.2.1", - "glslify": "^7.0.0" - } - }, "node_modules/gl-select-static": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/gl-select-static/-/gl-select-static-2.0.7.tgz", @@ -3939,11 +3886,6 @@ "weakmap-shim": "^1.1.0" } }, - "node_modules/gl-spikes2d": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/gl-spikes2d/-/gl-spikes2d-1.0.2.tgz", - "integrity": "sha512-QVeOZsi9nQuJJl7NB3132CCv5KA10BWxAY2QgJNsKqbLsG53B/TrGJpjIAohnJftdZ4fT6b3ZojWgeaXk8bOOA==" - }, "node_modules/gl-spikes3d": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/gl-spikes3d/-/gl-spikes3d-1.0.11.tgz", @@ -4514,11 +4456,6 @@ "binary-search-bounds": "^2.0.0" } }, - "node_modules/iota-array": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/iota-array/-/iota-array-1.0.0.tgz", - "integrity": "sha1-ge9X/l0FgUzVjCSDYyqZwwoOgIc=" - }, "node_modules/is-arguments": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", @@ -6315,14 +6252,6 @@ "node": ">=0.4.0" } }, - "node_modules/text-cache": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/text-cache/-/text-cache-4.3.0.tgz", - "integrity": "sha512-FM1X6SZwuGy5hgTJvl4SyFENUbLrujUUjb9bsLtz54HTqCasidnk7EfXjZkij0dhEFTD8J6LsYbNUN3KpyKYpg==", - "dependencies": { - "vectorize-text": "^3.2.1" - } - }, "node_modules/through2": { "version": "0.6.5", "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", @@ -9718,19 +9647,6 @@ "sprintf-js": "^1.0.3" } }, - "gl-heatmap2d": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/gl-heatmap2d/-/gl-heatmap2d-1.1.1.tgz", - "integrity": "sha512-6Vo1fPIB1vQFWBA/MR6JAA16XuQuhwvZRbSjYEq++m4QV33iqjGS2HcVIRfJGX+fomd5eiz6bwkVZcKm69zQPw==", - "requires": { - "binary-search-bounds": "^2.0.4", - "gl-buffer": "^2.1.2", - "gl-shader": "^4.2.1", - "glslify": "^7.0.0", - "iota-array": "^1.0.0", - "typedarray-pool": "^1.2.0" - } - }, "gl-line3d": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/gl-line3d/-/gl-line3d-1.2.2.tgz", @@ -9778,20 +9694,6 @@ "typedarray-pool": "^1.1.0" } }, - "gl-plot2d": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/gl-plot2d/-/gl-plot2d-1.5.0.tgz", - "integrity": "sha512-zOv9CU+Gm8vPSUM8Rm/9Ymzuk9RUMfk0ol0ewe6TUF83rGCN/ZRr+xTHoXigI1N0lQ7nfnj+m1raPn7VFTu2IA==", - "requires": { - "binary-search-bounds": "^2.0.4", - "gl-buffer": "^2.1.2", - "gl-select-static": "^2.0.7", - "gl-shader": "^4.2.1", - "glsl-inverse": "^1.0.0", - "glslify": "^7.0.0", - "text-cache": "^4.3.0" - } - }, "gl-plot3d": { "version": "2.4.7", "resolved": "https://registry.npmjs.org/gl-plot3d/-/gl-plot3d-2.4.7.tgz", @@ -9815,17 +9717,6 @@ "right-now": "^1.0.0" } }, - "gl-pointcloud2d": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/gl-pointcloud2d/-/gl-pointcloud2d-1.0.3.tgz", - "integrity": "sha512-OS2e1irvJXVRpg/GziXj10xrFJm9kkRfFoB6BLUvkjCQV7ZRNNcs2CD+YSK1r0gvMwTg2T3lfLM3UPwNtz+4Xw==", - "requires": { - "gl-buffer": "^2.1.2", - "gl-shader": "^4.2.1", - "glslify": "^7.0.0", - "typedarray-pool": "^1.1.0" - } - }, "gl-quat": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/gl-quat/-/gl-quat-1.0.0.tgz", @@ -9852,16 +9743,6 @@ "vectorize-text": "^3.2.1" } }, - "gl-select-box": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/gl-select-box/-/gl-select-box-1.0.4.tgz", - "integrity": "sha512-mKsCnglraSKyBbQiGq0Ila0WF+m6Tr+EWT2yfaMn/Sh9aMHq5Wt0F/l6Cf/Ed3CdERq5jHWAY5yxLviZteYu2w==", - "requires": { - "gl-buffer": "^2.1.2", - "gl-shader": "^4.2.1", - "glslify": "^7.0.0" - } - }, "gl-select-static": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/gl-select-static/-/gl-select-static-2.0.7.tgz", @@ -9882,11 +9763,6 @@ "weakmap-shim": "^1.1.0" } }, - "gl-spikes2d": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/gl-spikes2d/-/gl-spikes2d-1.0.2.tgz", - "integrity": "sha512-QVeOZsi9nQuJJl7NB3132CCv5KA10BWxAY2QgJNsKqbLsG53B/TrGJpjIAohnJftdZ4fT6b3ZojWgeaXk8bOOA==" - }, "gl-spikes3d": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/gl-spikes3d/-/gl-spikes3d-1.0.11.tgz", @@ -10385,11 +10261,6 @@ "binary-search-bounds": "^2.0.0" } }, - "iota-array": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/iota-array/-/iota-array-1.0.0.tgz", - "integrity": "sha1-ge9X/l0FgUzVjCSDYyqZwwoOgIc=" - }, "is-arguments": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", @@ -11896,14 +11767,6 @@ "terser": "^5.26.0" } }, - "text-cache": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/text-cache/-/text-cache-4.3.0.tgz", - "integrity": "sha512-FM1X6SZwuGy5hgTJvl4SyFENUbLrujUUjb9bsLtz54HTqCasidnk7EfXjZkij0dhEFTD8J6LsYbNUN3KpyKYpg==", - "requires": { - "vectorize-text": "^3.2.1" - } - }, "through2": { "version": "0.6.5", "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", diff --git a/stackgl_modules/package.json b/stackgl_modules/package.json index 16b5deae50e..c066f087ee1 100644 --- a/stackgl_modules/package.json +++ b/stackgl_modules/package.json @@ -16,16 +16,11 @@ "gl-axes3d": "^1.7.1", "gl-cone3d": "^1.6.1", "gl-error3d": "^1.0.17", - "gl-heatmap2d": "^1.1.1", "gl-line3d": "^1.2.2", "gl-mesh3d": "^2.3.2", - "gl-plot2d": "^1.5.0", "gl-plot3d": "^2.4.7", - "gl-pointcloud2d": "^1.0.3", "gl-scatter3d": "^1.4.1", - "gl-select-box": "^1.0.4", "gl-shader": "4.3.1", - "gl-spikes2d": "^1.0.2", "gl-spikes3d": "^1.0.11", "gl-streamtube3d": "^1.4.2", "gl-surface3d": "^1.6.2", From dc148477118bb303adbe1a8cbcdff411a58bd6a4 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Mon, 7 Oct 2024 16:18:27 -0400 Subject: [PATCH 05/23] rebuild stackgl index --- stackgl_modules/index.js | 2320 +------------------------------------- 1 file changed, 6 insertions(+), 2314 deletions(-) diff --git a/stackgl_modules/index.js b/stackgl_modules/index.js index dca35add9ad..f0411fed5ef 100644 --- a/stackgl_modules/index.js +++ b/stackgl_modules/index.js @@ -10,15 +10,10 @@ module.exports = { delaunay_triangulate: __webpack_require__(7642), gl_cone3d: __webpack_require__(6405), gl_error3d: __webpack_require__(9165), - gl_heatmap2d: __webpack_require__(2510), gl_line3d: __webpack_require__(5714), gl_mesh3d: __webpack_require__(7201), - gl_plot2d: __webpack_require__(1850), gl_plot3d: __webpack_require__(4100), - gl_pointcloud2d: __webpack_require__(4696), gl_scatter3d: __webpack_require__(8418), - gl_select_box: __webpack_require__(3161), - gl_spikes2d: __webpack_require__(4098), gl_streamtube3d: __webpack_require__(7815), gl_surface3d: __webpack_require__(9499), ndarray: __webpack_require__(9618), @@ -1837,7 +1832,7 @@ module.exports = createViewController var createTurntable = __webpack_require__(7261) var createOrbit = __webpack_require__(9977) -var createMatrix = __webpack_require__(4192) +var createMatrix = __webpack_require__(1811) function ViewController(controllers, mode) { this._controllerNames = Object.keys(controllers) @@ -2426,7 +2421,7 @@ function div(a, b) { var isRat = __webpack_require__(6330) var isBN = __webpack_require__(1533) var num2bn = __webpack_require__(2651) -var str2bn = __webpack_require__(4387) +var str2bn = __webpack_require__(6768) var rationalize = __webpack_require__(869) var div = __webpack_require__(8697) @@ -2653,7 +2648,7 @@ function rationalize(numer, denom) { /***/ }), -/***/ 4387: +/***/ 6768: /***/ (function(module, __unused_webpack_exports, __webpack_require__) { "use strict"; @@ -7603,7 +7598,7 @@ function lo_lessThan_p0_and_p1_lessThan_hi(a, b, c, d, e, f, p0, p1) { /***/ }), -/***/ 1811: +/***/ 4192: /***/ (function(module) { "use strict"; @@ -7862,7 +7857,7 @@ module.exports = { var pool = __webpack_require__(1888) var bits = __webpack_require__(8828) -var isort = __webpack_require__(1811) +var isort = __webpack_require__(4192) //Flag for blue var BLUE_FLAG = (1<<28) @@ -15715,382 +15710,6 @@ function formatCompilerError(errLog, src, type) { -/***/ }), - -/***/ 2510: -/***/ (function(module, __unused_webpack_exports, __webpack_require__) { - -"use strict"; - - -module.exports = createHeatmap2D - -var bsearch = __webpack_require__(2478) -var iota = __webpack_require__(7762) -var pool = __webpack_require__(1888) -var createShader = __webpack_require__(9405) -var createBuffer = __webpack_require__(2762) - -var shaders = __webpack_require__(6768) - -function GLHeatmap2D ( - plot, - shader, - pickShader, - positionBuffer, - weightBuffer, - colorBuffer, - idBuffer) { - this.plot = plot - this.shader = shader - this.pickShader = pickShader - this.positionBuffer = positionBuffer - this.weightBuffer = weightBuffer - this.colorBuffer = colorBuffer - this.idBuffer = idBuffer - this.xData = [] - this.yData = [] - this.shape = [0, 0] - this.bounds = [Infinity, Infinity, -Infinity, -Infinity] - this.pickOffset = 0 -} - -var proto = GLHeatmap2D.prototype - -var WEIGHTS = [ - 0, 0, - 1, 0, - 0, 1, - 1, 0, - 1, 1, - 0, 1 -] - -proto.draw = (function () { - var MATRIX = [ - 1, 0, 0, - 0, 1, 0, - 0, 0, 1 - ] - - return function () { - var plot = this.plot - var shader = this.shader - var bounds = this.bounds - var numVertices = this.numVertices - - if (numVertices <= 0) { - return - } - - var gl = plot.gl - var dataBox = plot.dataBox - - var boundX = bounds[2] - bounds[0] - var boundY = bounds[3] - bounds[1] - var dataX = dataBox[2] - dataBox[0] - var dataY = dataBox[3] - dataBox[1] - - MATRIX[0] = 2.0 * boundX / dataX - MATRIX[4] = 2.0 * boundY / dataY - MATRIX[6] = 2.0 * (bounds[0] - dataBox[0]) / dataX - 1.0 - MATRIX[7] = 2.0 * (bounds[1] - dataBox[1]) / dataY - 1.0 - - shader.bind() - - var uniforms = shader.uniforms - uniforms.viewTransform = MATRIX - - uniforms.shape = this.shape - - var attributes = shader.attributes - this.positionBuffer.bind() - attributes.position.pointer() - - this.weightBuffer.bind() - attributes.weight.pointer(gl.UNSIGNED_BYTE, false) - - this.colorBuffer.bind() - attributes.color.pointer(gl.UNSIGNED_BYTE, true) - - gl.drawArrays(gl.TRIANGLES, 0, numVertices) - } -})() - -proto.drawPick = (function () { - var MATRIX = [ - 1, 0, 0, - 0, 1, 0, - 0, 0, 1 - ] - - var PICK_VECTOR = [0, 0, 0, 0] - - return function (pickOffset) { - var plot = this.plot - var shader = this.pickShader - var bounds = this.bounds - var numVertices = this.numVertices - - if (numVertices <= 0) { - return - } - - var gl = plot.gl - var dataBox = plot.dataBox - - var boundX = bounds[2] - bounds[0] - var boundY = bounds[3] - bounds[1] - var dataX = dataBox[2] - dataBox[0] - var dataY = dataBox[3] - dataBox[1] - - MATRIX[0] = 2.0 * boundX / dataX - MATRIX[4] = 2.0 * boundY / dataY - MATRIX[6] = 2.0 * (bounds[0] - dataBox[0]) / dataX - 1.0 - MATRIX[7] = 2.0 * (bounds[1] - dataBox[1]) / dataY - 1.0 - - for (var i = 0; i < 4; ++i) { - PICK_VECTOR[i] = (pickOffset >> (i * 8)) & 0xff - } - - this.pickOffset = pickOffset - - shader.bind() - - var uniforms = shader.uniforms - uniforms.viewTransform = MATRIX - uniforms.pickOffset = PICK_VECTOR - uniforms.shape = this.shape - - var attributes = shader.attributes - this.positionBuffer.bind() - attributes.position.pointer() - - this.weightBuffer.bind() - attributes.weight.pointer(gl.UNSIGNED_BYTE, false) - - this.idBuffer.bind() - attributes.pickId.pointer(gl.UNSIGNED_BYTE, false) - - gl.drawArrays(gl.TRIANGLES, 0, numVertices) - - return pickOffset + this.shape[0] * this.shape[1] - } -})() - -proto.pick = function (x, y, value) { - var pickOffset = this.pickOffset - var pointCount = this.shape[0] * this.shape[1] - if (value < pickOffset || value >= pickOffset + pointCount) { - return null - } - var pointId = value - pickOffset - var xData = this.xData - var yData = this.yData - return { - object: this, - pointId: pointId, - dataCoord: [ - xData[pointId % this.shape[0]], - yData[(pointId / this.shape[0]) | 0]] - } -} - -proto.update = function (options) { - options = options || {} - - var shape = options.shape || [0, 0] - - var x = options.x || iota(shape[0]) - var y = options.y || iota(shape[1]) - var z = options.z || new Float32Array(shape[0] * shape[1]) - - var isSmooth = options.zsmooth !== false - - this.xData = x - this.yData = y - - var colorLevels = options.colorLevels || [0] - var colorValues = options.colorValues || [0, 0, 0, 1] - var colorCount = colorLevels.length - - var bounds = this.bounds - var lox, loy, hix, hiy - if (isSmooth) { - lox = bounds[0] = x[0] - loy = bounds[1] = y[0] - hix = bounds[2] = x[x.length - 1] - hiy = bounds[3] = y[y.length - 1] - } else { - // To get squares to centre on data values - lox = bounds[0] = x[0] + (x[1] - x[0]) / 2 // starting x value - loy = bounds[1] = y[0] + (y[1] - y[0]) / 2 // starting y value - - // Bounds needs to add half a square on each end - hix = bounds[2] = x[x.length - 1] + (x[x.length - 1] - x[x.length - 2]) / 2 - hiy = bounds[3] = y[y.length - 1] + (y[y.length - 1] - y[y.length - 2]) / 2 - - // N.B. Resolution = 1 / range - } - var xs = 1.0 / (hix - lox) - var ys = 1.0 / (hiy - loy) - - var numX = shape[0] - var numY = shape[1] - - this.shape = [numX, numY] - - var numVerts = ( - isSmooth ? (numX - 1) * (numY - 1) : numX * numY - ) * (WEIGHTS.length >>> 1) - - this.numVertices = numVerts - - var colors = pool.mallocUint8(numVerts * 4) - var positions = pool.mallocFloat32(numVerts * 2) - var weights = pool.mallocUint8 (numVerts * 2) - var ids = pool.mallocUint32(numVerts) - - var ptr = 0 - - var ni = isSmooth ? numX - 1 : numX - var nj = isSmooth ? numY - 1 : numY - - for (var j = 0; j < nj; ++j) { - var yc0, yc1 - - if (isSmooth) { - yc0 = ys * (y[j] - loy) - yc1 = ys * (y[j + 1] - loy) - } else { - yc0 = j < numY - 1 ? ys * (y[j] - (y[j + 1] - y[j])/2 - loy) : ys * (y[j] - (y[j] - y[j - 1])/2 - loy) - yc1 = j < numY - 1 ? ys * (y[j] + (y[j + 1] - y[j])/2 - loy) : ys * (y[j] + (y[j] - y[j - 1])/2 - loy) - } - - for (var i = 0; i < ni; ++i) { - var xc0, xc1 - - if (isSmooth) { - xc0 = xs * (x[i] - lox) - xc1 = xs * (x[i + 1] - lox) - } else { - xc0 = i < numX - 1 ? xs * (x[i] - (x[i + 1] - x[i])/2 - lox) : xs * (x[i] - (x[i] - x[i - 1])/2 - lox) - xc1 = i < numX - 1 ? xs * (x[i] + (x[i + 1] - x[i])/2 - lox) : xs * (x[i] + (x[i] - x[i - 1])/2 - lox) - } - - for (var dd = 0; dd < WEIGHTS.length; dd += 2) { - var dx = WEIGHTS[dd] - var dy = WEIGHTS[dd + 1] - var offset = isSmooth ? (j + dy) * numX + (i + dx) : j * numX + i - var zc = z[offset] - var colorIdx = bsearch.le(colorLevels, zc) - var r, g, b, a - if (colorIdx < 0) { - r = colorValues[0] - g = colorValues[1] - b = colorValues[2] - a = colorValues[3] - } else if (colorIdx === colorCount - 1) { - r = colorValues[4 * colorCount - 4] - g = colorValues[4 * colorCount - 3] - b = colorValues[4 * colorCount - 2] - a = colorValues[4 * colorCount - 1] - } else { - var t = (zc - colorLevels[colorIdx]) / - (colorLevels[colorIdx + 1] - colorLevels[colorIdx]) - var ti = 1.0 - t - var i0 = 4 * colorIdx - var i1 = 4 * (colorIdx + 1) - r = ti * colorValues[i0] + t * colorValues[i1] - g = ti * colorValues[i0 + 1] + t * colorValues[i1 + 1] - b = ti * colorValues[i0 + 2] + t * colorValues[i1 + 2] - a = ti * colorValues[i0 + 3] + t * colorValues[i1 + 3] - } - - colors[4 * ptr] = 255 * r - colors[4 * ptr + 1] = 255 * g - colors[4 * ptr + 2] = 255 * b - colors[4 * ptr + 3] = 255 * a - - positions[2*ptr] = xc0*.5 + xc1*.5; - positions[2*ptr+1] = yc0*.5 + yc1*.5; - - weights[2*ptr] = dx; - weights[2*ptr+1] = dy; - - ids[ptr] = j * numX + i - - ptr += 1 - } - } - } - - this.positionBuffer.update(positions) - this.weightBuffer.update(weights) - this.colorBuffer.update(colors) - this.idBuffer.update(ids) - - pool.free(positions) - pool.free(colors) - pool.free(weights) - pool.free(ids) -} - -proto.dispose = function () { - this.shader.dispose() - this.pickShader.dispose() - this.positionBuffer.dispose() - this.weightBuffer.dispose() - this.colorBuffer.dispose() - this.idBuffer.dispose() - this.plot.removeObject(this) -} - -function createHeatmap2D (plot, options) { - var gl = plot.gl - - var shader = createShader(gl, shaders.vertex, shaders.fragment) - var pickShader = createShader(gl, shaders.pickVertex, shaders.pickFragment) - - var positionBuffer = createBuffer(gl) - var weightBuffer = createBuffer(gl) - var colorBuffer = createBuffer(gl) - var idBuffer = createBuffer(gl) - - var heatmap = new GLHeatmap2D( - plot, - shader, - pickShader, - positionBuffer, - weightBuffer, - colorBuffer, - idBuffer) - - heatmap.update(options) - plot.addObject(heatmap) - - return heatmap -} - - -/***/ }), - -/***/ 6768: -/***/ (function(module, __unused_webpack_exports, __webpack_require__) { - -"use strict"; - - -var glslify = __webpack_require__(3236) - -module.exports = { - fragment: glslify(["precision lowp float;\n#define GLSLIFY 1\nvarying vec4 fragColor;\nvoid main() {\n gl_FragColor = vec4(fragColor.rgb * fragColor.a, fragColor.a);\n}\n"]), - vertex: glslify(["precision mediump float;\n#define GLSLIFY 1\n\nattribute vec2 position;\nattribute vec4 color;\nattribute vec2 weight;\n\nuniform vec2 shape;\nuniform mat3 viewTransform;\n\nvarying vec4 fragColor;\n\nvoid main() {\n vec3 vPosition = viewTransform * vec3( position + (weight-.5)/(shape-1.) , 1.0);\n fragColor = color;\n gl_Position = vec4(vPosition.xy, 0, vPosition.z);\n}\n"]), - pickFragment: glslify(["precision mediump float;\n#define GLSLIFY 1\n\nvarying vec4 fragId;\nvarying vec2 vWeight;\n\nuniform vec2 shape;\nuniform vec4 pickOffset;\n\nvoid main() {\n vec2 d = step(.5, vWeight);\n vec4 id = fragId + pickOffset;\n id.x += d.x + d.y*shape.x;\n\n id.y += floor(id.x / 256.0);\n id.x -= floor(id.x / 256.0) * 256.0;\n\n id.z += floor(id.y / 256.0);\n id.y -= floor(id.y / 256.0) * 256.0;\n\n id.w += floor(id.z / 256.0);\n id.z -= floor(id.z / 256.0) * 256.0;\n\n gl_FragColor = id/255.;\n}\n"]), - pickVertex: glslify(["precision mediump float;\n#define GLSLIFY 1\n\nattribute vec2 position;\nattribute vec4 pickId;\nattribute vec2 weight;\n\nuniform vec2 shape;\nuniform mat3 viewTransform;\n\nvarying vec4 fragId;\nvarying vec2 vWeight;\n\nvoid main() {\n vWeight = weight;\n\n fragId = pickId;\n\n vec3 vPosition = viewTransform * vec3( position + (weight-.5)/(shape-1.) , 1.0);\n gl_Position = vec4(vPosition.xy, 0, vPosition.z);\n}\n"]) -} - - /***/ }), /***/ 7319: @@ -18712,1320 +18331,6 @@ function createSimplicialMesh(gl, params) { module.exports = createSimplicialMesh -/***/ }), - -/***/ 8120: -/***/ (function(module, __unused_webpack_exports, __webpack_require__) { - -"use strict"; - - -module.exports = createBoxes - -var createBuffer = __webpack_require__(2762) -var createShader = __webpack_require__(9405) - -var shaders = __webpack_require__(3603) - -function Boxes(plot, vbo, shader) { - this.plot = plot - this.vbo = vbo - this.shader = shader -} - -var proto = Boxes.prototype - -proto.bind = function() { - var shader = this.shader - this.vbo.bind() - this.shader.bind() - shader.attributes.coord.pointer() - shader.uniforms.screenBox = this.plot.screenBox -} - -proto.drawBox = (function() { - var lo = [0,0] - var hi = [0,0] - return function(loX, loY, hiX, hiY, color) { - var plot = this.plot - var shader = this.shader - var gl = plot.gl - - lo[0] = loX - lo[1] = loY - hi[0] = hiX - hi[1] = hiY - - shader.uniforms.lo = lo - shader.uniforms.hi = hi - shader.uniforms.color = color - - gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4) - } -}()) - -proto.dispose = function() { - this.vbo.dispose() - this.shader.dispose() -} - -function createBoxes(plot) { - var gl = plot.gl - var vbo = createBuffer(gl, [ - 0,0, - 0,1, - 1,0, - 1,1]) - var shader = createShader(gl, shaders.boxVert, shaders.lineFrag) - return new Boxes(plot, vbo, shader) -} - - -/***/ }), - -/***/ 1913: -/***/ (function(module, __unused_webpack_exports, __webpack_require__) { - -"use strict"; - - -module.exports = createGrid - -var createBuffer = __webpack_require__(2762) -var createShader = __webpack_require__(9405) -var bsearch = __webpack_require__(2478) -var shaders = __webpack_require__(3603) - -function Grid(plot, vbo, shader, tickShader) { - this.plot = plot - this.vbo = vbo - this.shader = shader - this.tickShader = tickShader - this.ticks = [[], []] -} - -function compareTickNum(a, b) { - return a - b -} - -var proto = Grid.prototype - -proto.draw = (function() { - - var DATA_SHIFT = [0,0] - var DATA_SCALE = [0,0] - var DATA_AXIS = [0,0] - - return function() { - var plot = this.plot - var vbo = this.vbo - var shader = this.shader - var ticks = this.ticks - var gl = plot.gl - var bounds = plot._tickBounds - var dataBox = plot.dataBox - var viewPixels = plot.viewBox - var lineWidth = plot.gridLineWidth - var gridColor = plot.gridLineColor - var gridEnable = plot.gridLineEnable - var pixelRatio = plot.pixelRatio - - for(var i=0; i<2; ++i) { - var lo = bounds[i] - var hi = bounds[i+2] - var boundScale = hi - lo - var dataCenter = 0.5 * (dataBox[i+2] + dataBox[i]) - var dataWidth = dataBox[i+2] - dataBox[i] - DATA_SCALE[i] = 2.0 * boundScale / dataWidth - DATA_SHIFT[i] = 2.0 * (lo - dataCenter) / dataWidth - } - - shader.bind() - vbo.bind() - shader.attributes.dataCoord.pointer() - shader.uniforms.dataShift = DATA_SHIFT - shader.uniforms.dataScale = DATA_SCALE - - var offset = 0 - for(var i=0; i<2; ++i) { - DATA_AXIS[0] = DATA_AXIS[1] = 0 - DATA_AXIS[i] = 1 - shader.uniforms.dataAxis = DATA_AXIS - shader.uniforms.lineWidth = lineWidth[i] / (viewPixels[i+2] - viewPixels[i]) * pixelRatio - shader.uniforms.color = gridColor[i] - - var size = ticks[i].length * 6 - if(gridEnable[i] && size) { - gl.drawArrays(gl.TRIANGLES, offset, size) - } - offset += size - } - } -})() - -proto.drawTickMarks = (function() { - var DATA_SHIFT = [0,0] - var DATA_SCALE = [0,0] - var X_AXIS = [1,0] - var Y_AXIS = [0,1] - var SCR_OFFSET = [0,0] - var TICK_SCALE = [0,0] - - return function() { - var plot = this.plot - var vbo = this.vbo - var shader = this.tickShader - var ticks = this.ticks - var gl = plot.gl - var bounds = plot._tickBounds - var dataBox = plot.dataBox - var viewBox = plot.viewBox - var pixelRatio = plot.pixelRatio - var screenBox = plot.screenBox - - var screenWidth = screenBox[2] - screenBox[0] - var screenHeight = screenBox[3] - screenBox[1] - var viewWidth = viewBox[2] - viewBox[0] - var viewHeight = viewBox[3] - viewBox[1] - - for(var i=0; i<2; ++i) { - var lo = bounds[i] - var hi = bounds[i+2] - var boundScale = hi - lo - var dataCenter = 0.5 * (dataBox[i+2] + dataBox[i]) - var dataWidth = (dataBox[i+2] - dataBox[i]) - DATA_SCALE[i] = 2.0 * boundScale / dataWidth - DATA_SHIFT[i] = 2.0 * (lo - dataCenter) / dataWidth - } - - DATA_SCALE[0] *= viewWidth / screenWidth - DATA_SHIFT[0] *= viewWidth / screenWidth - - DATA_SCALE[1] *= viewHeight / screenHeight - DATA_SHIFT[1] *= viewHeight / screenHeight - - shader.bind() - vbo.bind() - - shader.attributes.dataCoord.pointer() - - var uniforms = shader.uniforms - uniforms.dataShift = DATA_SHIFT - uniforms.dataScale = DATA_SCALE - - var tickMarkLength = plot.tickMarkLength - var tickMarkWidth = plot.tickMarkWidth - var tickMarkColor = plot.tickMarkColor - - var xTicksOffset = 0 - var yTicksOffset = ticks[0].length * 6 - - var xStart = Math.min(bsearch.ge(ticks[0], (dataBox[0] - bounds[0]) / (bounds[2] - bounds[0]), compareTickNum), ticks[0].length) - var xEnd = Math.min(bsearch.gt(ticks[0], (dataBox[2] - bounds[0]) / (bounds[2] - bounds[0]), compareTickNum), ticks[0].length) - var xOffset = xTicksOffset + 6 * xStart - var xCount = 6 * Math.max(0, xEnd - xStart) - - var yStart = Math.min(bsearch.ge(ticks[1], (dataBox[1] - bounds[1]) / (bounds[3] - bounds[1]), compareTickNum), ticks[1].length) - var yEnd = Math.min(bsearch.gt(ticks[1], (dataBox[3] - bounds[1]) / (bounds[3] - bounds[1]), compareTickNum), ticks[1].length) - var yOffset = yTicksOffset + 6 * yStart - var yCount = 6 * Math.max(0, yEnd - yStart) - - SCR_OFFSET[0] = 2.0 * (viewBox[0] - tickMarkLength[1]) / screenWidth - 1.0 - SCR_OFFSET[1] = (viewBox[3] + viewBox[1]) / screenHeight - 1.0 - TICK_SCALE[0] = tickMarkLength[1] * pixelRatio / screenWidth - TICK_SCALE[1] = tickMarkWidth[1] * pixelRatio / screenHeight - - if(yCount) { - uniforms.color = tickMarkColor[1] - uniforms.tickScale = TICK_SCALE - uniforms.dataAxis = Y_AXIS - uniforms.screenOffset = SCR_OFFSET - gl.drawArrays(gl.TRIANGLES, yOffset, yCount) - } - - SCR_OFFSET[0] = (viewBox[2] + viewBox[0]) / screenWidth - 1.0 - SCR_OFFSET[1] = 2.0 * (viewBox[1] - tickMarkLength[0]) / screenHeight - 1.0 - TICK_SCALE[0] = tickMarkWidth[0] * pixelRatio / screenWidth - TICK_SCALE[1] = tickMarkLength[0] * pixelRatio / screenHeight - - if(xCount) { - uniforms.color = tickMarkColor[0] - uniforms.tickScale = TICK_SCALE - uniforms.dataAxis = X_AXIS - uniforms.screenOffset = SCR_OFFSET - gl.drawArrays(gl.TRIANGLES, xOffset, xCount) - } - - SCR_OFFSET[0] = 2.0 * (viewBox[2] + tickMarkLength[3]) / screenWidth - 1.0 - SCR_OFFSET[1] = (viewBox[3] + viewBox[1]) / screenHeight - 1.0 - TICK_SCALE[0] = tickMarkLength[3] * pixelRatio / screenWidth - TICK_SCALE[1] = tickMarkWidth[3] * pixelRatio / screenHeight - - if(yCount) { - uniforms.color = tickMarkColor[3] - uniforms.tickScale = TICK_SCALE - uniforms.dataAxis = Y_AXIS - uniforms.screenOffset = SCR_OFFSET - gl.drawArrays(gl.TRIANGLES, yOffset, yCount) - } - - SCR_OFFSET[0] = (viewBox[2] + viewBox[0]) / screenWidth - 1.0 - SCR_OFFSET[1] = 2.0 * (viewBox[3] + tickMarkLength[2]) / screenHeight - 1.0 - TICK_SCALE[0] = tickMarkWidth[2] * pixelRatio / screenWidth - TICK_SCALE[1] = tickMarkLength[2] * pixelRatio / screenHeight - - if(xCount) { - uniforms.color = tickMarkColor[2] - uniforms.tickScale = TICK_SCALE - uniforms.dataAxis = X_AXIS - uniforms.screenOffset = SCR_OFFSET - gl.drawArrays(gl.TRIANGLES, xOffset, xCount) - } - } -})() - -proto.update = (function() { - var OFFSET_X = [1, 1, -1, -1, 1, -1] - var OFFSET_Y = [1, -1, 1, 1, -1, -1] - - return function(options) { - var ticks = options.ticks - var bounds = options.bounds - var data = new Float32Array(6 * 3 * (ticks[0].length + ticks[1].length)) - - var zeroLineEnable = this.plot.zeroLineEnable - - var ptr = 0 - var gridTicks = [[], []] - for(var dim=0; dim<2; ++dim) { - var localTicks = gridTicks[dim] - var axisTicks = ticks[dim] - var lo = bounds[dim] - var hi = bounds[dim+2] - for(var i=0; i tickOffset[start]) { - shader.uniforms.dataAxis = DATA_AXIS - shader.uniforms.screenOffset = SCREEN_OFFSET - shader.uniforms.color = textColor[axis] - shader.uniforms.angle = textAngle[axis] - gl.drawArrays( - gl.TRIANGLES, - tickOffset[start], - tickOffset[end] - tickOffset[start]) - } - } - if(labelEnable[axis] && labelCount) { - SCREEN_OFFSET[axis^1] -= screenScale * pixelRatio * labelPad[axis] - shader.uniforms.dataAxis = ZERO_2 - shader.uniforms.screenOffset = SCREEN_OFFSET - shader.uniforms.color = labelColor[axis] - shader.uniforms.angle = labelAngle[axis] - gl.drawArrays( - gl.TRIANGLES, - labelOffset, - labelCount) - } - - SCREEN_OFFSET[axis^1] = screenScale * viewBox[2+(axis^1)] - 1.0 - if(tickEnable[axis+2]) { - SCREEN_OFFSET[axis^1] += screenScale * pixelRatio * tickPad[axis+2] - if(start < end && tickOffset[end] > tickOffset[start]) { - shader.uniforms.dataAxis = DATA_AXIS - shader.uniforms.screenOffset = SCREEN_OFFSET - shader.uniforms.color = textColor[axis+2] - shader.uniforms.angle = textAngle[axis+2] - gl.drawArrays( - gl.TRIANGLES, - tickOffset[start], - tickOffset[end] - tickOffset[start]) - } - } - if(labelEnable[axis+2] && labelCount) { - SCREEN_OFFSET[axis^1] += screenScale * pixelRatio * labelPad[axis+2] - shader.uniforms.dataAxis = ZERO_2 - shader.uniforms.screenOffset = SCREEN_OFFSET - shader.uniforms.color = labelColor[axis+2] - shader.uniforms.angle = labelAngle[axis+2] - gl.drawArrays( - gl.TRIANGLES, - labelOffset, - labelCount) - } - - } -})() - -proto.drawTitle = (function() { - var DATA_AXIS = [0,0] - var SCREEN_OFFSET = [0,0] - - return function() { - var plot = this.plot - var shader = this.shader - var gl = plot.gl - var screenBox = plot.screenBox - var titleCenter = plot.titleCenter - var titleAngle = plot.titleAngle - var titleColor = plot.titleColor - var pixelRatio = plot.pixelRatio - - if(!this.titleCount) { - return - } - - for(var i=0; i<2; ++i) { - SCREEN_OFFSET[i] = 2.0 * (titleCenter[i]*pixelRatio - screenBox[i]) / - (screenBox[2+i] - screenBox[i]) - 1 - } - - shader.bind() - shader.uniforms.dataAxis = DATA_AXIS - shader.uniforms.screenOffset = SCREEN_OFFSET - shader.uniforms.angle = titleAngle - shader.uniforms.color = titleColor - - gl.drawArrays(gl.TRIANGLES, this.titleOffset, this.titleCount) - } -})() - -proto.bind = (function() { - var DATA_SHIFT = [0,0] - var DATA_SCALE = [0,0] - var TEXT_SCALE = [0,0] - - return function() { - var plot = this.plot - var shader = this.shader - var bounds = plot._tickBounds - var dataBox = plot.dataBox - var screenBox = plot.screenBox - var viewBox = plot.viewBox - - shader.bind() - - //Set up coordinate scaling uniforms - for(var i=0; i<2; ++i) { - - var lo = bounds[i] - var hi = bounds[i+2] - var boundScale = hi - lo - var dataCenter = 0.5 * (dataBox[i+2] + dataBox[i]) - var dataWidth = (dataBox[i+2] - dataBox[i]) - - var viewLo = viewBox[i] - var viewHi = viewBox[i+2] - var viewScale = viewHi - viewLo - var screenLo = screenBox[i] - var screenHi = screenBox[i+2] - var screenScale = screenHi - screenLo - - DATA_SCALE[i] = 2.0 * boundScale / dataWidth * viewScale / screenScale - DATA_SHIFT[i] = 2.0 * (lo - dataCenter) / dataWidth * viewScale / screenScale - } - - TEXT_SCALE[1] = 2.0 * plot.pixelRatio / (screenBox[3] - screenBox[1]) - TEXT_SCALE[0] = TEXT_SCALE[1] * (screenBox[3] - screenBox[1]) / (screenBox[2] - screenBox[0]) - - shader.uniforms.dataScale = DATA_SCALE - shader.uniforms.dataShift = DATA_SHIFT - shader.uniforms.textScale = TEXT_SCALE - - //Set attributes - this.vbo.bind() - shader.attributes.textCoordinate.pointer() - } -})() - -proto.update = function(options) { - var vertices = [] - var axesTicks = options.ticks - var bounds = options.bounds - var i, j, k, data, scale, dimension - - for(dimension=0; dimension<2; ++dimension) { - var offsets = [Math.floor(vertices.length/3)], tickX = [-Infinity] - - //Copy vertices over to buffer - var ticks = axesTicks[dimension] - for(i=0; i= 0)) { - continue - } - - var zeroIntercept = screenBox[i] - - dataBox[i] * (screenBox[i+2] - screenBox[i]) / (dataBox[i+2] - dataBox[i]) - - if(i === 0) { - line.drawLine( - zeroIntercept, screenBox[1], zeroIntercept, screenBox[3], - zeroLineWidth[i], - zeroLineColor[i]) - } else { - line.drawLine( - screenBox[0], zeroIntercept, screenBox[2], zeroIntercept, - zeroLineWidth[i], - zeroLineColor[i]) - } - } - } - - //Draw traces - for(var i=0; i=0; --i) { - this.objects[i].dispose() - } - this.objects.length = 0 - for(var i=this.overlays.length-1; i>=0; --i) { - this.overlays[i].dispose() - } - this.overlays.length = 0 - - this.gl = null -} - -proto.addObject = function(object) { - if(this.objects.indexOf(object) < 0) { - this.objects.push(object) - this.setDirty() - } -} - -proto.removeObject = function(object) { - var objects = this.objects - for(var i=0; i 1.0) {\n discard;\n }\n baseColor = mix(borderColor, color, step(radius, centerFraction));\n gl_FragColor = vec4(baseColor.rgb * baseColor.a, baseColor.a);\n }\n}\n"]) -exports.pickVertex = glslify(["precision mediump float;\n#define GLSLIFY 1\n\nattribute vec2 position;\nattribute vec4 pickId;\n\nuniform mat3 matrix;\nuniform float pointSize;\nuniform vec4 pickOffset;\n\nvarying vec4 fragId;\n\nvoid main() {\n vec3 hgPosition = matrix * vec3(position, 1);\n gl_Position = vec4(hgPosition.xy, 0, hgPosition.z);\n gl_PointSize = pointSize;\n\n vec4 id = pickId + pickOffset;\n id.y += floor(id.x / 256.0);\n id.x -= floor(id.x / 256.0) * 256.0;\n\n id.z += floor(id.y / 256.0);\n id.y -= floor(id.y / 256.0) * 256.0;\n\n id.w += floor(id.z / 256.0);\n id.z -= floor(id.z / 256.0) * 256.0;\n\n fragId = id;\n}\n"]) -exports.pickFragment = glslify(["precision mediump float;\n#define GLSLIFY 1\n\nvarying vec4 fragId;\n\nvoid main() {\n float radius = length(2.0 * gl_PointCoord.xy - 1.0);\n if(radius > 1.0) {\n discard;\n }\n gl_FragColor = fragId / 255.0;\n}\n"]) - - -/***/ }), - -/***/ 4696: -/***/ (function(module, __unused_webpack_exports, __webpack_require__) { - -"use strict"; - - -var createShader = __webpack_require__(9405) -var createBuffer = __webpack_require__(2762) - -var pool = __webpack_require__(1888) - -var SHADERS = __webpack_require__(6640) - -module.exports = createPointcloud2D - -function Pointcloud2D(plot, offsetBuffer, pickBuffer, shader, pickShader) { - this.plot = plot - this.offsetBuffer = offsetBuffer - this.pickBuffer = pickBuffer - this.shader = shader - this.pickShader = pickShader - this.sizeMin = 0.5 - this.sizeMinCap = 2 - this.sizeMax = 20 - this.areaRatio = 1.0 - this.pointCount = 0 - this.color = [1, 0, 0, 1] - this.borderColor = [0, 0, 0, 1] - this.blend = false - this.pickOffset = 0 - this.points = null -} - -var proto = Pointcloud2D.prototype - -proto.dispose = function() { - this.shader.dispose() - this.pickShader.dispose() - this.offsetBuffer.dispose() - this.pickBuffer.dispose() - this.plot.removeObject(this) -} - -proto.update = function(options) { - - var i - - options = options || {} - - function dflt(opt, value) { - if(opt in options) { - return options[opt] - } - return value - } - - this.sizeMin = dflt('sizeMin', 0.5) - // this.sizeMinCap = dflt('sizeMinCap', 2) - this.sizeMax = dflt('sizeMax', 20) - this.color = dflt('color', [1, 0, 0, 1]).slice() - this.areaRatio = dflt('areaRatio', 1) - this.borderColor = dflt('borderColor', [0, 0, 0, 1]).slice() - this.blend = dflt('blend', false) - - //Update point data - - // Attempt straight-through processing (STP) to avoid allocation and copy - // TODO eventually abstract out STP logic, maybe into `pool` or a layer above - var pointCount = options.positions.length >>> 1 - var dataStraightThrough = options.positions instanceof Float32Array - var idStraightThrough = options.idToIndex instanceof Int32Array && options.idToIndex.length >= pointCount // permit larger to help reuse - - var data = options.positions - var packed = dataStraightThrough ? data : pool.mallocFloat32(data.length) - var packedId = idStraightThrough ? options.idToIndex : pool.mallocInt32(pointCount) - - if(!dataStraightThrough) { - packed.set(data) - } - - if(!idStraightThrough) { - packed.set(data) - for(i = 0; i < pointCount; i++) { - packedId[i] = i - } - } - - this.points = data - - this.offsetBuffer.update(packed) - this.pickBuffer.update(packedId) - - if(!dataStraightThrough) { - pool.free(packed) - } - - if(!idStraightThrough) { - pool.free(packedId) - } - - this.pointCount = pointCount - this.pickOffset = 0 -} - -function count(points, dataBox) { - var visiblePointCountEstimate = 0 - var length = points.length >>> 1 - var i - for(i = 0; i < length; i++) { - var x = points[i * 2] - var y = points[i * 2 + 1] - if(x >= dataBox[0] && x <= dataBox[2] && y >= dataBox[1] && y <= dataBox[3]) - visiblePointCountEstimate++ - } - return visiblePointCountEstimate -} - -proto.unifiedDraw = (function() { - var MATRIX = [1, 0, 0, - 0, 1, 0, - 0, 0, 1] - var PICK_VEC4 = [0, 0, 0, 0] -return function(pickOffset) { - var pick = pickOffset !== void(0) - - var shader = pick ? this.pickShader : this.shader - var gl = this.plot.gl - var dataBox = this.plot.dataBox - - if(this.pointCount === 0) { - return pickOffset - } - - var dataX = dataBox[2] - dataBox[0] - var dataY = dataBox[3] - dataBox[1] - - var visiblePointCountEstimate = count(this.points, dataBox) - var basicPointSize = this.plot.pickPixelRatio * Math.max(Math.min(this.sizeMinCap, this.sizeMin), Math.min(this.sizeMax, this.sizeMax / Math.pow(visiblePointCountEstimate, 0.33333))) - - MATRIX[0] = 2.0 / dataX - MATRIX[4] = 2.0 / dataY - MATRIX[6] = -2.0 * dataBox[0] / dataX - 1.0 - MATRIX[7] = -2.0 * dataBox[1] / dataY - 1.0 - - this.offsetBuffer.bind() - - shader.bind() - shader.attributes.position.pointer() - shader.uniforms.matrix = MATRIX - shader.uniforms.color = this.color - shader.uniforms.borderColor = this.borderColor - shader.uniforms.pointCloud = basicPointSize < 5 - shader.uniforms.pointSize = basicPointSize - shader.uniforms.centerFraction = Math.min(1, Math.max(0, Math.sqrt(1 - this.areaRatio))) - - if(pick) { - - PICK_VEC4[0] = ( pickOffset & 0xff) - PICK_VEC4[1] = ((pickOffset >> 8) & 0xff) - PICK_VEC4[2] = ((pickOffset >> 16) & 0xff) - PICK_VEC4[3] = ((pickOffset >> 24) & 0xff) - - this.pickBuffer.bind() - shader.attributes.pickId.pointer(gl.UNSIGNED_BYTE) - shader.uniforms.pickOffset = PICK_VEC4 - this.pickOffset = pickOffset - } - - // Worth switching these off, but we can't make assumptions about other - // renderers, so let's restore it after each draw - var blend = gl.getParameter(gl.BLEND) - var dither = gl.getParameter(gl.DITHER) - - if(blend && !this.blend) - gl.disable(gl.BLEND) - if(dither) - gl.disable(gl.DITHER) - - gl.drawArrays(gl.POINTS, 0, this.pointCount) - - if(blend && !this.blend) - gl.enable(gl.BLEND) - if(dither) - gl.enable(gl.DITHER) - - return pickOffset + this.pointCount -} -})() - -proto.draw = proto.unifiedDraw -proto.drawPick = proto.unifiedDraw - -proto.pick = function(x, y, value) { - var pickOffset = this.pickOffset - var pointCount = this.pointCount - if(value < pickOffset || value >= pickOffset + pointCount) { - return null - } - var pointId = value - pickOffset - var points = this.points - return { - object: this, - pointId: pointId, - dataCoord: [points[2 * pointId], points[2 * pointId + 1] ] - } -} - -function createPointcloud2D(plot, options) { - var gl = plot.gl - var buffer = createBuffer(gl) - var pickBuffer = createBuffer(gl) - var shader = createShader(gl, SHADERS.pointVertex, SHADERS.pointFragment) - var pickShader = createShader(gl, SHADERS.pickVertex, SHADERS.pickFragment) - - var result = new Pointcloud2D(plot, buffer, pickBuffer, shader, pickShader) - result.update(options) - - //Register with plot - plot.addObject(result) - - return result -} - - /***/ }), /***/ 783: @@ -22588,152 +20654,6 @@ function createPointCloud(options) { } -/***/ }), - -/***/ 4298: -/***/ (function(__unused_webpack_module, exports, __webpack_require__) { - -"use strict"; - - -var glslify = __webpack_require__(3236) - -exports.boxVertex = glslify(["precision mediump float;\n#define GLSLIFY 1\n\nattribute vec2 vertex;\n\nuniform vec2 cornerA, cornerB;\n\nvoid main() {\n gl_Position = vec4(mix(cornerA, cornerB, vertex), 0, 1);\n}\n"]) -exports.boxFragment = glslify(["precision mediump float;\n#define GLSLIFY 1\n\nuniform vec4 color;\n\nvoid main() {\n gl_FragColor = color;\n}\n"]) - - -/***/ }), - -/***/ 3161: -/***/ (function(module, __unused_webpack_exports, __webpack_require__) { - -"use strict"; - - -var createShader = __webpack_require__(9405) -var createBuffer = __webpack_require__(2762) - -var SHADERS = __webpack_require__(4298) - -module.exports = createSelectBox - -function SelectBox(plot, boxBuffer, boxShader) { - this.plot = plot - this.boxBuffer = boxBuffer - this.boxShader = boxShader - - this.enabled = true - - this.selectBox = [Infinity,Infinity,-Infinity,-Infinity] - - this.borderColor = [0,0,0,1] - this.innerFill = false - this.innerColor = [0,0,0,0.25] - this.outerFill = true - this.outerColor = [0,0,0,0.5] - this.borderWidth = 10 -} - -var proto = SelectBox.prototype - -proto.draw = function() { - if(!this.enabled) { - return - } - - var plot = this.plot - var selectBox = this.selectBox - var lineWidth = this.borderWidth - - var innerFill = this.innerFill - var innerColor = this.innerColor - var outerFill = this.outerFill - var outerColor = this.outerColor - var borderColor = this.borderColor - - var boxes = plot.box - var screenBox = plot.screenBox - var dataBox = plot.dataBox - var viewBox = plot.viewBox - var pixelRatio = plot.pixelRatio - - //Map select box into pixel coordinates - var loX = (selectBox[0]-dataBox[0])*(viewBox[2]-viewBox[0])/(dataBox[2]-dataBox[0])+viewBox[0] - var loY = (selectBox[1]-dataBox[1])*(viewBox[3]-viewBox[1])/(dataBox[3]-dataBox[1])+viewBox[1] - var hiX = (selectBox[2]-dataBox[0])*(viewBox[2]-viewBox[0])/(dataBox[2]-dataBox[0])+viewBox[0] - var hiY = (selectBox[3]-dataBox[1])*(viewBox[3]-viewBox[1])/(dataBox[3]-dataBox[1])+viewBox[1] - - loX = Math.max(loX, viewBox[0]) - loY = Math.max(loY, viewBox[1]) - hiX = Math.min(hiX, viewBox[2]) - hiY = Math.min(hiY, viewBox[3]) - - if(hiX < loX || hiY < loY) { - return - } - - boxes.bind() - - //Draw box - var screenWidth = screenBox[2] - screenBox[0] - var screenHeight = screenBox[3] - screenBox[1] - - if(this.outerFill) { - boxes.drawBox(0, 0, screenWidth, loY, outerColor) - boxes.drawBox(0, loY, loX, hiY, outerColor) - boxes.drawBox(0, hiY, screenWidth, screenHeight, outerColor) - boxes.drawBox(hiX, loY, screenWidth, hiY, outerColor) - } - - if(this.innerFill) { - boxes.drawBox(loX, loY, hiX, hiY, innerColor) - } - - //Draw border - if(lineWidth > 0) { - - //Draw border - var w = lineWidth * pixelRatio - boxes.drawBox(loX-w, loY-w, hiX+w, loY+w, borderColor) - boxes.drawBox(loX-w, hiY-w, hiX+w, hiY+w, borderColor) - boxes.drawBox(loX-w, loY-w, loX+w, hiY+w, borderColor) - boxes.drawBox(hiX-w, loY-w, hiX+w, hiY+w, borderColor) - } -} - -proto.update = function(options) { - options = options || {} - - this.innerFill = !!options.innerFill - this.outerFill = !!options.outerFill - this.innerColor = (options.innerColor || [0,0,0,0.5]).slice() - this.outerColor = (options.outerColor || [0,0,0,0.5]).slice() - this.borderColor = (options.borderColor || [0,0,0,1]).slice() - this.borderWidth = options.borderWidth || 0 - this.selectBox = (options.selectBox || this.selectBox).slice() -} - -proto.dispose = function() { - this.boxBuffer.dispose() - this.boxShader.dispose() - this.plot.removeOverlay(this) -} - -function createSelectBox(plot, options) { - var gl = plot.gl - var buffer = createBuffer(gl, [ - 0, 0, - 0, 1, - 1, 0, - 1, 1 ]) - var shader = createShader(gl, SHADERS.boxVertex, SHADERS.boxFragment) - var selectBox = new SelectBox(plot, buffer, shader) - selectBox.update(options) - plot.addOverlay(selectBox) - return selectBox -} - - /***/ }), /***/ 3589: @@ -24019,100 +21939,6 @@ function createProgram(gl, vref, fref, attribs, locations) { } -/***/ }), - -/***/ 4098: -/***/ (function(module) { - -"use strict"; - - -module.exports = createSpikes2D - -function GLSpikes2D(plot) { - this.plot = plot - this.enable = [true, true, false, false] - this.width = [1, 1, 1, 1] - this.color = [[0,0,0,1], - [0,0,0,1], - [0,0,0,1], - [0,0,0,1]] - this.center = [Infinity, Infinity] -} - -var proto = GLSpikes2D.prototype - -proto.update = function(options) { - options = options || {} - this.enable = (options.enable || [true,true,false,false]).slice() - this.width = (options.width || [1,1,1,1]).slice() - this.color = (options.color || [ - [0,0,0,1], - [0,0,0,1], - [0,0,0,1], - [0,0,0,1]]).map(function(x) { return x.slice() }) - this.center = (options.center || [Infinity,Infinity]).slice() - this.plot.setOverlayDirty() -} - -proto.draw = function() { - var spikeEnable = this.enable - var spikeWidth = this.width - var spikeColor = this.color - var spikeCenter = this.center - var plot = this.plot - var line = plot.line - - var dataBox = plot.dataBox - var viewPixels = plot.viewBox - - line.bind() - - if(dataBox[0] <= spikeCenter[0] && spikeCenter[0] <= dataBox[2] && - dataBox[1] <= spikeCenter[1] && spikeCenter[1] <= dataBox[3]) { - - var centerX = viewPixels[0] + (spikeCenter[0] - dataBox[0]) / (dataBox[2] - dataBox[0]) * (viewPixels[2] - viewPixels[0]) - var centerY = viewPixels[1] + (spikeCenter[1] - dataBox[1]) / (dataBox[3] - dataBox[1]) * (viewPixels[3] - viewPixels[1]) - - if(spikeEnable[0]) { - line.drawLine( - centerX, centerY, - viewPixels[0], centerY, - spikeWidth[0], spikeColor[0]) - } - if(spikeEnable[1]) { - line.drawLine( - centerX, centerY, - centerX, viewPixels[1], - spikeWidth[1], spikeColor[1]) - } - if(spikeEnable[2]) { - line.drawLine( - centerX, centerY, - viewPixels[2], centerY, - spikeWidth[2], spikeColor[2]) - } - if(spikeEnable[3]) { - line.drawLine( - centerX, centerY, - centerX, viewPixels[3], - spikeWidth[3], spikeColor[3]) - } - } -} - -proto.dispose = function() { - this.plot.removeOverlay(this) -} - -function createSpikes2D(plot, options) { - var spikes = new GLSpikes2D(plot) - spikes.update(options) - plot.addOverlay(spikes) - return spikes -} - - /***/ }), /***/ 1493: @@ -30749,24 +28575,6 @@ function createWrapper(intervals) { } -/***/ }), - -/***/ 7762: -/***/ (function(module) { - -"use strict"; - - -function iota(n) { - var result = new Array(n) - for(var i=0; i0) { - shapeX += 0.02 - } - } - - var data = new Float32Array(bufferSize) - var ptr = 0 - var xOffset = -0.5 * shapeX - for(var i=0; i Date: Mon, 7 Oct 2024 16:36:46 -0400 Subject: [PATCH 06/23] drop hoverClosestGl2d from modebar --- src/components/modebar/buttons.js | 12 ------------ src/components/modebar/manage.js | 11 +++-------- 2 files changed, 3 insertions(+), 20 deletions(-) diff --git a/src/components/modebar/buttons.js b/src/components/modebar/buttons.js index 25846cfcf43..4ea6ccce589 100644 --- a/src/components/modebar/buttons.js +++ b/src/components/modebar/buttons.js @@ -559,18 +559,6 @@ function handleGeo(gd, ev) { } } -modeBarButtons.hoverClosestGl2d = { - name: 'hoverClosestGl2d', - _cat: 'hoverclosest', - title: function(gd) { return _(gd, 'Toggle show closest data on hover'); }, - attr: 'hovermode', - val: null, - toggle: true, - icon: Icons.tooltip_basic, - gravity: 'ne', - click: toggleHover -}; - modeBarButtons.hoverClosestPie = { name: 'hoverClosestPie', _cat: 'hoverclosest', diff --git a/src/components/modebar/manage.js b/src/components/modebar/manage.js index b45dd4a5d22..1683b082617 100644 --- a/src/components/modebar/manage.js +++ b/src/components/modebar/manage.js @@ -107,7 +107,6 @@ function getButtonGroups(gd) { var hasGeo = fullLayout._has('geo'); var hasPie = fullLayout._has('pie'); var hasFunnelarea = fullLayout._has('funnelarea'); - var hasGL2D = fullLayout._has('gl2d'); var hasTernary = fullLayout._has('ternary'); var hasMapbox = fullLayout._has('mapbox'); var hasMap = fullLayout._has('map'); @@ -155,7 +154,7 @@ function getButtonGroups(gd) { var resetGroup = []; var dragModeGroup = []; - if((hasCartesian || hasGL2D || hasPie || hasFunnelarea || hasTernary) + hasGeo + hasGL3D + hasMapbox + hasMap + hasPolar + hasSmith > 1) { + if((hasCartesian || hasPie || hasFunnelarea || hasTernary) + hasGeo + hasGL3D + hasMapbox + hasMap + hasPolar + hasSmith > 1) { // graphs with more than one plot types get 'union buttons' // which reset the view or toggle hover labels across all subplots. hoverGroup = ['toggleHover']; @@ -175,8 +174,6 @@ function getButtonGroups(gd) { zoomGroup = ['zoomInMap', 'zoomOutMap']; hoverGroup = ['toggleHover']; resetGroup = ['resetViewMap']; - } else if(hasGL2D) { - hoverGroup = ['hoverClosestGl2d']; } else if(hasPie) { hoverGroup = ['hoverClosestPie']; } else if(hasSankey) { @@ -196,14 +193,14 @@ function getButtonGroups(gd) { hoverGroup = []; } - if((hasCartesian || hasGL2D) && !allAxesFixed) { + if(hasCartesian && !allAxesFixed) { zoomGroup = ['zoomIn2d', 'zoomOut2d', 'autoScale2d']; if(resetGroup[0] !== 'resetViews') resetGroup = ['resetScale2d']; } if(hasGL3D) { dragModeGroup = ['zoom3d', 'pan3d', 'orbitRotation', 'tableRotation']; - } else if(((hasCartesian || hasGL2D) && !allAxesFixed) || hasTernary) { + } else if((hasCartesian && !allAxesFixed) || hasTernary) { dragModeGroup = ['zoom2d', 'pan2d']; } else if(hasMapbox || hasMap || hasGeo) { dragModeGroup = ['pan2d']; @@ -248,14 +245,12 @@ function getButtonGroups(gd) { enableHover('hoverClosestCartesian'); enableHover('hoverClosestGeo'); enableHover('hoverClosest3d'); - enableHover('hoverClosestGl2d'); enableHover('hoverClosestPie'); } else if(b === 'v1hovermode') { enableHover('hoverClosestCartesian'); enableHover('hoverCompareCartesian'); enableHover('hoverClosestGeo'); enableHover('hoverClosest3d'); - enableHover('hoverClosestGl2d'); enableHover('hoverClosestPie'); } } else newList.push(b); From 7d5dff2421d411df278c1041d6f671fb8557b41b Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Tue, 8 Oct 2024 09:26:00 -0400 Subject: [PATCH 07/23] src/components/images/draw.js --- src/components/images/draw.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/images/draw.js b/src/components/images/draw.js index cd6dfeb698b..a6e784c74f2 100644 --- a/src/components/images/draw.js +++ b/src/components/images/draw.js @@ -229,7 +229,6 @@ module.exports = function draw(gd) { var subplotObj = fullLayout._plots[subplot]; // filter out overlaid plots (which have their images on the main plot) - // and gl2d plots (which don't support below images, at least not yet) if(!subplotObj.imagelayer) continue; var imagesOnSubplot = subplotObj.imagelayer.selectAll('image') From adacbdf036bfec6f069027577d2ea1176c416778 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Tue, 8 Oct 2024 09:27:30 -0400 Subject: [PATCH 08/23] src/plot_api/plot_api.js --- src/plot_api/plot_api.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/plot_api/plot_api.js b/src/plot_api/plot_api.js index e82bd29ebc1..cd9244e8fe4 100644 --- a/src/plot_api/plot_api.js +++ b/src/plot_api/plot_api.js @@ -2191,8 +2191,6 @@ function _relayout(gd, aobj) { !(vOld === 'lasso' || vOld === 'select')) ) { flags.plot = true; - } else if(fullLayout._has('gl2d')) { - flags.plot = true; } else if(valObject) editTypes.update(flags, valObject); else flags.calc = true; From 0cb2ae9ae3c210c200e3ef97e4a101034e898ce8 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Tue, 8 Oct 2024 09:27:47 -0400 Subject: [PATCH 09/23] src/plot_api/plot_schema.js --- src/plot_api/plot_schema.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/plot_api/plot_schema.js b/src/plot_api/plot_schema.js index 29ffef77c8c..2d83a807887 100644 --- a/src/plot_api/plot_schema.js +++ b/src/plot_api/plot_schema.js @@ -324,7 +324,7 @@ function layoutHeadAttr(fullLayout, head) { _module = basePlotModules[i]; if(_module.attrRegex && _module.attrRegex.test(head)) { // if a module defines overrides, these take precedence - // initially this is to allow gl2d different editTypes from svg cartesian + // this is to allow different editTypes from svg cartesian if(_module.layoutAttrOverrides) return _module.layoutAttrOverrides; // otherwise take the first attributes we find @@ -332,7 +332,6 @@ function layoutHeadAttr(fullLayout, head) { } // a module can also override the behavior of base (and component) module layout attrs - // again see gl2d for initial use case var baseOverrides = _module.baseLayoutAttrOverrides; if(baseOverrides && head in baseOverrides) return baseOverrides[head]; } From 9e975f91bdfc4adf7545610c593302ef5d935ad3 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Tue, 8 Oct 2024 09:28:21 -0400 Subject: [PATCH 10/23] src/plot_api/subroutines.js --- src/plot_api/subroutines.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/plot_api/subroutines.js b/src/plot_api/subroutines.js index f7fc8850c23..cd5e890d01c 100644 --- a/src/plot_api/subroutines.js +++ b/src/plot_api/subroutines.js @@ -63,9 +63,7 @@ function lsInner(gd) { exports.drawMainTitle(gd); ModeBar.manage(gd); - // _has('cartesian') means SVG specifically, not GL2D - but GL2D - // can still get here because it makes some of the SVG structure - // for shared features like selections. + // _has('cartesian') means SVG specifically if(!fullLayout._has('cartesian')) { return Plots.previousPromises(gd); } From 09d795f3cf7fb562d6d4dcf1bc8c6be0b44595c3 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Tue, 8 Oct 2024 09:29:03 -0400 Subject: [PATCH 11/23] src/plots/cartesian/include_components.js --- src/plots/cartesian/include_components.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plots/cartesian/include_components.js b/src/plots/cartesian/include_components.js index ad27aeab79c..c5306f1c4c6 100644 --- a/src/plots/cartesian/include_components.js +++ b/src/plots/cartesian/include_components.js @@ -26,7 +26,7 @@ module.exports = function makeIncludeComponents(containerArrayName) { var xaList = subplots.xaxis; var yaList = subplots.yaxis; var cartesianList = subplots.cartesian; - var hasCartesianOrGL2D = layoutOut._has('cartesian') || layoutOut._has('gl2d'); + var hasCartesian = layoutOut._has('cartesian'); for(var i = 0; i < array.length; i++) { var itemi = array[i]; @@ -40,7 +40,7 @@ module.exports = function makeIncludeComponents(containerArrayName) { var hasXref = idRegex.x.test(xref); var hasYref = idRegex.y.test(yref); if(hasXref || hasYref) { - if(!hasCartesianOrGL2D) Lib.pushUnique(layoutOut._basePlotModules, Cartesian); + if(!hasCartesian) Lib.pushUnique(layoutOut._basePlotModules, Cartesian); var newAxis = false; if(hasXref && xaList.indexOf(xref) === -1) { From 11fb2da5854916e106a57e5fc591f611e6f1c992 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Tue, 8 Oct 2024 09:29:19 -0400 Subject: [PATCH 12/23] src/plots/cartesian/index.js --- src/plots/cartesian/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plots/cartesian/index.js b/src/plots/cartesian/index.js index b8f28c6ba6f..c4427721035 100644 --- a/src/plots/cartesian/index.js +++ b/src/plots/cartesian/index.js @@ -45,7 +45,7 @@ exports.finalizeSubplots = function(layoutIn, layoutOut) { var xList = subplots.xaxis; var yList = subplots.yaxis; var spSVG = subplots.cartesian; - var spAll = spSVG.concat(subplots.gl2d || []); + var spAll = spSVG; var allX = {}; var allY = {}; var i, xi, yi; From 8516c782f3282eef891ed4c03a71889c47e2aad7 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Tue, 8 Oct 2024 09:29:36 -0400 Subject: [PATCH 13/23] src/plots/cartesian/layout_defaults.js --- src/plots/cartesian/layout_defaults.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plots/cartesian/layout_defaults.js b/src/plots/cartesian/layout_defaults.js index 203eb51f266..cee585392fb 100644 --- a/src/plots/cartesian/layout_defaults.js +++ b/src/plots/cartesian/layout_defaults.js @@ -46,7 +46,7 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) { // look for axes in the data for(i = 0; i < fullData.length; i++) { var trace = fullData[i]; - if(!traceIs(trace, 'cartesian') && !traceIs(trace, 'gl2d')) continue; + if(!traceIs(trace, 'cartesian')) continue; var xaName; if(trace.xaxis) { From a813e5487a8af360a9a35ef3676f99e7d115e387 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Tue, 8 Oct 2024 09:29:57 -0400 Subject: [PATCH 14/23] src/plots/get_data.js --- src/plots/get_data.js | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/plots/get_data.js b/src/plots/get_data.js index 6096580e5a1..7c0dcc2b31a 100644 --- a/src/plots/get_data.js +++ b/src/plots/get_data.js @@ -99,22 +99,10 @@ exports.getSubplotData = function getSubplotData(data, type, subplotId) { var subplotData = []; var trace, subplotX, subplotY; - if(type === 'gl2d') { - var spmatch = subplotId.match(SUBPLOT_PATTERN); - subplotX = 'x' + spmatch[1]; - subplotY = 'y' + spmatch[2]; - } - for(var i = 0; i < data.length; i++) { trace = data[i]; - if(type === 'gl2d' && Registry.traceIs(trace, 'gl2d')) { - if(trace[attr[0]] === subplotX && trace[attr[1]] === subplotY) { - subplotData.push(trace); - } - } else { - if(trace[attr] === subplotId) subplotData.push(trace); - } + if(trace[attr] === subplotId) subplotData.push(trace); } return subplotData; From 0accd7b63d988c0ae2043170cb55c4f78ba0a53c Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Tue, 8 Oct 2024 09:30:32 -0400 Subject: [PATCH 15/23] src/snapshot/helpers.js --- src/snapshot/helpers.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/snapshot/helpers.js b/src/snapshot/helpers.js index a2cfbef76a5..f5d9611b42a 100644 --- a/src/snapshot/helpers.js +++ b/src/snapshot/helpers.js @@ -7,7 +7,6 @@ exports.getDelay = function(fullLayout) { return ( fullLayout._has('gl3d') || - fullLayout._has('gl2d') || fullLayout._has('mapbox') || fullLayout._has('map') ) ? 500 : 0; From e9061a4d87ee492ccbcf036b474aa579d8b325c7 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Tue, 8 Oct 2024 09:30:54 -0400 Subject: [PATCH 16/23] src/traces/heatmap/calc.js --- src/traces/heatmap/calc.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/traces/heatmap/calc.js b/src/traces/heatmap/calc.js index e477abbb332..1df2abbb100 100644 --- a/src/traces/heatmap/calc.js +++ b/src/traces/heatmap/calc.js @@ -21,7 +21,6 @@ module.exports = function calc(gd, trace) { var ya = Axes.getFromId(gd, trace.yaxis || 'y'); var isContour = Registry.traceIs(trace, 'contour'); var isHist = Registry.traceIs(trace, 'histogram'); - var isGL2D = Registry.traceIs(trace, 'gl2d'); var zsmooth = isContour ? 'best' : trace.zsmooth; var x, x0, dx, origX; var y, y0, dy, origY; @@ -124,11 +123,8 @@ module.exports = function calc(gd, trace) { var yIn = trace.ytype === 'scaled' ? '' : y; var yArray = makeBoundArray(trace, yIn, y0, dy, z.length, ya); - // handled in gl2d convert step - if(!isGL2D) { - trace._extremes[xa._id] = Axes.findExtremes(xa, xArray); - trace._extremes[ya._id] = Axes.findExtremes(ya, yArray); - } + trace._extremes[xa._id] = Axes.findExtremes(xa, xArray); + trace._extremes[ya._id] = Axes.findExtremes(ya, yArray); var cd0 = { x: xArray, From a58069abe687adf0be2e19c1a8b8f9131cd1582c Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Tue, 8 Oct 2024 12:32:43 -0400 Subject: [PATCH 17/23] src/components/rangeslider/helpers.js --- src/components/rangeslider/helpers.js | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/components/rangeslider/helpers.js b/src/components/rangeslider/helpers.js index d534c4074a8..f2f1b5d20cf 100644 --- a/src/components/rangeslider/helpers.js +++ b/src/components/rangeslider/helpers.js @@ -17,18 +17,16 @@ exports.makeData = function(fullLayout) { var margin = fullLayout.margin; var rangeSliderData = []; - if(!fullLayout._has('gl2d')) { - for(var i = 0; i < axes.length; i++) { - var ax = axes[i]; + for(var i = 0; i < axes.length; i++) { + var ax = axes[i]; - if(isVisible(ax)) { - rangeSliderData.push(ax); + if(isVisible(ax)) { + rangeSliderData.push(ax); - var opts = ax[name]; - opts._id = name + ax._id; - opts._height = (fullLayout.height - margin.b - margin.t) * opts.thickness; - opts._offsetShift = Math.floor(opts.borderwidth / 2); - } + var opts = ax[name]; + opts._id = name + ax._id; + opts._height = (fullLayout.height - margin.b - margin.t) * opts.thickness; + opts._offsetShift = Math.floor(opts.borderwidth / 2); } } From c6e3d645b214e5dd26d0bb9fa5f1f3e71455d727 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Tue, 8 Oct 2024 12:35:11 -0400 Subject: [PATCH 18/23] src/traces/heatmap/make_bound_array.js --- src/traces/heatmap/make_bound_array.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/traces/heatmap/make_bound_array.js b/src/traces/heatmap/make_bound_array.js index e2deffe4ddb..cf1eecd38de 100644 --- a/src/traces/heatmap/make_bound_array.js +++ b/src/traces/heatmap/make_bound_array.js @@ -7,7 +7,6 @@ module.exports = function makeBoundArray(trace, arrayIn, v0In, dvIn, numbricks, var arrayOut = []; var isContour = Registry.traceIs(trace, 'contour'); var isHist = Registry.traceIs(trace, 'histogram'); - var isGL2D = Registry.traceIs(trace, 'gl2d'); var v0; var dv; var i; @@ -22,7 +21,7 @@ module.exports = function makeBoundArray(trace, arrayIn, v0In, dvIn, numbricks, // and extend it linearly based on the last two points if(len <= numbricks) { // contour plots only want the centers - if(isContour || isGL2D) arrayOut = Array.from(arrayIn).slice(0, numbricks); + if(isContour) arrayOut = Array.from(arrayIn).slice(0, numbricks); else if(numbricks === 1) { if(ax.type === 'log') { arrayOut = [0.5 * arrayIn[0], 2 * arrayIn[0]]; @@ -93,7 +92,7 @@ module.exports = function makeBoundArray(trace, arrayIn, v0In, dvIn, numbricks, dv = dvIn || 1; - for(i = (isContour || isGL2D) ? 0 : -0.5; i < numbricks; i++) { + for(i = isContour ? 0 : -0.5; i < numbricks; i++) { arrayOut.push(v0 + dv * i); } } From 02a0322414130856267407410fd85ff359593907 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Tue, 8 Oct 2024 13:58:58 -0400 Subject: [PATCH 19/23] src/plots/plots.js --- src/plots/plots.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/plots/plots.js b/src/plots/plots.js index 0aaab922b95..bc24c529904 100644 --- a/src/plots/plots.js +++ b/src/plots/plots.js @@ -461,12 +461,10 @@ plots.supplyDefaults = function(gd, opts) { // clean subplots and other artifacts from previous plot calls plots.cleanPlot(newFullData, newFullLayout, oldFullData, oldFullLayout); - var hadGL2D = !!(oldFullLayout._has && oldFullLayout._has('gl2d')); - var hasGL2D = !!(newFullLayout._has && newFullLayout._has('gl2d')); var hadCartesian = !!(oldFullLayout._has && oldFullLayout._has('cartesian')); var hasCartesian = !!(newFullLayout._has && newFullLayout._has('cartesian')); - var hadBgLayer = hadCartesian || hadGL2D; - var hasBgLayer = hasCartesian || hasGL2D; + var hadBgLayer = hadCartesian; + var hasBgLayer = hasCartesian; if(hadBgLayer && !hasBgLayer) { // remove bgLayer oldFullLayout._bgLayer.remove(); @@ -855,7 +853,7 @@ plots.linkSubplots = function(newFullData, newFullLayout, oldFullData, oldFullLa _fullLayout: newFullLayout }; - var ids = newSubplotList.cartesian.concat(newSubplotList.gl2d || []); + var ids = newSubplotList.cartesian || []; for(i = 0; i < ids.length; i++) { var id = ids[i]; From fa66d7e542488d6667f522248569ff171af7993a Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Tue, 8 Oct 2024 14:00:08 -0400 Subject: [PATCH 20/23] src/plots/plots.js 2 --- src/plots/plots.js | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/src/plots/plots.js b/src/plots/plots.js index bc24c529904..ed6b7dab1b8 100644 --- a/src/plots/plots.js +++ b/src/plots/plots.js @@ -1281,28 +1281,20 @@ plots.supplyTraceDefaults = function(traceIn, traceOut, colorIndex, layout, trac var subplots = layout._subplots; var subplotId = ''; - if( - visible || - basePlotModule.name !== 'gl2d' // for now just drop empty gl2d subplots - // TODO - currently if we draw an empty gl2d subplot, it draws - // nothing then gets stuck and you can't get it back without newPlot - // sort this out in the regl refactor? - ) { - if(Array.isArray(subplotAttr)) { - for(i = 0; i < subplotAttr.length; i++) { - var attri = subplotAttr[i]; - var vali = Lib.coerce(traceIn, traceOut, subplotAttrs, attri); + if(Array.isArray(subplotAttr)) { + for(i = 0; i < subplotAttr.length; i++) { + var attri = subplotAttr[i]; + var vali = Lib.coerce(traceIn, traceOut, subplotAttrs, attri); - if(subplots[attri]) Lib.pushUnique(subplots[attri], vali); - subplotId += vali; - } - } else { - subplotId = Lib.coerce(traceIn, traceOut, subplotAttrs, subplotAttr); + if(subplots[attri]) Lib.pushUnique(subplots[attri], vali); + subplotId += vali; } + } else { + subplotId = Lib.coerce(traceIn, traceOut, subplotAttrs, subplotAttr); + } - if(subplots[basePlotModule.name]) { - Lib.pushUnique(subplots[basePlotModule.name], subplotId); - } + if(subplots[basePlotModule.name]) { + Lib.pushUnique(subplots[basePlotModule.name], subplotId); } } } From 0be88d286681920ef031b993abc6da16df44782e Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Tue, 8 Oct 2024 14:01:25 -0400 Subject: [PATCH 21/23] more heatmapgl removal --- src/components/fx/hover.js | 2 +- src/traces/heatmap/xyz_defaults.js | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/components/fx/hover.js b/src/components/fx/hover.js index 98a8af61aa7..80fc4a07cf3 100644 --- a/src/components/fx/hover.js +++ b/src/components/fx/hover.js @@ -160,7 +160,7 @@ exports.loneHover = function loneHover(hoverItems, opts) { x1 += dx; y0 += dy; y1 += dy; - } // TODO: handle heatmapgl + } eventData.bbox = { x0: x0 + gLeft, diff --git a/src/traces/heatmap/xyz_defaults.js b/src/traces/heatmap/xyz_defaults.js index 1ded29e8811..044fce9cbdf 100644 --- a/src/traces/heatmap/xyz_defaults.js +++ b/src/traces/heatmap/xyz_defaults.js @@ -36,8 +36,6 @@ module.exports = function handleXYZDefaults(traceIn, traceOut, coerce, layout, x traceOut._length = null; } - if(traceIn.type === 'heatmapgl') return true; // skip calendars until we handle them in those traces - var handleCalendarDefaults = Registry.getComponentMethod('calendars', 'handleTraceDefaults'); handleCalendarDefaults(traceIn, traceOut, [xName, yName], layout); From 45c5f263575d385175e14dd54a8b8898dc2f94f4 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Tue, 8 Oct 2024 14:04:33 -0400 Subject: [PATCH 22/23] remove heatmapgl from petrophysics template --- test/image/mocks/petrophysics.json | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/test/image/mocks/petrophysics.json b/test/image/mocks/petrophysics.json index 2facb7267a0..8522f664891 100644 --- a/test/image/mocks/petrophysics.json +++ b/test/image/mocks/petrophysics.json @@ -313167,24 +313167,6 @@ ] } ], - "heatmapgl": [ - { - "type": "heatmapgl", - "colorbar": { "outlinewidth": 0, "ticks": "" }, - "colorscale": [ - [0.0, "#0d0887"], - [0.1111111111111111, "#46039f"], - [0.2222222222222222, "#7201a8"], - [0.3333333333333333, "#9c179e"], - [0.4444444444444444, "#bd3786"], - [0.5555555555555556, "#d8576b"], - [0.6666666666666666, "#ed7953"], - [0.7777777777777778, "#fb9f3a"], - [0.8888888888888888, "#fdca26"], - [1.0, "#f0f921"] - ] - } - ], "contourcarpet": [ { "type": "contourcarpet", "colorbar": { "outlinewidth": 0, "ticks": "" } } ], From 6c94890de5b2a0b5a6a4e647810854a32fe376d2 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Tue, 8 Oct 2024 14:05:14 -0400 Subject: [PATCH 23/23] edit draftlog --- draftlogs/{7213_change.md => 7213_remove.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename draftlogs/{7213_change.md => 7213_remove.md} (100%) diff --git a/draftlogs/7213_change.md b/draftlogs/7213_remove.md similarity index 100% rename from draftlogs/7213_change.md rename to draftlogs/7213_remove.md