diff --git a/src/components/colorbar/draw.js b/src/components/colorbar/draw.js index a908e953b47..95b9660b447 100644 --- a/src/components/colorbar/draw.js +++ b/src/components/colorbar/draw.js @@ -72,66 +72,102 @@ function draw(gd) { } function makeColorBarData(gd) { + var fullLayout = gd._fullLayout; var calcdata = gd.calcdata; var out = []; + // single out item + var opts; + // colorbar attr parent container + var cont; + // trace attr container + var trace; + // colorbar options + var cbOpt; + + function initOpts(opts) { + return extendFlat(opts, { + // fillcolor can be a d3 scale, domain is z values, range is colors + // or leave it out for no fill, + // or set to a string constant for single-color fill + _fillcolor: null, + // line.color has the same options as fillcolor + _line: {color: null, width: null, dash: null}, + // levels of lines to draw. + // note that this DOES NOT determine the extent of the bar + // that's given by the domain of fillcolor + // (or line.color if no fillcolor domain) + _levels: {start: null, end: null, size: null}, + // separate fill levels (for example, heatmap coloring of a + // contour map) if this is omitted, fillcolors will be + // evaluated halfway between levels + _filllevels: null, + // for continuous colorscales: fill with a gradient instead of explicit levels + // value should be the colorscale [[0, c0], [v1, c1], ..., [1, cEnd]] + _fillgradient: null, + // when using a gradient, we need the data range specified separately + _zrange: null + }); + } + + function calcOpts() { + if(typeof cbOpt.calc === 'function') { + cbOpt.calc(gd, trace, opts); + } else { + opts._fillgradient = cont.reversescale ? + flipScale(cont.colorscale) : + cont.colorscale; + opts._zrange = [cont[cbOpt.min], cont[cbOpt.max]]; + } + } + for(var i = 0; i < calcdata.length; i++) { var cd = calcdata[i]; - var trace = cd[0].trace; + trace = cd[0].trace; var moduleOpts = trace._module.colorbar; if(trace.visible === true && moduleOpts) { - var cbOpts = Array.isArray(moduleOpts) ? moduleOpts : [moduleOpts]; + var allowsMultiplotCbs = Array.isArray(moduleOpts); + var cbOpts = allowsMultiplotCbs ? moduleOpts : [moduleOpts]; for(var j = 0; j < cbOpts.length; j++) { - var cbOpt = cbOpts[j]; + cbOpt = cbOpts[j]; var contName = cbOpt.container; - var cont = contName ? trace[contName] : trace; + cont = contName ? trace[contName] : trace; if(cont && cont.showscale) { - var opts = cont.colorbar; - opts._id = 'cb' + trace.uid; + opts = initOpts(cont.colorbar); + opts._id = 'cb' + trace.uid + (allowsMultiplotCbs && contName ? '-' + contName : ''); opts._traceIndex = trace.index; opts._propPrefix = (contName ? contName + '.' : '') + 'colorbar.'; - - extendFlat(opts, { - // fillcolor can be a d3 scale, domain is z values, range is colors - // or leave it out for no fill, - // or set to a string constant for single-color fill - _fillcolor: null, - // line.color has the same options as fillcolor - _line: {color: null, width: null, dash: null}, - // levels of lines to draw. - // note that this DOES NOT determine the extent of the bar - // that's given by the domain of fillcolor - // (or line.color if no fillcolor domain) - _levels: {start: null, end: null, size: null}, - // separate fill levels (for example, heatmap coloring of a - // contour map) if this is omitted, fillcolors will be - // evaluated halfway between levels - _filllevels: null, - // for continuous colorscales: fill with a gradient instead of explicit levels - // value should be the colorscale [[0, c0], [v1, c1], ..., [1, cEnd]] - _fillgradient: null, - // when using a gradient, we need the data range specified separately - _zrange: null - }); - - if(typeof cbOpt.calc === 'function') { - cbOpt.calc(gd, cd, opts); - } else { - opts._fillgradient = cont.reversescale ? - flipScale(cont.colorscale) : - cont.colorscale; - opts._zrange = [cont[cbOpt.min], cont[cbOpt.max]]; - } - + calcOpts(); out.push(opts); } } } } + for(var k in fullLayout._colorAxes) { + cont = fullLayout[k]; + + if(cont.showscale) { + var colorAxOpts = fullLayout._colorAxes[k]; + + opts = initOpts(cont.colorbar); + opts._id = 'cb' + k; + opts._propPrefix = k + '.colorbar.'; + + cbOpt = {min: 'cmin', max: 'cmax'}; + if(colorAxOpts[0] !== 'heatmap') { + trace = colorAxOpts[1]; + cbOpt.calc = trace._module.colorbar.calc; + } + + calcOpts(); + out.push(opts); + } + } + return out; } @@ -561,7 +597,11 @@ function makeEditable(g, opts, gd) { var update = {}; update[opts._propPrefix + 'x'] = xf; update[opts._propPrefix + 'y'] = yf; - Registry.call('_guiRestyle', gd, update, opts._traceIndex); + if(opts._traceIndex !== undefined) { + Registry.call('_guiRestyle', gd, update, opts._traceIndex); + } else { + Registry.call('_guiRelayout', gd, update); + } } } }); diff --git a/src/components/colorscale/attributes.js b/src/components/colorscale/attributes.js index 014377c1c91..3df6baec2a5 100644 --- a/src/components/colorscale/attributes.js +++ b/src/components/colorscale/attributes.js @@ -8,6 +8,9 @@ 'use strict'; +var colorbarAttrs = require('../colorbar/attributes'); +var counterRegex = require('../../lib/regex').counter; + var palettes = require('./scales.js').scales; var paletteStr = Object.keys(palettes); @@ -240,6 +243,25 @@ module.exports = function colorScaleAttrs(context, opts) { effectDesc ].join('') }; + + attrs.colorbar = colorbarAttrs; + } + + if(!opts.noColorAxis) { + attrs.coloraxis = { + valType: 'subplotid', + role: 'info', + regex: counterRegex('coloraxis'), + dflt: null, + editType: 'calc', + 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.' + ].join(' ') + }; } return attrs; diff --git a/src/components/colorscale/calc.js b/src/components/colorscale/calc.js index ed2491f9420..54911a76452 100644 --- a/src/components/colorscale/calc.js +++ b/src/components/colorscale/calc.js @@ -8,37 +8,50 @@ 'use strict'; +var isNumeric = require('fast-isnumeric'); + var Lib = require('../../lib'); +var extractOpts = require('./helpers').extractOpts; module.exports = function calc(gd, trace, opts) { var fullLayout = gd._fullLayout; var vals = opts.vals; var containerStr = opts.containerStr; - var cLetter = opts.cLetter; var container = containerStr ? Lib.nestedProperty(trace, containerStr).get() : trace; - var autoAttr = cLetter + 'auto'; - var minAttr = cLetter + 'min'; - var maxAttr = cLetter + 'max'; - var midAttr = cLetter + 'mid'; - var auto = container[autoAttr]; - var min = container[minAttr]; - var max = container[maxAttr]; - var mid = container[midAttr]; - var scl = container.colorscale; + var cOpts = extractOpts(container); + var auto = cOpts.auto !== false; + var min = cOpts.min; + var max = cOpts.max; + var mid = cOpts.mid; + + var minVal = function() { return Lib.aggNums(Math.min, null, vals); }; + var maxVal = function() { return Lib.aggNums(Math.max, null, vals); }; - if(auto !== false || min === undefined) { - min = Lib.aggNums(Math.min, null, vals); + if(min === undefined) { + min = minVal(); + } else if(auto) { + if(container._colorAx && isNumeric(min)) { + min = Math.min(min, minVal()); + } else { + min = minVal(); + } } - if(auto !== false || max === undefined) { - max = Lib.aggNums(Math.max, null, vals); + if(max === undefined) { + max = maxVal(); + } else if(auto) { + if(container._colorAx && isNumeric(max)) { + max = Math.max(max, maxVal()); + } else { + max = maxVal(); + } } - if(auto !== false && mid !== undefined) { + if(auto && mid !== undefined) { if(max - mid > mid - min) { min = mid - (max - mid); } else if(max - mid < mid - min) { @@ -51,14 +64,14 @@ module.exports = function calc(gd, trace, opts) { max += 0.5; } - container['_' + minAttr] = container[minAttr] = min; - container['_' + maxAttr] = container[maxAttr] = max; + cOpts._sync('min', min); + cOpts._sync('max', max); - if(container.autocolorscale) { + if(cOpts.autocolorscale) { + var scl; if(min * max < 0) scl = fullLayout.colorscale.diverging; else if(min >= 0) scl = fullLayout.colorscale.sequential; else scl = fullLayout.colorscale.sequentialminus; - - container._colorscale = container.colorscale = scl; + cOpts._sync('colorscale', scl); } }; diff --git a/src/components/colorscale/cross_trace_defaults.js b/src/components/colorscale/cross_trace_defaults.js index 5933b669166..706bb7ccfb7 100644 --- a/src/components/colorscale/cross_trace_defaults.js +++ b/src/components/colorscale/cross_trace_defaults.js @@ -10,8 +10,9 @@ var Lib = require('../../lib'); var hasColorscale = require('./helpers').hasColorscale; +var extractOpts = require('./helpers').extractOpts; -module.exports = function crossTraceDefaults(fullData) { +module.exports = function crossTraceDefaults(fullData, fullLayout) { function replace(cont, k) { var val = cont['_' + k]; if(val !== undefined) { @@ -19,44 +20,46 @@ module.exports = function crossTraceDefaults(fullData) { } } - function relinkColorAtts(trace, cAttrs) { - var cont = cAttrs.container ? - Lib.nestedProperty(trace, cAttrs.container).get() : - trace; + function relinkColorAtts(outerCont, cbOpt) { + var cont = cbOpt.container ? + Lib.nestedProperty(outerCont, cbOpt.container).get() : + outerCont; if(cont) { - var isAuto = cont.zauto || cont.cauto; - var minAttr = cAttrs.min; - var maxAttr = cAttrs.max; + if(cont.coloraxis) { + // stash ref to color axis + cont._colorAx = fullLayout[cont.coloraxis]; + } else { + var cOpts = extractOpts(cont); + var isAuto = cOpts.auto; - if(isAuto || cont[minAttr] === undefined) { - replace(cont, minAttr); - } - if(isAuto || cont[maxAttr] === undefined) { - replace(cont, maxAttr); - } - if(cont.autocolorscale) { - replace(cont, 'colorscale'); + if(isAuto || cOpts.min === undefined) { + replace(cont, cbOpt.min); + } + if(isAuto || cOpts.max === undefined) { + replace(cont, cbOpt.max); + } + if(cOpts.autocolorscale) { + replace(cont, 'colorscale'); + } } } } for(var i = 0; i < fullData.length; i++) { var trace = fullData[i]; - var colorbar = trace._module.colorbar; + var cbOpts = trace._module.colorbar; - if(colorbar) { - if(Array.isArray(colorbar)) { - for(var j = 0; j < colorbar.length; j++) { - relinkColorAtts(trace, colorbar[j]); + if(cbOpts) { + if(Array.isArray(cbOpts)) { + for(var j = 0; j < cbOpts.length; j++) { + relinkColorAtts(trace, cbOpts[j]); } } else { - relinkColorAtts(trace, colorbar); + relinkColorAtts(trace, cbOpts); } } - // TODO could generalize _module.colorscale and use it here? - if(hasColorscale(trace, 'marker.line')) { relinkColorAtts(trace, { container: 'marker.line', @@ -64,13 +67,9 @@ module.exports = function crossTraceDefaults(fullData) { max: 'cmax' }); } + } - if(hasColorscale(trace, 'line')) { - relinkColorAtts(trace, { - container: 'line', - min: 'cmin', - max: 'cmax' - }); - } + for(var k in fullLayout._colorAxes) { + relinkColorAtts(fullLayout[k], {min: 'cmin', max: 'cmax'}); } }; diff --git a/src/components/colorscale/defaults.js b/src/components/colorscale/defaults.js index 20070edf750..0cb953129b5 100644 --- a/src/components/colorscale/defaults.js +++ b/src/components/colorscale/defaults.js @@ -15,20 +15,74 @@ var hasColorbar = require('../colorbar/has_colorbar'); var colorbarDefaults = require('../colorbar/defaults'); var isValidScale = require('./scales').isValid; +var traceIs = require('../../registry').traceIs; -function npMaybe(cont, prefix) { +function npMaybe(parentCont, prefix) { var containerStr = prefix.slice(0, prefix.length - 1); return prefix ? - Lib.nestedProperty(cont, containerStr).get() || {} : - cont; + Lib.nestedProperty(parentCont, containerStr).get() || {} : + parentCont; } -module.exports = function colorScaleDefaults(traceIn, traceOut, layout, coerce, opts) { +/** + * Colorscale / colorbar default handler + * + * @param {object} parentContIn : user (input) parent container (e.g. trace or layout coloraxis object) + * @param {object} parentContOut : full parent container + * @param {object} layout : (full) layout object + * @param {fn} coerce : Lib.coerce wrapper + * @param {object} opts : + * - prefix {string} : attr string prefix to colorscale container from parent root + * - cLetter {string} : 'c or 'z' color letter + */ +module.exports = function colorScaleDefaults(parentContIn, parentContOut, layout, coerce, opts) { var prefix = opts.prefix; var cLetter = opts.cLetter; - var containerIn = npMaybe(traceIn, prefix); - var containerOut = npMaybe(traceOut, prefix); - var template = npMaybe(traceOut._template || {}, prefix) || {}; + var inTrace = '_module' in parentContOut; + var containerIn = npMaybe(parentContIn, prefix); + var containerOut = npMaybe(parentContOut, prefix); + var template = npMaybe(parentContOut._template || {}, prefix) || {}; + + // colorScaleDefaults wrapper called if-ever we need to reset the colorscale + // attributes for containers that were linked to invalid color axes + var thisFn = function() { + delete parentContIn.coloraxis; + delete parentContOut.coloraxis; + return colorScaleDefaults(parentContIn, parentContOut, layout, coerce, opts); + }; + + if(inTrace) { + var colorAxes = layout._colorAxes || {}; + var colorAx = coerce(prefix + 'coloraxis'); + + if(colorAx) { + var colorbarVisuals = ( + traceIs(parentContOut, 'contour') && + Lib.nestedProperty(parentContOut, 'contours.coloring').get() + ) || 'heatmap'; + + var stash = colorAxes[colorAx]; + + if(stash) { + stash[2].push(thisFn); + + if(stash[0] !== colorbarVisuals) { + stash[0] = false; + Lib.warn([ + 'Ignoring coloraxis:', colorAx, 'setting', + 'as it is linked to incompatible colorscales.' + ].join(' ')); + } + } else { + // stash: + // - colorbar visual 'type' + // - colorbar options to help in Colorbar.draw + // - list of colorScaleDefaults wrapper functions + colorAxes[colorAx] = [colorbarVisuals, parentContOut, [thisFn]]; + } + return; + } + } var minIn = containerIn[cLetter + 'min']; var maxIn = containerIn[cLetter + 'max']; @@ -58,7 +112,7 @@ module.exports = function colorScaleDefaults(traceIn, traceOut, layout, coerce, // handles both the trace case where the dflt is listed in attributes and // the marker case where the dflt is determined by hasColorbar var showScaleDflt; - if(prefix) showScaleDflt = hasColorbar(containerIn); + if(prefix && inTrace) showScaleDflt = hasColorbar(containerIn); var showScale = coerce(prefix + 'showscale', showScaleDflt); if(showScale) colorbarDefaults(containerIn, containerOut, layout); diff --git a/src/components/colorscale/helpers.js b/src/components/colorscale/helpers.js index 47c53f8fd56..73ca3994476 100644 --- a/src/components/colorscale/helpers.js +++ b/src/components/colorscale/helpers.js @@ -44,6 +44,67 @@ function hasColorscale(trace, containerStr) { ); } +var constantAttrs = ['showscale', 'autocolorscale', 'colorscale', 'reversescale', 'colorbar']; +var letterAttrs = ['min', 'max', 'mid', 'auto']; + +/** + * Extract 'c' / 'z', trace / color axis colorscale options + * + * Note that it would be nice to replace all z* with c* equivalents in v2 + * + * @param {object} cont : attribute container + * @return {object}: + * - min: cmin or zmin + * - max: cmax or zmax + * - mid: cmid or zmid + * - auto: cauto or zauto + * - *scale: *scale attrs + * - colorbar: colorbar + * - _sync: function syncing attr and underscore dual (useful when calc'ing min/max) + */ +function extractOpts(cont) { + var colorAx = cont._colorAx; + var cont2 = colorAx ? colorAx : cont; + var out = {}; + var cLetter; + var i, k; + + for(i = 0; i < constantAttrs.length; i++) { + k = constantAttrs[i]; + out[k] = cont2[k]; + } + + if(colorAx) { + cLetter = 'c'; + for(i = 0; i < letterAttrs.length; i++) { + k = letterAttrs[i]; + out[k] = cont2['c' + k]; + } + } else { + var k2; + for(i = 0; i < letterAttrs.length; i++) { + k = letterAttrs[i]; + k2 = 'c' + k; + if(k2 in cont2) { + out[k] = cont2[k2]; + continue; + } + k2 = 'z' + k; + if(k2 in cont2) { + out[k] = cont2[k2]; + } + } + cLetter = k2.charAt(0); + } + + out._sync = function(k, v) { + var k2 = letterAttrs.indexOf(k) !== -1 ? cLetter + k : k; + cont2[k2] = cont2['_' + k2] = v; + }; + + return out; +} + /** * Extract colorscale into numeric domain and color range. * @@ -52,24 +113,19 @@ function hasColorscale(trace, containerStr) { * - cmin/zmin {number} * - cmax/zmax {number} * - reversescale {boolean} - * @param {object} opts - * - cLetter {string} 'c' (for cmin/cmax) or 'z' (for zmin/zmax) * * @return {object} * - domain {array} * - range {array} */ -function extractScale(cont, opts) { - var cLetter = opts.cLetter; - - var scl = cont.reversescale ? - flipScale(cont.colorscale) : - cont.colorscale; +function extractScale(cont) { + var cOpts = extractOpts(cont); + var cmin = cOpts.min; + var cmax = cOpts.max; - // minimum color value (used to clamp scale) - var cmin = cont[cLetter + 'min']; - // maximum color value (used to clamp scale) - var cmax = cont[cLetter + 'max']; + var scl = cOpts.reversescale ? + flipScale(cOpts.colorscale) : + cOpts.colorscale; var N = scl.length; var domain = new Array(N); @@ -81,10 +137,7 @@ function extractScale(cont, opts) { range[i] = si[1]; } - return { - domain: domain, - range: range - }; + return {domain: domain, range: range}; } function flipScale(scl) { @@ -160,6 +213,10 @@ function makeColorScaleFunc(specs, opts) { return sclFunc; } +function makeColorScaleFuncFromTrace(trace, opts) { + return makeColorScaleFunc(extractScale(trace), opts); +} + function colorArray2rbga(colorArray) { var colorObj = { r: colorArray[0], @@ -173,7 +230,9 @@ function colorArray2rbga(colorArray) { module.exports = { hasColorscale: hasColorscale, + extractOpts: extractOpts, extractScale: extractScale, flipScale: flipScale, - makeColorScaleFunc: makeColorScaleFunc + makeColorScaleFunc: makeColorScaleFunc, + makeColorScaleFuncFromTrace: makeColorScaleFuncFromTrace }; diff --git a/src/components/colorscale/index.js b/src/components/colorscale/index.js index 224cc41de65..2976b51926b 100644 --- a/src/components/colorscale/index.js +++ b/src/components/colorscale/index.js @@ -32,7 +32,9 @@ module.exports = { isValidScale: scales.isValid, hasColorscale: helpers.hasColorscale, - flipScale: helpers.flipScale, + extractOpts: helpers.extractOpts, extractScale: helpers.extractScale, - makeColorScaleFunc: helpers.makeColorScaleFunc + flipScale: helpers.flipScale, + makeColorScaleFunc: helpers.makeColorScaleFunc, + makeColorScaleFuncFromTrace: helpers.makeColorScaleFuncFromTrace }; diff --git a/src/components/colorscale/layout_attributes.js b/src/components/colorscale/layout_attributes.js index 75ec78007af..3612884c172 100644 --- a/src/components/colorscale/layout_attributes.js +++ b/src/components/colorscale/layout_attributes.js @@ -8,40 +8,63 @@ 'use strict'; +var extendFlat = require('../../lib/extend').extendFlat; + +var colorScaleAttrs = require('./attributes'); var scales = require('./scales').scales; var msg = 'Note that `autocolorscale` must be true for this attribute to work.'; module.exports = { editType: 'calc', - sequential: { - valType: 'colorscale', - dflt: scales.Reds, - role: 'style', - editType: 'calc', - description: [ - 'Sets the default sequential colorscale for positive values.', - msg - ].join(' ') - }, - sequentialminus: { - valType: 'colorscale', - dflt: scales.Blues, - role: 'style', + + colorscale: { editType: 'calc', - description: [ - 'Sets the default sequential colorscale for negative values.', - msg - ].join(' ') + + sequential: { + valType: 'colorscale', + dflt: scales.Reds, + role: 'style', + editType: 'calc', + description: [ + 'Sets the default sequential colorscale for positive values.', + msg + ].join(' ') + }, + sequentialminus: { + valType: 'colorscale', + dflt: scales.Blues, + role: 'style', + editType: 'calc', + description: [ + 'Sets the default sequential colorscale for negative values.', + msg + ].join(' ') + }, + diverging: { + valType: 'colorscale', + dflt: scales.RdBu, + role: 'style', + editType: 'calc', + description: [ + 'Sets the default diverging colorscale.', + msg + ].join(' ') + } }, - diverging: { - valType: 'colorscale', - dflt: scales.RdBu, - role: 'style', + + coloraxis: extendFlat({ + // not really a 'subplot' attribute container, + // but this is the flag we use to denote attributes that + // support yaxis, yaxis2, yaxis3, ... counters + _isSubplotObj: true, editType: 'calc', description: [ - 'Sets the default diverging colorscale.', - msg + '' ].join(' ') - } + }, colorScaleAttrs('', { + colorAttr: 'corresponding trace color array(s)', + noColorAxis: true, + showScaleDflt: true + })) }; diff --git a/src/components/colorscale/layout_defaults.js b/src/components/colorscale/layout_defaults.js index b05d56895c0..744e575de83 100644 --- a/src/components/colorscale/layout_defaults.js +++ b/src/components/colorscale/layout_defaults.js @@ -9,17 +9,41 @@ 'use strict'; var Lib = require('../../lib'); -var colorscaleAttrs = require('./layout_attributes'); var Template = require('../../plot_api/plot_template'); +var colorScaleAttrs = require('./layout_attributes'); +var colorScaleDefaults = require('./defaults'); + module.exports = function supplyLayoutDefaults(layoutIn, layoutOut) { - var colorscaleIn = layoutIn.colorscale; - var colorscaleOut = Template.newContainer(layoutOut, 'colorscale'); function coerce(attr, dflt) { - return Lib.coerce(colorscaleIn, colorscaleOut, colorscaleAttrs, attr, dflt); + return Lib.coerce(layoutIn, layoutOut, colorScaleAttrs, attr, dflt); } - coerce('sequential'); - coerce('sequentialminus'); - coerce('diverging'); + coerce('colorscale.sequential'); + coerce('colorscale.sequentialminus'); + coerce('colorscale.diverging'); + + var colorAxes = layoutOut._colorAxes; + var colorAxIn, colorAxOut; + + function coerceAx(attr, dflt) { + return Lib.coerce(colorAxIn, colorAxOut, colorScaleAttrs.coloraxis, attr, dflt); + } + + for(var k in colorAxes) { + var stash = colorAxes[k]; + + if(stash[0]) { + colorAxIn = layoutIn[k] || {}; + colorAxOut = Template.newContainer(layoutOut, k, 'coloraxis'); + colorAxOut._name = k; + colorScaleDefaults(colorAxIn, colorAxOut, layoutOut, coerceAx, {prefix: '', cLetter: 'c'}); + } else { + // re-coerce colorscale attributes w/o coloraxis + for(var i = 0; i < stash[2].length; i++) { + stash[2][i](); + } + delete layoutOut._colorAxes[k]; + } + } }; diff --git a/src/components/drawing/index.js b/src/components/drawing/index.js index 9e764d93562..de3f243d87c 100644 --- a/src/components/drawing/index.js +++ b/src/components/drawing/index.js @@ -638,13 +638,9 @@ drawing.tryColorscale = function(marker, prefix) { var cont = prefix ? Lib.nestedProperty(marker, prefix).get() : marker; if(cont) { - var scl = cont.colorscale; var colorArray = cont.color; - - if(scl && Lib.isArrayOrTypedArray(colorArray)) { - return Colorscale.makeColorScaleFunc( - Colorscale.extractScale(cont, {cLetter: 'c'}) - ); + if((cont.colorscale || cont._colorAx) && Lib.isArrayOrTypedArray(colorArray)) { + return Colorscale.makeColorScaleFuncFromTrace(cont); } } return Lib.identity; diff --git a/src/lib/gl_format_color.js b/src/lib/gl_format_color.js index cfa7a587aa6..36cd70d5ba7 100644 --- a/src/lib/gl_format_color.js +++ b/src/lib/gl_format_color.js @@ -6,7 +6,6 @@ * LICENSE file in the root directory of this source tree. */ - 'use strict'; var isNumeric = require('fast-isnumeric'); @@ -47,9 +46,7 @@ function formatColor(containerIn, opacityIn, len) { var sclFunc, getColor, getOpacity, colori, opacityi; if(containerIn.colorscale !== undefined) { - sclFunc = Colorscale.makeColorScaleFunc( - Colorscale.extractScale(containerIn, {cLetter: 'c'}) - ); + sclFunc = Colorscale.makeColorScaleFuncFromTrace(containerIn); } else { sclFunc = validateColor; } @@ -81,9 +78,11 @@ function formatColor(containerIn, opacityIn, len) { function parseColorScale(cont, alpha) { if(alpha === undefined) alpha = 1; - var colorscale = cont.reversescale ? - Colorscale.flipScale(cont.colorscale) : - cont.colorscale; + var cOpts = Colorscale.extractOpts(cont); + + var colorscale = cOpts.reversescale ? + Colorscale.flipScale(cOpts.colorscale) : + cOpts.colorscale; return colorscale.map(function(elem) { var index = elem[0]; diff --git a/src/plot_api/edit_types.js b/src/plot_api/edit_types.js index 6f849283de0..73972c449c6 100644 --- a/src/plot_api/edit_types.js +++ b/src/plot_api/edit_types.js @@ -35,7 +35,7 @@ var layoutOpts = { extras: ['none'], flags: [ 'calc', 'plot', 'legend', 'ticks', 'axrange', - 'layoutstyle', 'modebar', 'camera', 'arraydraw' + 'layoutstyle', 'modebar', 'camera', 'arraydraw', 'colorbars' ], description: [ 'layout attributes should include an `editType` string matching this flaglist.', @@ -49,7 +49,8 @@ var layoutOpts = { '*modebar* just updates the modebar.', '*camera* just updates the camera settings for gl3d scenes.', '*arraydraw* allows component arrays to invoke the redraw routines just for the', - 'component(s) that changed.' + 'component(s) that changed.', + '*colorbars* only redraws colorbars.' ].join(' ') }; diff --git a/src/plot_api/plot_api.js b/src/plot_api/plot_api.js index 7476b40c727..070ba387819 100644 --- a/src/plot_api/plot_api.js +++ b/src/plot_api/plot_api.js @@ -1871,6 +1871,7 @@ function relayout(gd, astr, val) { if(flags.ticks) seq.push(subroutines.doTicksRelayout); if(flags.modebar) seq.push(subroutines.doModeBar); if(flags.camera) seq.push(subroutines.doCamera); + if(flags.colorbars) seq.push(subroutines.doColorBars); seq.push(emitAfterPlot); } @@ -2382,7 +2383,7 @@ function update(gd, traceUpdate, layoutUpdate, _traces) { axRangeSupplyDefaultsByPass(gd, relayoutFlags, relayoutSpecs) || Plots.supplyDefaults(gd); if(restyleFlags.style) seq.push(subroutines.doTraceStyle); - if(restyleFlags.colorbars) seq.push(subroutines.doColorBars); + if(restyleFlags.colorbars || relayoutFlags.colorbars) seq.push(subroutines.doColorBars); if(relayoutFlags.legend) seq.push(subroutines.doLegend); if(relayoutFlags.layoutstyle) seq.push(subroutines.layoutStyles); if(relayoutFlags.axrange) addAxRangeSequence(seq, relayoutSpecs.rangesAltered); @@ -2779,7 +2780,7 @@ exports.react = function(gd, data, layout, config) { seq.push(Plots.previousPromises); if(restyleFlags.style) seq.push(subroutines.doTraceStyle); - if(restyleFlags.colorbars) seq.push(subroutines.doColorBars); + if(restyleFlags.colorbars || relayoutFlags.colorbars) seq.push(subroutines.doColorBars); if(relayoutFlags.legend) seq.push(subroutines.doLegend); if(relayoutFlags.layoutstyle) seq.push(subroutines.layoutStyles); if(relayoutFlags.axrange) addAxRangeSequence(seq); diff --git a/src/plot_api/plot_schema.js b/src/plot_api/plot_schema.js index 5dbe3fb4774..516a79c0fcf 100644 --- a/src/plot_api/plot_schema.js +++ b/src/plot_api/plot_schema.js @@ -373,7 +373,9 @@ function layoutHeadAttr(fullLayout, head) { */ for(key in Registry.componentsRegistry) { _module = Registry.componentsRegistry[key]; - if(!_module.schema && (head === _module.name)) { + if(_module.name === 'colorscale' && head.indexOf('coloraxis') === 0) { + return _module.layoutAttributes[head]; + } else if(!_module.schema && (head === _module.name)) { return _module.layoutAttributes; } } @@ -544,24 +546,26 @@ function getLayoutAttributes() { var schema = _module.schema; if(schema && (schema.subplots || schema.layout)) { - /* - * Components with defined schema have already been merged in at register time - * but a few components define attributes that apply only to xaxis - * not yaxis (rangeselector, rangeslider) - delete from y schema. - * Note that the input attributes for xaxis/yaxis are the same object - * so it's not possible to only add them to xaxis from the start. - * If we ever have such asymmetry the other way, or anywhere else, - * we will need to extend both this code and mergeComponentAttrsToSubplot - * (which will not find yaxis only for example) - */ - + /* + * Components with defined schema have already been merged in at register time + * but a few components define attributes that apply only to xaxis + * not yaxis (rangeselector, rangeslider) - delete from y schema. + * Note that the input attributes for xaxis/yaxis are the same object + * so it's not possible to only add them to xaxis from the start. + * If we ever have such asymmetry the other way, or anywhere else, + * we will need to extend both this code and mergeComponentAttrsToSubplot + * (which will not find yaxis only for example) + */ var subplots = schema.subplots; if(subplots && subplots.xaxis && !subplots.yaxis) { - for(var xkey in subplots.xaxis) delete layoutAttributes.yaxis[xkey]; + for(var xkey in subplots.xaxis) { + delete layoutAttributes.yaxis[xkey]; + } } + } else if(_module.name === 'colorscale') { + extendDeepAll(layoutAttributes, _module.layoutAttributes); } else if(_module.layoutAttributes) { - // older style without schema need to be explicitly merged in now - + // older style without schema need to be explicitly merged in now insertAttrs(layoutAttributes, _module.layoutAttributes, _module.name); } } diff --git a/src/plots/layout_attributes.js b/src/plots/layout_attributes.js index ac204dbe8c6..66b55d13da8 100644 --- a/src/plots/layout_attributes.js +++ b/src/plots/layout_attributes.js @@ -11,7 +11,6 @@ var fontAttrs = require('./font_attributes'); var animationAttrs = require('./animation_attributes'); var colorAttrs = require('../components/color/attributes'); -var colorscaleAttrs = require('../components/colorscale/layout_attributes'); var padAttrs = require('./pad_attributes'); var extendFlat = require('../lib/extend').extendFlat; @@ -292,7 +291,6 @@ module.exports = { editType: 'calc', description: 'Sets the default trace colors.' }, - colorscale: colorscaleAttrs, datarevision: { valType: 'any', role: 'info', diff --git a/src/plots/plots.js b/src/plots/plots.js index de8951680ba..8a92a745911 100644 --- a/src/plots/plots.js +++ b/src/plots/plots.js @@ -390,6 +390,8 @@ plots.supplyDefaults = function(gd, opts) { newFullLayout._firstScatter = {}; // for grouped bar/box/violin trace to share config across traces newFullLayout._alignmentOpts = {}; + // track color axes referenced in the data + newFullLayout._colorAxes = {}; // for traces to request a default rangeslider on their x axes // eg set `_requestRangeslider.x2 = true` for xaxis2 @@ -445,7 +447,6 @@ plots.supplyDefaults = function(gd, opts) { for(i = 0; i < crossTraceDefaultsFuncs.length; i++) { crossTraceDefaultsFuncs[i](newFullData, newFullLayout); } - Registry.getComponentMethod('colorscale', 'crossTraceDefaults')(newFullData, newFullLayout); // turn on flag to optimize large splom-only graphs // mostly by omitting SVG layers during Cartesian.drawFramework @@ -485,6 +486,9 @@ plots.supplyDefaults = function(gd, opts) { // relink functions and _ attributes to promote consistency between plots relinkPrivateKeys(newFullLayout, oldFullLayout); + // colorscale crossTraceDefaults needs newFullLayout with relinked keys + Registry.getComponentMethod('colorscale', 'crossTraceDefaults')(newFullData, newFullLayout); + // For persisting GUI-driven changes in layout // _preGUI and _tracePreGUI were already copied over in relinkPrivateKeys if(!newFullLayout._preGUI) newFullLayout._preGUI = {}; diff --git a/src/traces/bar/attributes.js b/src/traces/bar/attributes.js index 5cf9003da59..b9c4526df62 100644 --- a/src/traces/bar/attributes.js +++ b/src/traces/bar/attributes.js @@ -10,8 +10,7 @@ var scatterAttrs = require('../scatter/attributes'); var hovertemplateAttrs = require('../../components/fx/hovertemplate_attributes'); -var colorAttributes = require('../../components/colorscale/attributes'); -var colorbarAttrs = require('../../components/colorbar/attributes'); +var colorScaleAttrs = require('../../components/colorscale/attributes'); var fontAttrs = require('../../plots/font_attributes'); var constants = require('./constants.js'); @@ -33,13 +32,12 @@ var markerLineWidth = extendFlat({}, var markerLine = extendFlat({ width: markerLineWidth, editType: 'calc' -}, colorAttributes('marker.line')); +}, colorScaleAttrs('marker.line')); var marker = extendFlat({ line: markerLine, editType: 'calc' -}, colorAttributes('marker'), { - colorbar: colorbarAttrs, +}, colorScaleAttrs('marker'), { opacity: { valType: 'number', arrayOk: true, diff --git a/src/traces/choropleth/attributes.js b/src/traces/choropleth/attributes.js index 5e68b2b7f71..827f25d7dfa 100644 --- a/src/traces/choropleth/attributes.js +++ b/src/traces/choropleth/attributes.js @@ -10,8 +10,7 @@ var hovertemplateAttrs = require('../../components/fx/hovertemplate_attributes'); var scatterGeoAttrs = require('../scattergeo/attributes'); -var colorscaleAttrs = require('../../components/colorscale/attributes'); -var colorbarAttrs = require('../../components/colorbar/attributes'); +var colorScaleAttrs = require('../../components/colorscale/attributes'); var plotAttrs = require('../../plots/attributes'); var extendFlat = require('../../lib/extend').extendFlat; @@ -80,9 +79,8 @@ module.exports = extendFlat({ hovertemplate: hovertemplateAttrs(), }, - colorscaleAttrs('', { + colorScaleAttrs('', { cLetter: 'z', editTypeOverride: 'calc' - }), - {colorbar: colorbarAttrs} + }) ); diff --git a/src/traces/choropleth/style.js b/src/traces/choropleth/style.js index 9da61ac1580..c87efa20954 100644 --- a/src/traces/choropleth/style.js +++ b/src/traces/choropleth/style.js @@ -24,9 +24,7 @@ function styleTrace(gd, calcTrace) { var marker = trace.marker || {}; var markerLine = marker.line || {}; - var sclFunc = Colorscale.makeColorScaleFunc( - Colorscale.extractScale(trace, {cLetter: 'z'}) - ); + var sclFunc = Colorscale.makeColorScaleFuncFromTrace(trace); locs.each(function(d) { d3.select(this) diff --git a/src/traces/cone/attributes.js b/src/traces/cone/attributes.js index 0df3c8d9964..a47c8dc8ee5 100644 --- a/src/traces/cone/attributes.js +++ b/src/traces/cone/attributes.js @@ -8,8 +8,7 @@ 'use strict'; -var colorscaleAttrs = require('../../components/colorscale/attributes'); -var colorbarAttrs = require('../../components/colorbar/attributes'); +var colorScaleAttrs = require('../../components/colorscale/attributes'); var hovertemplateAttrs = require('../../components/fx/hovertemplate_attributes'); var mesh3dAttrs = require('../mesh3d/attributes'); var baseAttrs = require('../../plots/attributes'); @@ -170,13 +169,11 @@ var attrs = { hovertemplate: hovertemplateAttrs({editType: 'calc'}, {keys: ['norm']}) }; -extendFlat(attrs, colorscaleAttrs('', { +extendFlat(attrs, colorScaleAttrs('', { colorAttr: 'u/v/w norm', showScaleDflt: true, editTypeOverride: 'calc' -}), { - colorbar: colorbarAttrs -}); +})); var fromMesh3d = ['opacity', 'lightposition', 'lighting']; diff --git a/src/traces/cone/convert.js b/src/traces/cone/convert.js index dcdfcb9d5f1..740258a4998 100644 --- a/src/traces/cone/convert.js +++ b/src/traces/cone/convert.js @@ -13,6 +13,7 @@ var createConeMesh = require('gl-cone3d').createConeMesh; var simpleMap = require('../../lib').simpleMap; var parseColorScale = require('../../lib/gl_format_color').parseColorScale; +var extractOpts = require('../../components/colorscale').extractOpts; var zip3 = require('../../plots/gl3d/zip3'); function Cone(scene, uid) { @@ -80,8 +81,9 @@ function convert(scene, trace) { trace._len ); + var cOpts = extractOpts(trace); coneOpts.colormap = parseColorScale(trace); - coneOpts.vertexIntensityBounds = [trace.cmin / trace._normMax, trace.cmax / trace._normMax]; + coneOpts.vertexIntensityBounds = [cOpts.min / trace._normMax, cOpts.max / trace._normMax]; coneOpts.coneOffset = anchor2coneOffset[trace.anchor]; if(trace.sizemode === 'scaled') { diff --git a/src/traces/contour/attributes.js b/src/traces/contour/attributes.js index 4e48ff14beb..4d2fef35fcc 100644 --- a/src/traces/contour/attributes.js +++ b/src/traces/contour/attributes.js @@ -10,8 +10,7 @@ var heatmapAttrs = require('../heatmap/attributes'); var scatterAttrs = require('../scatter/attributes'); -var colorscaleAttrs = require('../../components/colorscale/attributes'); -var colorbarAttrs = require('../../components/colorbar/attributes'); +var colorScaleAttrs = require('../../components/colorscale/attributes'); var dash = require('../../components/drawing/attributes').dash; var fontAttrs = require('../../plots/font_attributes'); var extendFlat = require('../../lib/extend').extendFlat; @@ -251,10 +250,9 @@ module.exports = extendFlat({ editType: 'plot' } }, - colorscaleAttrs('', { + colorScaleAttrs('', { cLetter: 'z', autoColorDflt: false, editTypeOverride: 'calc' - }), - { colorbar: colorbarAttrs } + }) ); diff --git a/src/traces/contour/calc.js b/src/traces/contour/calc.js index 5f16e8f312c..7f764e22f2e 100644 --- a/src/traces/contour/calc.js +++ b/src/traces/contour/calc.js @@ -6,17 +6,46 @@ * LICENSE file in the root directory of this source tree. */ - 'use strict'; +var Colorscale = require('../../components/colorscale'); + var heatmapCalc = require('../heatmap/calc'); var setContours = require('./set_contours'); +var endPlus = require('./end_plus'); // most is the same as heatmap calc, then adjust it // though a few things inside heatmap calc still look for // contour maps, because the makeBoundArray calls are too entangled module.exports = function calc(gd, trace) { var cd = heatmapCalc(gd, trace); - setContours(trace); + + var zOut = cd[0].z; + setContours(trace, zOut); + + var contours = trace.contours; + var cOpts = Colorscale.extractOpts(trace); + var cVals; + + if(contours.coloring === 'heatmap' && cOpts.auto && trace.autocontour === false) { + var start = contours.start; + var end = endPlus(contours); + var cs = contours.size || 1; + var nc = Math.floor((end - start) / cs) + 1; + + if(!isFinite(cs)) { + cs = 1; + nc = 1; + } + + var min0 = start - cs / 2; + var max0 = min0 + nc * cs; + cVals = [min0, max0]; + } else { + cVals = zOut; + } + + Colorscale.calc(gd, trace, {vals: cVals, cLetter: 'z'}); + return cd; }; diff --git a/src/traces/contour/colorbar.js b/src/traces/contour/colorbar.js index 0dd7a58c0eb..46514b90a78 100644 --- a/src/traces/contour/colorbar.js +++ b/src/traces/contour/colorbar.js @@ -8,11 +8,11 @@ 'use strict'; +var extractOpts = require('../../components/colorscale').extractOpts; var makeColorMap = require('./make_color_map'); var endPlus = require('./end_plus'); -function calc(gd, cd, opts) { - var trace = cd[0].trace; +function calc(gd, trace, opts) { var contours = trace.contours; var line = trace.line; var cs = contours.size || 1; @@ -20,8 +20,9 @@ function calc(gd, cd, opts) { var colorMap = makeColorMap(trace, {isColorbar: true}); if(coloring === 'heatmap') { + var cOpts = extractOpts(trace); opts._fillgradient = trace.colorscale; - opts._zrange = [trace.zmin, trace.zmax]; + opts._zrange = [cOpts.min, cOpts.max]; } else if(coloring === 'fill') { opts._fillcolor = colorMap; } diff --git a/src/traces/contour/make_color_map.js b/src/traces/contour/make_color_map.js index 74c1ca90889..c739bf25500 100644 --- a/src/traces/contour/make_color_map.js +++ b/src/traces/contour/make_color_map.js @@ -6,10 +6,10 @@ * LICENSE file in the root directory of this source tree. */ - 'use strict'; var d3 = require('d3'); + var Colorscale = require('../../components/colorscale'); var endPlus = require('./end_plus'); @@ -20,15 +20,16 @@ module.exports = function makeColorMap(trace) { var cs = contours.size || 1; var nc = Math.floor((end - start) / cs) + 1; var extra = contours.coloring === 'lines' ? 0 : 1; + var cOpts = Colorscale.extractOpts(trace); if(!isFinite(cs)) { cs = 1; nc = 1; } - var scl = trace.reversescale ? - Colorscale.flipScale(trace.colorscale) : - trace.colorscale; + var scl = cOpts.reversescale ? + Colorscale.flipScale(cOpts.colorscale) : + cOpts.colorscale; var len = scl.length; var domain = new Array(len); @@ -37,51 +38,45 @@ module.exports = function makeColorMap(trace) { var si, i; if(contours.coloring === 'heatmap') { - if(trace.zauto && trace.autocontour === false) { - trace.zmin = start - cs / 2; - trace.zmax = trace.zmin + nc * cs; - } + var zmin0 = cOpts.min; + var zmax0 = cOpts.max; for(i = 0; i < len; i++) { si = scl[i]; - - domain[i] = si[0] * (trace.zmax - trace.zmin) + trace.zmin; + domain[i] = si[0] * (zmax0 - zmin0) + zmin0; range[i] = si[1]; } // do the contours extend beyond the colorscale? // if so, extend the colorscale with constants var zRange = d3.extent([ - trace.zmin, - trace.zmax, + zmin0, + zmax0, contours.start, contours.start + cs * (nc - 1) ]); - var zmin = zRange[trace.zmin < trace.zmax ? 0 : 1]; - var zmax = zRange[trace.zmin < trace.zmax ? 1 : 0]; + var zmin = zRange[zmin0 < zmax0 ? 0 : 1]; + var zmax = zRange[zmin0 < zmax0 ? 1 : 0]; - if(zmin !== trace.zmin) { + if(zmin !== zmin0) { domain.splice(0, 0, zmin); - range.splice(0, 0, Range[0]); + range.splice(0, 0, range[0]); } - if(zmax !== trace.zmax) { + if(zmax !== zmax0) { domain.push(zmax); range.push(range[range.length - 1]); } } else { for(i = 0; i < len; i++) { si = scl[i]; - domain[i] = (si[0] * (nc + extra - 1) - (extra / 2)) * cs + start; range[i] = si[1]; } } - return Colorscale.makeColorScaleFunc({ - domain: domain, - range: range, - }, { - noNumericCheck: true - }); + return Colorscale.makeColorScaleFunc( + {domain: domain, range: range}, + {noNumericCheck: true} + ); }; diff --git a/src/traces/contour/plot.js b/src/traces/contour/plot.js index 0411e864695..201965f9765 100644 --- a/src/traces/contour/plot.js +++ b/src/traces/contour/plot.js @@ -43,12 +43,6 @@ exports.plot = function plot(gd, plotinfo, cdcontours, contourLayer) { var heatmapColoringLayer = Lib.ensureSingle(plotGroup, 'g', 'heatmapcoloring'); var cdheatmaps = []; if(contours.coloring === 'heatmap') { - if(trace.zauto && (trace.autocontour === false)) { - trace._input.zmin = trace.zmin = - contours.start - contours.size / 2; - trace._input.zmax = trace.zmax = - trace.zmin + pathinfo.length * contours.size; - } cdheatmaps = [cd]; } heatmapPlot(gd, plotinfo, cdheatmaps, heatmapColoringLayer); diff --git a/src/traces/contour/set_contours.js b/src/traces/contour/set_contours.js index 0804413a4a3..31d8f7f0f8b 100644 --- a/src/traces/contour/set_contours.js +++ b/src/traces/contour/set_contours.js @@ -6,28 +6,29 @@ * LICENSE file in the root directory of this source tree. */ - 'use strict'; var Axes = require('../../plots/cartesian/axes'); var Lib = require('../../lib'); - -module.exports = function setContours(trace) { +module.exports = function setContours(trace, vals) { var contours = trace.contours; // check if we need to auto-choose contour levels if(trace.autocontour) { + // N.B. do not try to use coloraxis cmin/cmax, + // these values here are meant to remain "per-trace" for now var zmin = trace.zmin; var zmax = trace.zmax; - if(zmin === undefined || zmax === undefined) { - zmin = Lib.aggNums(Math.min, null, trace._z); - zmax = Lib.aggNums(Math.max, null, trace._z); + if(trace.zauto || zmin === undefined) { + zmin = Lib.aggNums(Math.min, null, vals); + } + if(trace.zauto || zmax === undefined) { + zmax = Lib.aggNums(Math.max, null, vals); } - var dummyAx = autoContours(zmin, zmax, trace.ncontours); + var dummyAx = autoContours(zmin, zmax, trace.ncontours); contours.size = dummyAx.dtick; - contours.start = Axes.tickFirst(dummyAx); dummyAx.range.reverse(); contours.end = Axes.tickFirst(dummyAx); diff --git a/src/traces/contourcarpet/attributes.js b/src/traces/contourcarpet/attributes.js index 6bcec99d63f..d2d28b86aef 100644 --- a/src/traces/contourcarpet/attributes.js +++ b/src/traces/contourcarpet/attributes.js @@ -12,8 +12,7 @@ var heatmapAttrs = require('../heatmap/attributes'); var contourAttrs = require('../contour/attributes'); var contourContourAttrs = contourAttrs.contours; var scatterAttrs = require('../scatter/attributes'); -var colorscaleAttrs = require('../../components/colorscale/attributes'); -var colorbarAttrs = require('../../components/colorbar/attributes'); +var colorScaleAttrs = require('../../components/colorscale/attributes'); var extendFlat = require('../../lib/extend').extendFlat; @@ -95,9 +94,8 @@ module.exports = extendFlat({ transforms: undefined }, - colorscaleAttrs('', { + colorScaleAttrs('', { cLetter: 'z', autoColorDflt: false - }), - { colorbar: colorbarAttrs } + }) ); diff --git a/src/traces/contourcarpet/calc.js b/src/traces/contourcarpet/calc.js index 07d5919ab34..73f418dbccc 100644 --- a/src/traces/contourcarpet/calc.js +++ b/src/traces/contourcarpet/calc.js @@ -45,8 +45,7 @@ module.exports = function calc(gd, trace) { } var cd = heatmappishCalc(gd, trace); - - setContours(trace); + setContours(trace, trace._z); return cd; }; diff --git a/src/traces/heatmap/attributes.js b/src/traces/heatmap/attributes.js index 89cc79bf02c..4821fcbeb0f 100644 --- a/src/traces/heatmap/attributes.js +++ b/src/traces/heatmap/attributes.js @@ -10,8 +10,7 @@ var scatterAttrs = require('../scatter/attributes'); var hovertemplateAttrs = require('../../components/fx/hovertemplate_attributes'); -var colorscaleAttrs = require('../../components/colorscale/attributes'); -var colorbarAttrs = require('../../components/colorbar/attributes'); +var colorScaleAttrs = require('../../components/colorscale/attributes'); var extendFlat = require('../../lib/extend').extendFlat; @@ -121,9 +120,5 @@ module.exports = extendFlat({ }, { transforms: undefined }, - colorscaleAttrs('', { - cLetter: 'z', - autoColorDflt: false - }), - { colorbar: colorbarAttrs } + colorScaleAttrs('', {cLetter: 'z', autoColorDflt: false}) ); diff --git a/src/traces/heatmap/calc.js b/src/traces/heatmap/calc.js index f86bb23ed37..69633c278f3 100644 --- a/src/traces/heatmap/calc.js +++ b/src/traces/heatmap/calc.js @@ -142,13 +142,8 @@ module.exports = function calc(gd, trace) { cd0.pts = binned.pts; } - // auto-z and autocolorscale if applicable - if(!isContour || trace.contours.type !== 'constraint') { - colorscaleCalc(gd, trace, { - vals: z, - containerStr: '', - cLetter: 'z' - }); + if(!isContour) { + colorscaleCalc(gd, trace, {vals: z, cLetter: 'z'}); } if(isContour && trace.contours && trace.contours.coloring === 'heatmap') { diff --git a/src/traces/heatmap/hover.js b/src/traces/heatmap/hover.js index cfc2e72f0c2..55e9f63d195 100644 --- a/src/traces/heatmap/hover.js +++ b/src/traces/heatmap/hover.js @@ -6,12 +6,12 @@ * LICENSE file in the root directory of this source tree. */ - 'use strict'; var Fx = require('../../components/fx'); var Lib = require('../../lib'); var Axes = require('../../plots/cartesian/axes'); +var extractOpts = require('../../components/colorscale').extractOpts; module.exports = function hoverPoints(pointData, xval, yval, hovermode, hoverLayer, contour) { var cd0 = pointData.cd[0]; @@ -24,7 +24,6 @@ module.exports = function hoverPoints(pointData, xval, yval, hovermode, hoverLay var xc = cd0.xCenter; var yc = cd0.yCenter; var zmask = cd0.zmask; - var range = [trace.zmin, trace.zmax]; var zhoverformat = trace.zhoverformat; var x2 = x; var y2 = y; @@ -95,17 +94,16 @@ module.exports = function hoverPoints(pointData, xval, yval, hovermode, hoverLay text = cd0.text[ny][nx]; } - var zLabel; // dummy axis for formatting the z value + var cOpts = extractOpts(trace); var dummyAx = { type: 'linear', - range: range, + range: [cOpts.min, cOpts.max], hoverformat: zhoverformat, _separators: xa._separators, _numFormat: xa._numFormat }; - var zLabelObj = Axes.tickText(dummyAx, zVal, 'hover'); - zLabel = zLabelObj.text; + var zLabel = Axes.tickText(dummyAx, zVal, 'hover').text; return [Lib.extendFlat(pointData, { index: [ny, nx], diff --git a/src/traces/heatmap/plot.js b/src/traces/heatmap/plot.js index 190d56e2a4b..66259cfcf1c 100644 --- a/src/traces/heatmap/plot.js +++ b/src/traces/heatmap/plot.js @@ -14,7 +14,7 @@ var tinycolor = require('tinycolor2'); var Registry = require('../../registry'); var Lib = require('../../lib'); -var Colorscale = require('../../components/colorscale'); +var makeColorScaleFuncFromTrace = require('../../components/colorscale').makeColorScaleFuncFromTrace; var xmlnsNamespaces = require('../../constants/xmlns_namespaces'); module.exports = function(gd, plotinfo, cdheatmaps, heatmapLayer) { @@ -140,10 +140,7 @@ module.exports = function(gd, plotinfo, cdheatmaps, heatmapLayer) { canvas.height = canvasH; var context = canvas.getContext('2d'); - var sclFunc = Colorscale.makeColorScaleFunc( - Colorscale.extractScale(trace, {cLetter: 'z'}), - { noNumericCheck: true, returnArray: true } - ); + var sclFunc = makeColorScaleFuncFromTrace(trace, {noNumericCheck: true, returnArray: true}); // map brick boundaries to image pixels var xpx, diff --git a/src/traces/heatmapgl/attributes.js b/src/traces/heatmapgl/attributes.js index 081fb12499b..8769247f0d3 100644 --- a/src/traces/heatmapgl/attributes.js +++ b/src/traces/heatmapgl/attributes.js @@ -8,15 +8,12 @@ 'use strict'; - var heatmapAttrs = require('../heatmap/attributes'); -var colorscaleAttrs = require('../../components/colorscale/attributes'); -var colorbarAttrs = require('../../components/colorbar/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', @@ -34,8 +31,7 @@ for(var i = 0; i < commonList.length; i++) { extendFlat( attrs, - colorscaleAttrs('', {cLetter: 'z', autoColorDflt: false}), - {colorbar: colorbarAttrs} + colorScaleAttrs('', {cLetter: 'z', autoColorDflt: false}) ); module.exports = overrideAll(attrs, 'calc', 'nested'); diff --git a/src/traces/histogram2d/attributes.js b/src/traces/histogram2d/attributes.js index 72befadf1fd..ae4648c929f 100644 --- a/src/traces/histogram2d/attributes.js +++ b/src/traces/histogram2d/attributes.js @@ -12,8 +12,7 @@ var histogramAttrs = require('../histogram/attributes'); var makeBinAttrs = require('../histogram/bin_attributes'); var heatmapAttrs = require('../heatmap/attributes'); var hovertemplateAttrs = require('../../components/fx/hovertemplate_attributes'); -var colorscaleAttrs = require('../../components/colorscale/attributes'); -var colorbarAttrs = require('../../components/colorbar/attributes'); +var colorScaleAttrs = require('../../components/colorscale/attributes'); var extendFlat = require('../../lib/extend').extendFlat; @@ -51,9 +50,5 @@ module.exports = extendFlat( zhoverformat: heatmapAttrs.zhoverformat, hovertemplate: hovertemplateAttrs({}, {keys: 'z'}) }, - colorscaleAttrs('', { - cLetter: 'z', - autoColorDflt: false - }), - { colorbar: colorbarAttrs } + colorScaleAttrs('', {cLetter: 'z', autoColorDflt: false}) ); diff --git a/src/traces/histogram2dcontour/attributes.js b/src/traces/histogram2dcontour/attributes.js index 2dfe6dc89c2..19c4db142bf 100644 --- a/src/traces/histogram2dcontour/attributes.js +++ b/src/traces/histogram2dcontour/attributes.js @@ -10,8 +10,7 @@ var histogram2dAttrs = require('../histogram2d/attributes'); var contourAttrs = require('../contour/attributes'); -var colorscaleAttrs = require('../../components/colorscale/attributes'); -var colorbarAttrs = require('../../components/colorbar/attributes'); +var colorScaleAttrs = require('../../components/colorscale/attributes'); var extendFlat = require('../../lib/extend').extendFlat; @@ -37,9 +36,8 @@ module.exports = extendFlat({ zhoverformat: histogram2dAttrs.zhoverformat, hovertemplate: histogram2dAttrs.hovertemplate }, - colorscaleAttrs('', { + colorScaleAttrs('', { cLetter: 'z', editTypeOverride: 'calc' - }), - { colorbar: colorbarAttrs } + }) ); diff --git a/src/traces/isosurface/attributes.js b/src/traces/isosurface/attributes.js index bff5d187dd3..37cf47f316e 100644 --- a/src/traces/isosurface/attributes.js +++ b/src/traces/isosurface/attributes.js @@ -8,8 +8,7 @@ 'use strict'; -var colorscaleAttrs = require('../../components/colorscale/attributes'); -var colorbarAttrs = require('../../components/colorbar/attributes'); +var colorScaleAttrs = require('../../components/colorscale/attributes'); var hovertemplateAttrs = require('../../components/fx/hovertemplate_attributes'); var meshAttrs = require('../mesh3d/attributes'); var baseAttrs = require('../../plots/attributes'); @@ -236,14 +235,11 @@ var attrs = module.exports = overrideAll(extendFlat({ hovertemplate: hovertemplateAttrs() }, -colorscaleAttrs('', { +colorScaleAttrs('', { colorAttr: '`value`', showScaleDflt: true, editTypeOverride: 'calc' }), { - - colorbar: colorbarAttrs, - opacity: meshAttrs.opacity, lightposition: meshAttrs.lightposition, lighting: meshAttrs.lighting, diff --git a/src/traces/isosurface/convert.js b/src/traces/isosurface/convert.js index 0e50885f9e7..d3a67e00f25 100644 --- a/src/traces/isosurface/convert.js +++ b/src/traces/isosurface/convert.js @@ -6,15 +6,16 @@ * LICENSE file in the root directory of this source tree. */ - 'use strict'; var createMesh = require('gl-mesh3d'); +var Lib = require('../../lib'); + var parseColorScale = require('../../lib/gl_format_color').parseColorScale; var str2RgbaArray = require('../../lib/str2rgbarray'); +var extractOpts = require('../../components/colorscale').extractOpts; var zip3 = require('../../plots/gl3d/zip3'); -var Lib = require('../../lib'); function distinctVals(col) { return Lib.distinctVals(col).vals; @@ -121,8 +122,9 @@ proto.update = function(data) { useFacetNormals: data.flatshading }; + var cOpts = extractOpts(data); config.vertexIntensity = data._intensity; - config.vertexIntensityBounds = [data.cmin, data.cmax]; + config.vertexIntensityBounds = [cOpts.min, cOpts.max]; config.colormap = parseColorScale(data); // Update mesh diff --git a/src/traces/mesh3d/attributes.js b/src/traces/mesh3d/attributes.js index bd90dfb8e86..c383df63a7a 100644 --- a/src/traces/mesh3d/attributes.js +++ b/src/traces/mesh3d/attributes.js @@ -8,8 +8,7 @@ 'use strict'; -var colorscaleAttrs = require('../../components/colorscale/attributes'); -var colorbarAttrs = require('../../components/colorbar/attributes'); +var colorScaleAttrs = require('../../components/colorscale/attributes'); var hovertemplateAttrs = require('../../components/fx/hovertemplate_attributes'); var surfaceAtts = require('../surface/attributes'); var baseAttrs = require('../../plots/attributes'); @@ -178,14 +177,11 @@ module.exports = extendFlat({ transforms: undefined }, -colorscaleAttrs('', { +colorScaleAttrs('', { colorAttr: '`intensity`', showScaleDflt: true, editTypeOverride: 'calc' }), { - - colorbar: colorbarAttrs, - opacity: surfaceAtts.opacity, // Flat shaded mode diff --git a/src/traces/mesh3d/convert.js b/src/traces/mesh3d/convert.js index dca58ed8355..bc9b69ebfa4 100644 --- a/src/traces/mesh3d/convert.js +++ b/src/traces/mesh3d/convert.js @@ -6,7 +6,6 @@ * LICENSE file in the root directory of this source tree. */ - 'use strict'; var createMesh = require('gl-mesh3d'); @@ -16,6 +15,7 @@ var convexHull = require('convex-hull'); var parseColorScale = require('../../lib/gl_format_color').parseColorScale; var str2RgbaArray = require('../../lib/str2rgbarray'); +var extractOpts = require('../../components/colorscale').extractOpts; var zip3 = require('../../plots/gl3d/zip3'); function Mesh3DTrace(scene, mesh, uid) { @@ -158,9 +158,10 @@ proto.update = function(data) { }; if(data.intensity) { + var cOpts = extractOpts(data); this.color = '#fff'; config.vertexIntensity = data.intensity; - config.vertexIntensityBounds = [data.cmin, data.cmax]; + config.vertexIntensityBounds = [cOpts.min, cOpts.max]; config.colormap = parseColorScale(data); } else if(data.vertexcolor) { this.color = data.vertexcolor[0]; diff --git a/src/traces/parcats/attributes.js b/src/traces/parcats/attributes.js index 98b6ada66cd..a2188a08636 100644 --- a/src/traces/parcats/attributes.js +++ b/src/traces/parcats/attributes.js @@ -11,19 +11,14 @@ var extendFlat = require('../../lib/extend').extendFlat; var plotAttrs = require('../../plots/attributes'); var fontAttrs = require('../../plots/font_attributes'); -var colorAttributes = require('../../components/colorscale/attributes'); +var colorScaleAttrs = require('../../components/colorscale/attributes'); var hovertemplateAttrs = require('../../components/fx/hovertemplate_attributes'); var domainAttrs = require('../../plots/domain').attributes; -var scatterAttrs = require('../scatter/attributes'); -var scatterLineAttrs = scatterAttrs.line; -var colorbarAttrs = require('../../components/colorbar/attributes'); -var line = extendFlat({ - editType: 'calc' -}, colorAttributes('line', {editType: 'calc'}), +var line = extendFlat( + {editType: 'calc'}, + colorScaleAttrs('line', {editTypeOverride: 'calc'}), { - showscale: scatterLineAttrs.showscale, - colorbar: colorbarAttrs, shape: { valType: 'enumerated', values: ['linear', 'hspline'], @@ -46,7 +41,8 @@ var line = extendFlat({ 'This value here applies when hovering over lines.' ].join(' ') }) - }); + } +); module.exports = { domain: domainAttrs({name: 'parcats', trace: true, editType: 'calc'}), diff --git a/src/traces/parcoords/attributes.js b/src/traces/parcoords/attributes.js index 7994896990b..bf1f7223410 100644 --- a/src/traces/parcoords/attributes.js +++ b/src/traces/parcoords/attributes.js @@ -8,8 +8,7 @@ 'use strict'; -var colorAttributes = require('../../components/colorscale/attributes'); -var colorbarAttrs = require('../../components/colorbar/attributes'); +var colorScaleAttrs = require('../../components/colorscale/attributes'); var axesAttrs = require('../../plots/cartesian/layout_attributes'); var fontAttrs = require('../../plots/font_attributes'); var domainAttrs = require('../../plots/domain').attributes; @@ -112,15 +111,13 @@ module.exports = { description: 'The dimensions (variables) of the parallel coordinates chart. 2..60 dimensions are supported.' }), - line: extendFlat( - colorAttributes('line', { + line: extendFlat({editType: 'calc'}, + colorScaleAttrs('line', { // the default autocolorscale isn't quite usable for parcoords due to context ambiguity around 0 (grey, off-white) // autocolorscale therefore defaults to false too, to avoid being overridden by the blue-white-red autocolor palette colorscaleDflt: 'Viridis', autoColorDflt: false, editTypeOverride: 'calc' - }), { - colorbar: colorbarAttrs, - editType: 'calc' }) + ) }; diff --git a/src/traces/scatter/attributes.js b/src/traces/scatter/attributes.js index 86f8161f82e..e46a5f75513 100644 --- a/src/traces/scatter/attributes.js +++ b/src/traces/scatter/attributes.js @@ -9,8 +9,7 @@ 'use strict'; var hovertemplateAttrs = require('../../components/fx/hovertemplate_attributes'); -var colorAttributes = require('../../components/colorscale/attributes'); -var colorbarAttrs = require('../../components/colorbar/attributes'); +var colorScaleAttrs = require('../../components/colorscale/attributes'); var fontAttrs = require('../../plots/font_attributes'); var dash = require('../../components/drawing/attributes').dash; @@ -415,8 +414,6 @@ module.exports = { ].join(' ') }, - colorbar: colorbarAttrs, - line: extendFlat({ width: { valType: 'number', @@ -429,7 +426,7 @@ module.exports = { }, editType: 'calc' }, - colorAttributes('marker.line', {anim: true}) + colorScaleAttrs('marker.line', {anim: true}) ), gradient: { type: { @@ -458,7 +455,7 @@ module.exports = { }, editType: 'calc' }, - colorAttributes('marker', {anim: true}) + colorScaleAttrs('marker', {anim: true}) ), selected: { marker: { diff --git a/src/traces/scattercarpet/attributes.js b/src/traces/scattercarpet/attributes.js index c263e3b333a..3c2fed05336 100644 --- a/src/traces/scattercarpet/attributes.js +++ b/src/traces/scattercarpet/attributes.js @@ -11,8 +11,7 @@ var scatterAttrs = require('../scatter/attributes'); var plotAttrs = require('../../plots/attributes'); var hovertemplateAttrs = require('../../components/fx/hovertemplate_attributes'); -var colorAttributes = require('../../components/colorscale/attributes'); -var colorbarAttrs = require('../../components/colorbar/attributes'); +var colorScaleAttrs = require('../../components/colorscale/attributes'); var extendFlat = require('../../lib/extend').extendFlat; @@ -101,13 +100,13 @@ module.exports = { width: scatterMarkerLineAttrs.width, editType: 'calc' }, - colorAttributes('marker.line') + colorScaleAttrs('marker.line') ), gradient: scatterMarkerAttrs.gradient, editType: 'calc' - }, colorAttributes('marker'), { - colorbar: colorbarAttrs - }), + }, + colorScaleAttrs('marker') + ), textfont: scatterAttrs.textfont, textposition: scatterAttrs.textposition, diff --git a/src/traces/scattergl/attributes.js b/src/traces/scattergl/attributes.js index fb78d50a5b8..4aa74ec4202 100644 --- a/src/traces/scattergl/attributes.js +++ b/src/traces/scattergl/attributes.js @@ -10,7 +10,7 @@ var plotAttrs = require('../../plots/attributes'); var scatterAttrs = require('../scatter/attributes'); -var colorAttrs = require('../../components/colorscale/attributes'); +var colorScaleAttrs = require('../../components/colorscale/attributes'); var extendFlat = require('../../lib/extend').extendFlat; var overrideAll = require('../../plot_api/edit_types').overrideAll; @@ -65,7 +65,7 @@ var attrs = module.exports = overrideAll({ description: 'Sets the style of the lines.' } }, - marker: extendFlat({}, colorAttrs('marker'), { + marker: extendFlat({}, colorScaleAttrs('marker'), { symbol: scatterMarkerAttrs.symbol, size: scatterMarkerAttrs.size, sizeref: scatterMarkerAttrs.sizeref, @@ -73,7 +73,7 @@ var attrs = module.exports = overrideAll({ sizemode: scatterMarkerAttrs.sizemode, opacity: scatterMarkerAttrs.opacity, colorbar: scatterMarkerAttrs.colorbar, - line: extendFlat({}, colorAttrs('marker.line'), { + line: extendFlat({}, colorScaleAttrs('marker.line'), { width: scatterMarkerLineAttrs.width }) }), diff --git a/src/traces/scattermapbox/attributes.js b/src/traces/scattermapbox/attributes.js index 8609904e1a2..876e9e4f9c2 100644 --- a/src/traces/scattermapbox/attributes.js +++ b/src/traces/scattermapbox/attributes.js @@ -13,7 +13,7 @@ var scatterGeoAttrs = require('../scattergeo/attributes'); var scatterAttrs = require('../scatter/attributes'); var mapboxAttrs = require('../../plots/mapbox/layout_attributes'); var plotAttrs = require('../../plots/attributes'); -var colorbarAttrs = require('../../components/colorbar/attributes'); +var colorScaleAttrs = require('../../components/colorscale/attributes'); var extendFlat = require('../../lib/extend').extendFlat; var overrideAll = require('../../plot_api/edit_types').overrideAll; @@ -70,7 +70,7 @@ module.exports = overrideAll({ connectgaps: scatterAttrs.connectgaps, - marker: { + marker: extendFlat({ symbol: { valType: 'string', dflt: 'circle', @@ -87,20 +87,11 @@ module.exports = overrideAll({ size: markerAttrs.size, sizeref: markerAttrs.sizeref, sizemin: markerAttrs.sizemin, - sizemode: markerAttrs.sizemode, - color: markerAttrs.color, - colorscale: markerAttrs.colorscale, - cauto: markerAttrs.cauto, - cmax: markerAttrs.cmax, - cmin: markerAttrs.cmin, - cmid: markerAttrs.cmid, - autocolorscale: markerAttrs.autocolorscale, - reversescale: markerAttrs.reversescale, - showscale: markerAttrs.showscale, - colorbar: colorbarAttrs, - - // line + sizemode: markerAttrs.sizemode }, + colorScaleAttrs('marker') + // line + ), fill: scatterGeoAttrs.fill, fillcolor: scatterAttrs.fillcolor, diff --git a/src/traces/scattermapbox/convert.js b/src/traces/scattermapbox/convert.js index 5dbc94ced6a..8aba0245549 100644 --- a/src/traces/scattermapbox/convert.js +++ b/src/traces/scattermapbox/convert.js @@ -157,9 +157,7 @@ function makeCircleOpts(calcTrace) { var colorFn; if(arrayColor) { if(Colorscale.hasColorscale(trace, 'marker')) { - colorFn = Colorscale.makeColorScaleFunc( - Colorscale.extractScale(marker, {cLetter: 'c'}) - ); + colorFn = Colorscale.makeColorScaleFuncFromTrace(marker); } else { colorFn = Lib.identity; } diff --git a/src/traces/scatterternary/attributes.js b/src/traces/scatterternary/attributes.js index 439259f7897..9b86099c84b 100644 --- a/src/traces/scatterternary/attributes.js +++ b/src/traces/scatterternary/attributes.js @@ -11,8 +11,7 @@ var hovertemplateAttrs = require('../../components/fx/hovertemplate_attributes'); var scatterAttrs = require('../scatter/attributes'); var plotAttrs = require('../../plots/attributes'); -var colorAttributes = require('../../components/colorscale/attributes'); -var colorbarAttrs = require('../../components/colorbar/attributes'); +var colorScaleAttrs = require('../../components/colorscale/attributes'); var dash = require('../../components/drawing/attributes').dash; var extendFlat = require('../../lib/extend').extendFlat; @@ -130,13 +129,13 @@ module.exports = { width: scatterMarkerLineAttrs.width, editType: 'calc' }, - colorAttributes('marker.line') + colorScaleAttrs('marker.line') ), gradient: scatterMarkerAttrs.gradient, editType: 'calc' - }, colorAttributes('marker'), { - colorbar: colorbarAttrs - }), + }, + colorScaleAttrs('marker') + ), textfont: scatterAttrs.textfont, textposition: scatterAttrs.textposition, diff --git a/src/traces/splom/attributes.js b/src/traces/splom/attributes.js index d7c8e7fc311..e75878fdf25 100644 --- a/src/traces/splom/attributes.js +++ b/src/traces/splom/attributes.js @@ -9,7 +9,7 @@ 'use strict'; var scatterAttrs = require('../scatter/attributes'); -var colorAttrs = require('../../components/colorscale/attributes'); +var colorScaleAttrs = require('../../components/colorscale/attributes'); var hovertemplateAttrs = require('../../components/fx/hovertemplate_attributes'); var scatterGlAttrs = require('../scattergl/attributes'); var cartesianIdRegex = require('../../plots/cartesian/constants').idRegex; @@ -19,12 +19,12 @@ var extendFlat = require('../../lib/extend').extendFlat; var scatterMarkerAttrs = scatterAttrs.marker; var scatterMarkerLineAttrs = scatterMarkerAttrs.line; -var markerLineAttrs = extendFlat(colorAttrs('marker.line', {editTypeOverride: 'calc'}), { +var markerLineAttrs = extendFlat(colorScaleAttrs('marker.line', {editTypeOverride: 'calc'}), { width: extendFlat({}, scatterMarkerLineAttrs.width, {editType: 'calc'}), editType: 'calc' }); -var markerAttrs = extendFlat(colorAttrs('marker'), { +var markerAttrs = extendFlat(colorScaleAttrs('marker'), { symbol: scatterMarkerAttrs.symbol, size: extendFlat({}, scatterMarkerAttrs.size, {editType: 'markerSize'}), sizeref: scatterMarkerAttrs.sizeref, diff --git a/src/traces/streamtube/attributes.js b/src/traces/streamtube/attributes.js index c1a4c08810e..47b4f2f103b 100644 --- a/src/traces/streamtube/attributes.js +++ b/src/traces/streamtube/attributes.js @@ -8,8 +8,7 @@ 'use strict'; -var colorscaleAttrs = require('../../components/colorscale/attributes'); -var colorbarAttrs = require('../../components/colorbar/attributes'); +var colorScaleAttrs = require('../../components/colorscale/attributes'); var hovertemplateAttrs = require('../../components/fx/hovertemplate_attributes'); var mesh3dAttrs = require('../mesh3d/attributes'); var baseAttrs = require('../../plots/attributes'); @@ -148,13 +147,11 @@ var attrs = { }) }; -extendFlat(attrs, colorscaleAttrs('', { +extendFlat(attrs, colorScaleAttrs('', { colorAttr: 'u/v/w norm', showScaleDflt: true, editTypeOverride: 'calc' -}), { - colorbar: colorbarAttrs -}); +})); var fromMesh3d = ['opacity', 'lightposition', 'lighting']; fromMesh3d.forEach(function(k) { diff --git a/src/traces/streamtube/convert.js b/src/traces/streamtube/convert.js index ced5c0b1508..a958fb3cbfc 100644 --- a/src/traces/streamtube/convert.js +++ b/src/traces/streamtube/convert.js @@ -13,6 +13,7 @@ var createTubeMesh = tube2mesh.createTubeMesh; var Lib = require('../../lib'); var parseColorScale = require('../../lib/gl_format_color').parseColorScale; +var extractOpts = require('../../components/colorscale').extractOpts; var zip3 = require('../../plots/gl3d/zip3'); var axisName2scaleIndex = {xaxis: 0, yaxis: 1, zaxis: 2}; @@ -177,7 +178,8 @@ function convert(scene, trace) { // N.B. cmin/cmax correspond to the min/max vector norm // in the u/v/w arrays, which in general is NOT equal to max // intensity that colors the tubes. - meshData.vertexIntensityBounds = [trace.cmin / trace._normMax, trace.cmax / trace._normMax]; + var cOpts = extractOpts(trace); + meshData.vertexIntensityBounds = [cOpts.min / trace._normMax, cOpts.max / trace._normMax]; // pass gl-mesh3d lighting attributes var lp = trace.lightposition; diff --git a/src/traces/surface/attributes.js b/src/traces/surface/attributes.js index 56c8f14cfe8..7e0fbfe0a6f 100644 --- a/src/traces/surface/attributes.js +++ b/src/traces/surface/attributes.js @@ -9,8 +9,7 @@ 'use strict'; var Color = require('../../components/color'); -var colorscaleAttrs = require('../../components/colorscale/attributes'); -var colorbarAttrs = require('../../components/colorbar/attributes'); +var colorScaleAttrs = require('../../components/colorscale/attributes'); var hovertemplateAttrs = require('../../components/fx/hovertemplate_attributes'); var baseAttrs = require('../../plots/attributes'); @@ -188,14 +187,12 @@ var attrs = module.exports = overrideAll(extendFlat({ }, }, -colorscaleAttrs('', { +colorScaleAttrs('', { colorAttr: 'z or surfacecolor', showScaleDflt: true, autoColorDflt: false, editTypeOverride: 'calc' }), { - colorbar: colorbarAttrs, - contours: { x: makeContourAttr('x'), y: makeContourAttr('y'), @@ -302,13 +299,13 @@ colorscaleAttrs('', { }, _deprecated: { - zauto: extendFlat({}, colorscaleAttrs.zauto, { + zauto: extendFlat({}, colorScaleAttrs.zauto, { description: 'Obsolete. Use `cauto` instead.' }), - zmin: extendFlat({}, colorscaleAttrs.zmin, { + zmin: extendFlat({}, colorScaleAttrs.zmin, { description: 'Obsolete. Use `cmin` instead.' }), - zmax: extendFlat({}, colorscaleAttrs.zmax, { + zmax: extendFlat({}, colorScaleAttrs.zmax, { description: 'Obsolete. Use `cmax` instead.' }) }, diff --git a/src/traces/surface/convert.js b/src/traces/surface/convert.js index 1be1c4d50e9..9b2e44eb123 100644 --- a/src/traces/surface/convert.js +++ b/src/traces/surface/convert.js @@ -18,6 +18,7 @@ var fill = require('ndarray-fill'); var isArrayOrTypedArray = require('../../lib').isArrayOrTypedArray; var parseColorScale = require('../../lib/gl_format_color').parseColorScale; var str2RgbaArray = require('../../lib/str2rgbarray'); +var extractOpts = require('../../components/colorscale').extractOpts; var interp2d = require('../heatmap/interp2d'); var findEmpties = require('../heatmap/find_empties'); @@ -534,7 +535,8 @@ proto.update = function(data) { opacity: data.opacity }; - params.intensityBounds = [data.cmin, data.cmax]; + var cOpts = extractOpts(data); + params.intensityBounds = [cOpts.min, cOpts.max]; // Refine surface color if necessary if(data.surfacecolor) { diff --git a/src/traces/volume/attributes.js b/src/traces/volume/attributes.js index f677ed0b1cd..adf1e14eb6f 100644 --- a/src/traces/volume/attributes.js +++ b/src/traces/volume/attributes.js @@ -8,7 +8,7 @@ 'use strict'; -var colorscaleAttrs = require('../../components/colorscale/attributes'); +var colorScaleAttrs = require('../../components/colorscale/attributes'); var isosurfaceAttrs = require('../isosurface/attributes'); var baseAttrs = require('../../plots/attributes'); @@ -55,7 +55,7 @@ var attrs = module.exports = overrideAll(extendFlat({ hovertemplate: isosurfaceAttrs.hovertemplate }, -colorscaleAttrs('', { +colorScaleAttrs('', { colorAttr: '`value`', showScaleDflt: true, editTypeOverride: 'calc' diff --git a/src/traces/volume/convert.js b/src/traces/volume/convert.js index 219b191fd60..03437b0ad37 100644 --- a/src/traces/volume/convert.js +++ b/src/traces/volume/convert.js @@ -6,13 +6,13 @@ * LICENSE file in the root directory of this source tree. */ - 'use strict'; var createMesh = require('gl-mesh3d'); var parseColorScale = require('../../lib/gl_format_color').parseColorScale; var str2RgbaArray = require('../../lib/str2rgbarray'); +var extractOpts = require('../../components/colorscale').extractOpts; var zip3 = require('../../plots/gl3d/zip3'); var findNearestOnAxis = require('../isosurface/convert').findNearestOnAxis; @@ -103,8 +103,9 @@ proto.update = function(data) { useFacetNormals: data.flatshading }; + var cOpts = extractOpts(data); config.vertexIntensity = data._intensity; - config.vertexIntensityBounds = [data.cmin, data.cmax]; + config.vertexIntensityBounds = [cOpts.min, cOpts.max]; config.colormap = parseColorScale(data); // Update mesh diff --git a/test/image/baselines/contour-heatmap-coloring-set-contours.png b/test/image/baselines/contour-heatmap-coloring-set-contours.png new file mode 100644 index 00000000000..2bce86a4600 Binary files /dev/null and b/test/image/baselines/contour-heatmap-coloring-set-contours.png differ diff --git a/test/image/baselines/gl3d_coloraxes.png b/test/image/baselines/gl3d_coloraxes.png new file mode 100644 index 00000000000..1030595b4c4 Binary files /dev/null and b/test/image/baselines/gl3d_coloraxes.png differ diff --git a/test/image/baselines/gl3d_ribbons.png b/test/image/baselines/gl3d_ribbons.png index 0309f7c7ccc..f9083f8357f 100644 Binary files a/test/image/baselines/gl3d_ribbons.png and b/test/image/baselines/gl3d_ribbons.png differ diff --git a/test/image/baselines/gl3d_scatter3d-colorscale-marker-and-line.png b/test/image/baselines/gl3d_scatter3d-colorscale-marker-and-line.png new file mode 100644 index 00000000000..b5b807b9f5c Binary files /dev/null and b/test/image/baselines/gl3d_scatter3d-colorscale-marker-and-line.png differ diff --git a/test/image/baselines/shared_coloraxes.png b/test/image/baselines/shared_coloraxes.png new file mode 100644 index 00000000000..9941fa6a668 Binary files /dev/null and b/test/image/baselines/shared_coloraxes.png differ diff --git a/test/image/baselines/shared_coloraxes_contour.png b/test/image/baselines/shared_coloraxes_contour.png new file mode 100644 index 00000000000..b8e32c1db24 Binary files /dev/null and b/test/image/baselines/shared_coloraxes_contour.png differ diff --git a/test/image/mocks/contour-heatmap-coloring-set-contours.json b/test/image/mocks/contour-heatmap-coloring-set-contours.json new file mode 100644 index 00000000000..8b74c0f6250 --- /dev/null +++ b/test/image/mocks/contour-heatmap-coloring-set-contours.json @@ -0,0 +1,28 @@ +{ + "data": [{ + "name": "with set contours", + "type": "contour", + "x": [1, 2, 3], + "z": [[1, 2, 3], [1, 2, 3]], + "contours": { + "coloring": "heatmap", + "start": 0, "end": 5 + }, + "colorbar": { + "x": -0.05, "xanchor": "right", + "title": {"text": "with set
contours"} + } + }, { + "type": "contour", + "name": "auto contours", + "x": [5, 6, 7], + "z": [[1, 2, 3], [1, 2, 3]], + "contours": { + "coloring": "heatmap" + }, + "colorbar": { + "x": 1.05, "xanchor": "left", + "title": {"text": "auto
contours"} + } + }] +} diff --git a/test/image/mocks/gl3d_coloraxes.json b/test/image/mocks/gl3d_coloraxes.json new file mode 100644 index 00000000000..377cb0653a9 --- /dev/null +++ b/test/image/mocks/gl3d_coloraxes.json @@ -0,0 +1,1243 @@ +{ + "data": [{ + "type": "cone", + "x": [2, 3], + "y": [2, 3], + "z": [2, 3], + "u": [0, 0], + "v": [3, 0], + "w": [0, 2], + "coloraxis": "coloraxis" + }, { + "type": "streamtube", + "x": [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2], + "y": [0, 0, 0, 1, 1, 1, 2, 2, 2, 0, 0, 0, 1, 1, 1, 2, 2, 2, 0, 0, 0, 1, 1, 1, 2, 2, 2], + "z": [0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2], + "u": [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1.8414709848078965, + 1.8414709848078965, + 1.8414709848078965, + 1.8414709848078965, + 1.8414709848078965, + 1.8414709848078965, + 1.8414709848078965, + 1.8414709848078965, + 1.8414709848078965, + 1.9092974268256817, + 1.9092974268256817, + 1.9092974268256817, + 1.9092974268256817, + 1.9092974268256817, + 1.9092974268256817, + 1.9092974268256817, + 1.9092974268256817, + 1.9092974268256817 + ], + "v": [ + 1, + 1, + 1, + 0.5403023058681398, + 0.5403023058681398, + 0.5403023058681398, + -0.4161468365471424, + -0.4161468365471424, + -0.4161468365471424, + 1, + 1, + 1, + 0.5403023058681398, + 0.5403023058681398, + 0.5403023058681398, + -0.4161468365471424, + -0.4161468365471424, + -0.4161468365471424, + 1, + 1, + 1, + 0.5403023058681398, + 0.5403023058681398, + 0.5403023058681398, + -0.4161468365471424, + -0.4161468365471424, + -0.4161468365471424 + ], + "w": [ + 0, + 0.08865606199840186, + 0.1693927420185106, + 0, + 0.08865606199840186, + 0.1693927420185106, + 0, + 0.08865606199840186, + 0.1693927420185106, + 0, + 0.08865606199840186, + 0.1693927420185106, + 0, + 0.08865606199840186, + 0.1693927420185106, + 0, + 0.08865606199840186, + 0.1693927420185106, + 0, + 0.08865606199840186, + 0.1693927420185106, + 0, + 0.08865606199840186, + 0.1693927420185106, + 0, + 0.08865606199840186, + 0.1693927420185106 + ], + "sizeref": 0.5, + "coloraxis": "coloraxis" + }, { + "type":"mesh3d", + "x":[0, 1, 2, 0], + "y":[0, 0, 1, 2], + "z":[0, 2, 0, 1], + "i":[0, 0, 0, 1], + "j":[1, 2, 3, 2], + "k":[2, 3, 1, 3], + "intensity": [0, 1, 2, 3], + "coloraxis": "coloraxis" + }, + + { + "type": "isosurface", + "value": [ + 0, 125, 250, 375, 500, 625, 750, 875, 1000, + -125, 0, 125, 250, 375, 500, 625, 750, 875, + -250, -125, 0, 125, 250, 375, 500, 625, 750, + -375, -250, -125, 0, 125, 250, 375, 500, 625, + -500, -375, -250, -125, 0, 125, 250, 375, 500, + -625, -500, -375, -250, -125, 0, 125, 250, 375, + -750, -625, -500, -375, -250, -125, 0, 125, 250, + -875, -750, -625, -500, -375, -250, -125, 0, 125, + -1000, -875, -750, -625, -500, -375, -250, -125, 0, + + -125, 0, 125, 250, 375, 500, 625, 750, 875, + -250, -121, 8, 137, 266, 395, 523, 652, 781, + -375, -242, -109, 23, 156, 289, 422, 555, 688, + -500, -363, -227, -90, 47, 184, 320, 457, 594, + -625, -484, -344, -203, -63, 78, 219, 359, 500, + -750, -605, -461, -316, -172, -27, 117, 262, 406, + -875, -727, -578, -430, -281, -133, 16, 164, 313, + -1000, -848, -695, -543, -391, -238, -86, 66, 219, + -1125, -969, -813, -656, -500, -344, -188, -31, 125, + + -250, -125, 0, 125, 250, 375, 500, 625, 750, + -375, -242, -109, 23, 156, 289, 422, 555, 688, + -500, -359, -219, -78, 63, 203, 344, 484, 625, + -625, -477, -328, -180, -31, 117, 266, 414, 563, + -750, -594, -438, -281, -125, 31, 188, 344, 500, + -875, -711, -547, -383, -219, -55, 109, 273, 438, + -1000, -828, -656, -484, -313, -141, 31, 203, 375, + -1125, -945, -766, -586, -406, -227, -47, 133, 313, + -1250, -1063, -875, -688, -500, -313, -125, 63, 250, + + -375, -250, -125, 0, 125, 250, 375, 500, 625, + -500, -363, -227, -90, 47, 184, 320, 457, 594, + -625, -477, -328, -180, -31, 117, 266, 414, 563, + -750, -590, -430, -270, -109, 51, 211, 371, 531, + -875, -703, -531, -359, -188, -16, 156, 328, 500, + -1000, -816, -633, -449, -266, -82, 102, 285, 469, + -1125, -930, -734, -539, -344, -148, 47, 242, 438, + -1250, -1043, -836, -629, -422, -215, -8, 199, 406, + -1375, -1156, -938, -719, -500, -281, -63, 156, 375, + + -500, -375, -250, -125, 0, 125, 250, 375, 500, + -625, -484, -344, -203, -63, 78, 219, 359, 500, + -750, -594, -438, -281, -125, 31, 188, 344, 500, + -875, -703, -531, -359, -188, -16, 156, 328, 500, + -1000, -813, -625, -438, -250, -63, 125, 313, 500, + -1125, -922, -719, -516, -313, -109, 94, 297, 500, + -1250, -1031, -813, -594, -375, -156, 63, 281, 500, + -1375, -1141, -906, -672, -438, -203, 31, 266, 500, + -1500, -1250, -1000, -750, -500, -250, 0, 250, 500, + + -625, -500, -375, -250, -125, 0, 125, 250, 375, + -750, -605, -461, -316, -172, -27, 117, 262, 406, + -875, -711, -547, -383, -219, -55, 109, 273, 438, + -1000, -816, -633, -449, -266, -82, 102, 285, 469, + -1125, -922, -719, -516, -313, -109, 94, 297, 500, + -1250, -1027, -805, -582, -359, -137, 86, 309, 531, + -1375, -1133, -891, -648, -406, -164, 78, 320, 563, + -1500, -1238, -977, -715, -453, -191, 70, 332, 594, + -1625, -1344, -1063, -781, -500, -219, 63, 344, 625, + + -750, -625, -500, -375, -250, -125, 0, 125, 250, + -875, -727, -578, -430, -281, -133, 16, 164, 313, + -1000, -828, -656, -484, -313, -141, 31, 203, 375, + -1125, -930, -734, -539, -344, -148, 47, 242, 438, + -1250, -1031, -813, -594, -375, -156, 63, 281, 500, + -1375, -1133, -891, -648, -406, -164, 78, 320, 563, + -1500, -1234, -969, -703, -438, -172, 94, 359, 625, + -1625, -1336, -1047, -758, -469, -180, 109, 398, 688, + -1750, -1438, -1125, -813, -500, -188, 125, 438, 750, + + -875, -750, -625, -500, -375, -250, -125, 0, 125, + -1000, -848, -695, -543, -391, -238, -86, 66, 219, + -1125, -945, -766, -586, -406, -227, -47, 133, 313, + -1250, -1043, -836, -629, -422, -215, -8, 199, 406, + -1375, -1141, -906, -672, -438, -203, 31, 266, 500, + -1500, -1238, -977, -715, -453, -191, 70, 332, 594, + -1625, -1336, -1047, -758, -469, -180, 109, 398, 688, + -1750, -1434, -1117, -801, -484, -168, 148, 465, 781, + -1875, -1531, -1188, -844, -500, -156, 188, 531, 875, + + -1000, -875, -750, -625, -500, -375, -250, -125, 0, + -1125, -969, -813, -656, -500, -344, -188, -31, 125, + -1250, -1063, -875, -688, -500, -313, -125, 63, 250, + -1375, -1156, -938, -719, -500, -281, -63, 156, 375, + -1500, -1250, -1000, -750, -500, -250, 0, 250, 500, + -1625, -1344, -1063, -781, -500, -219, 63, 344, 625, + -1750, -1438, -1125, -813, -500, -188, 125, 438, 750, + -1875, -1531, -1188, -844, -500, -156, 188, 531, 875, + -2000, -1625, -1250, -875, -500, -125, 250, 625, 1000 + ], + "x": [ + 2.000, 2.000, 2.000, 2.000, 2.000, 2.000, 2.000, 2.000, 2.000, + 2.000, 2.000, 2.000, 2.000, 2.000, 2.000, 2.000, 2.000, 2.000, + 2.000, 2.000, 2.000, 2.000, 2.000, 2.000, 2.000, 2.000, 2.000, + 2.000, 2.000, 2.000, 2.000, 2.000, 2.000, 2.000, 2.000, 2.000, + 2.000, 2.000, 2.000, 2.000, 2.000, 2.000, 2.000, 2.000, 2.000, + 2.000, 2.000, 2.000, 2.000, 2.000, 2.000, 2.000, 2.000, 2.000, + 2.000, 2.000, 2.000, 2.000, 2.000, 2.000, 2.000, 2.000, 2.000, + 2.000, 2.000, 2.000, 2.000, 2.000, 2.000, 2.000, 2.000, 2.000, + 2.000, 2.000, 2.000, 2.000, 2.000, 2.000, 2.000, 2.000, 2.000, + + 1.875, 1.875, 1.875, 1.875, 1.875, 1.875, 1.875, 1.875, 1.875, + 1.875, 1.875, 1.875, 1.875, 1.875, 1.875, 1.875, 1.875, 1.875, + 1.875, 1.875, 1.875, 1.875, 1.875, 1.875, 1.875, 1.875, 1.875, + 1.875, 1.875, 1.875, 1.875, 1.875, 1.875, 1.875, 1.875, 1.875, + 1.875, 1.875, 1.875, 1.875, 1.875, 1.875, 1.875, 1.875, 1.875, + 1.875, 1.875, 1.875, 1.875, 1.875, 1.875, 1.875, 1.875, 1.875, + 1.875, 1.875, 1.875, 1.875, 1.875, 1.875, 1.875, 1.875, 1.875, + 1.875, 1.875, 1.875, 1.875, 1.875, 1.875, 1.875, 1.875, 1.875, + 1.875, 1.875, 1.875, 1.875, 1.875, 1.875, 1.875, 1.875, 1.875, + + 1.750, 1.750, 1.750, 1.750, 1.750, 1.750, 1.750, 1.750, 1.750, + 1.750, 1.750, 1.750, 1.750, 1.750, 1.750, 1.750, 1.750, 1.750, + 1.750, 1.750, 1.750, 1.750, 1.750, 1.750, 1.750, 1.750, 1.750, + 1.750, 1.750, 1.750, 1.750, 1.750, 1.750, 1.750, 1.750, 1.750, + 1.750, 1.750, 1.750, 1.750, 1.750, 1.750, 1.750, 1.750, 1.750, + 1.750, 1.750, 1.750, 1.750, 1.750, 1.750, 1.750, 1.750, 1.750, + 1.750, 1.750, 1.750, 1.750, 1.750, 1.750, 1.750, 1.750, 1.750, + 1.750, 1.750, 1.750, 1.750, 1.750, 1.750, 1.750, 1.750, 1.750, + 1.750, 1.750, 1.750, 1.750, 1.750, 1.750, 1.750, 1.750, 1.750, + + 1.625, 1.625, 1.625, 1.625, 1.625, 1.625, 1.625, 1.625, 1.625, + 1.625, 1.625, 1.625, 1.625, 1.625, 1.625, 1.625, 1.625, 1.625, + 1.625, 1.625, 1.625, 1.625, 1.625, 1.625, 1.625, 1.625, 1.625, + 1.625, 1.625, 1.625, 1.625, 1.625, 1.625, 1.625, 1.625, 1.625, + 1.625, 1.625, 1.625, 1.625, 1.625, 1.625, 1.625, 1.625, 1.625, + 1.625, 1.625, 1.625, 1.625, 1.625, 1.625, 1.625, 1.625, 1.625, + 1.625, 1.625, 1.625, 1.625, 1.625, 1.625, 1.625, 1.625, 1.625, + 1.625, 1.625, 1.625, 1.625, 1.625, 1.625, 1.625, 1.625, 1.625, + 1.625, 1.625, 1.625, 1.625, 1.625, 1.625, 1.625, 1.625, 1.625, + + 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, + 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, + 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, + 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, + 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, + 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, + 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, + 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, + 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, + + 1.375, 1.375, 1.375, 1.375, 1.375, 1.375, 1.375, 1.375, 1.375, + 1.375, 1.375, 1.375, 1.375, 1.375, 1.375, 1.375, 1.375, 1.375, + 1.375, 1.375, 1.375, 1.375, 1.375, 1.375, 1.375, 1.375, 1.375, + 1.375, 1.375, 1.375, 1.375, 1.375, 1.375, 1.375, 1.375, 1.375, + 1.375, 1.375, 1.375, 1.375, 1.375, 1.375, 1.375, 1.375, 1.375, + 1.375, 1.375, 1.375, 1.375, 1.375, 1.375, 1.375, 1.375, 1.375, + 1.375, 1.375, 1.375, 1.375, 1.375, 1.375, 1.375, 1.375, 1.375, + 1.375, 1.375, 1.375, 1.375, 1.375, 1.375, 1.375, 1.375, 1.375, + 1.375, 1.375, 1.375, 1.375, 1.375, 1.375, 1.375, 1.375, 1.375, + + 1.250, 1.250, 1.250, 1.250, 1.250, 1.250, 1.250, 1.250, 1.250, + 1.250, 1.250, 1.250, 1.250, 1.250, 1.250, 1.250, 1.250, 1.250, + 1.250, 1.250, 1.250, 1.250, 1.250, 1.250, 1.250, 1.250, 1.250, + 1.250, 1.250, 1.250, 1.250, 1.250, 1.250, 1.250, 1.250, 1.250, + 1.250, 1.250, 1.250, 1.250, 1.250, 1.250, 1.250, 1.250, 1.250, + 1.250, 1.250, 1.250, 1.250, 1.250, 1.250, 1.250, 1.250, 1.250, + 1.250, 1.250, 1.250, 1.250, 1.250, 1.250, 1.250, 1.250, 1.250, + 1.250, 1.250, 1.250, 1.250, 1.250, 1.250, 1.250, 1.250, 1.250, + 1.250, 1.250, 1.250, 1.250, 1.250, 1.250, 1.250, 1.250, 1.250, + + 1.125, 1.125, 1.125, 1.125, 1.125, 1.125, 1.125, 1.125, 1.125, + 1.125, 1.125, 1.125, 1.125, 1.125, 1.125, 1.125, 1.125, 1.125, + 1.125, 1.125, 1.125, 1.125, 1.125, 1.125, 1.125, 1.125, 1.125, + 1.125, 1.125, 1.125, 1.125, 1.125, 1.125, 1.125, 1.125, 1.125, + 1.125, 1.125, 1.125, 1.125, 1.125, 1.125, 1.125, 1.125, 1.125, + 1.125, 1.125, 1.125, 1.125, 1.125, 1.125, 1.125, 1.125, 1.125, + 1.125, 1.125, 1.125, 1.125, 1.125, 1.125, 1.125, 1.125, 1.125, + 1.125, 1.125, 1.125, 1.125, 1.125, 1.125, 1.125, 1.125, 1.125, + 1.125, 1.125, 1.125, 1.125, 1.125, 1.125, 1.125, 1.125, 1.125, + + 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, + 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, + 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, + 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, + 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, + 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, + 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, + 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, + 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000 + ], + "y": [ + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, + 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, + 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, + 0.375, 0.375, 0.375, 0.375, 0.375, 0.375, 0.375, 0.375, 0.375, + 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, + 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, + 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, + 0.875, 0.875, 0.875, 0.875, 0.875, 0.875, 0.875, 0.875, 0.875, + 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, + + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, + 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, + 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, + 0.375, 0.375, 0.375, 0.375, 0.375, 0.375, 0.375, 0.375, 0.375, + 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, + 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, + 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, + 0.875, 0.875, 0.875, 0.875, 0.875, 0.875, 0.875, 0.875, 0.875, + 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, + + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, + 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, + 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, + 0.375, 0.375, 0.375, 0.375, 0.375, 0.375, 0.375, 0.375, 0.375, + 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, + 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, + 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, + 0.875, 0.875, 0.875, 0.875, 0.875, 0.875, 0.875, 0.875, 0.875, + 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, + + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, + 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, + 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, + 0.375, 0.375, 0.375, 0.375, 0.375, 0.375, 0.375, 0.375, 0.375, + 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, + 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, + 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, + 0.875, 0.875, 0.875, 0.875, 0.875, 0.875, 0.875, 0.875, 0.875, + 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, + + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, + 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, + 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, + 0.375, 0.375, 0.375, 0.375, 0.375, 0.375, 0.375, 0.375, 0.375, + 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, + 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, + 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, + 0.875, 0.875, 0.875, 0.875, 0.875, 0.875, 0.875, 0.875, 0.875, + 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, + + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, + 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, + 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, + 0.375, 0.375, 0.375, 0.375, 0.375, 0.375, 0.375, 0.375, 0.375, + 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, + 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, + 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, + 0.875, 0.875, 0.875, 0.875, 0.875, 0.875, 0.875, 0.875, 0.875, + 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, + + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, + 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, + 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, + 0.375, 0.375, 0.375, 0.375, 0.375, 0.375, 0.375, 0.375, 0.375, + 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, + 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, + 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, + 0.875, 0.875, 0.875, 0.875, 0.875, 0.875, 0.875, 0.875, 0.875, + 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, + + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, + 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, + 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, + 0.375, 0.375, 0.375, 0.375, 0.375, 0.375, 0.375, 0.375, 0.375, + 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, + 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, + 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, + 0.875, 0.875, 0.875, 0.875, 0.875, 0.875, 0.875, 0.875, 0.875, + 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, + + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, + 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, + 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, + 0.375, 0.375, 0.375, 0.375, 0.375, 0.375, 0.375, 0.375, 0.375, + 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, + 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, 0.625, + 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, + 0.875, 0.875, 0.875, 0.875, 0.875, 0.875, 0.875, 0.875, 0.875, + 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000 + ], + "z": [ + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000, + 0.000, 0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875, 1.000 + ], + + "scene": "scene2", + "coloraxis": "coloraxis2" + }, { + "type": "volume", + "value": [ + 1000.000, 866.025, 500.000, 0.000, -500.000, -866.025, -1000.000, -866.025, -500.000, -0.000, 500.000, 866.025, 1000.000, + 1500.000, 1366.025, 1000.000, 500.000, 0.000, -366.025, -500.000, -366.025, -0.000, 500.000, 1000.000, 1366.025, 1500.000, + 1866.025, 1732.051, 1366.025, 866.025, 366.025, -0.000, -133.975, 0.000, 366.025, 866.025, 1366.025, 1732.051, 1866.025, + 2000.000, 1866.025, 1500.000, 1000.000, 500.000, 133.975, 0.000, 133.975, 500.000, 1000.000, 1500.000, 1866.025, 2000.000, + 1866.025, 1732.051, 1366.025, 866.025, 366.025, 0.000, -133.975, 0.000, 366.025, 866.025, 1366.025, 1732.051, 1866.025, + 1500.000, 1366.025, 1000.000, 500.000, 0.000, -366.025, -500.000, -366.025, -0.000, 500.000, 1000.000, 1366.025, 1500.000, + 1000.000, 866.025, 500.000, 0.000, -500.000, -866.025, -1000.000, -866.025, -500.000, -0.000, 500.000, 866.025, 1000.000, + 500.000, 366.025, 0.000, -500.000, -1000.000, -1366.025, -1500.000, -1366.025, -1000.000, -500.000, 0.000, 366.025, 500.000, + 133.975, 0.000, -366.025, -866.025, -1366.025, -1732.051, -1866.025, -1732.051, -1366.025, -866.025, -366.025, -0.000, 133.975, + 0.000, -133.975, -500.000, -1000.000, -1500.000, -1866.025, -2000.000, -1866.025, -1500.000, -1000.000, -500.000, -133.975, 0.000, + 133.975, 0.000, -366.025, -866.025, -1366.025, -1732.051, -1866.025, -1732.051, -1366.025, -866.025, -366.025, -0.000, 133.975, + 500.000, 366.025, -0.000, -500.000, -1000.000, -1366.025, -1500.000, -1366.025, -1000.000, -500.000, -0.000, 366.025, 500.000, + 1000.000, 866.025, 500.000, -0.000, -500.000, -866.025, -1000.000, -866.025, -500.000, -0.000, 500.000, 866.025, 1000.000, + + 1500.000, 1366.025, 1000.000, 500.000, 0.000, -366.025, -500.000, -366.025, -0.000, 500.000, 1000.000, 1366.025, 1500.000, + 2000.000, 1866.025, 1500.000, 1000.000, 500.000, 133.975, -0.000, 133.975, 500.000, 1000.000, 1500.000, 1866.025, 2000.000, + 2366.025, 2232.051, 1866.025, 1366.025, 866.025, 500.000, 366.025, 500.000, 866.025, 1366.025, 1866.025, 2232.051, 2366.025, + 2500.000, 2366.025, 2000.000, 1500.000, 1000.000, 633.975, 500.000, 633.975, 1000.000, 1500.000, 2000.000, 2366.025, 2500.000, + 2366.025, 2232.051, 1866.025, 1366.025, 866.025, 500.000, 366.025, 500.000, 866.025, 1366.025, 1866.025, 2232.051, 2366.025, + 2000.000, 1866.025, 1500.000, 1000.000, 500.000, 133.975, -0.000, 133.975, 500.000, 1000.000, 1500.000, 1866.025, 2000.000, + 1500.000, 1366.025, 1000.000, 500.000, 0.000, -366.025, -500.000, -366.025, -0.000, 500.000, 1000.000, 1366.025, 1500.000, + 1000.000, 866.025, 500.000, -0.000, -500.000, -866.025, -1000.000, -866.025, -500.000, -0.000, 500.000, 866.025, 1000.000, + 633.975, 500.000, 133.975, -366.025, -866.025, -1232.051, -1366.025, -1232.051, -866.025, -366.025, 133.975, 500.000, 633.975, + 500.000, 366.025, 0.000, -500.000, -1000.000, -1366.025, -1500.000, -1366.025, -1000.000, -500.000, 0.000, 366.025, 500.000, + 633.975, 500.000, 133.975, -366.025, -866.025, -1232.051, -1366.025, -1232.051, -866.025, -366.025, 133.975, 500.000, 633.975, + 1000.000, 866.025, 500.000, -0.000, -500.000, -866.025, -1000.000, -866.025, -500.000, -0.000, 500.000, 866.025, 1000.000, + 1500.000, 1366.025, 1000.000, 500.000, -0.000, -366.025, -500.000, -366.025, -0.000, 500.000, 1000.000, 1366.025, 1500.000, + + 1866.025, 1732.051, 1366.025, 866.025, 366.025, -0.000, -133.975, 0.000, 366.025, 866.025, 1366.025, 1732.051, 1866.025, + 2366.025, 2232.051, 1866.025, 1366.025, 866.025, 500.000, 366.025, 500.000, 866.025, 1366.025, 1866.025, 2232.051, 2366.025, + 2732.051, 2598.076, 2232.051, 1732.051, 1232.051, 866.025, 732.051, 866.025, 1232.051, 1732.051, 2232.051, 2598.076, 2732.051, + 2866.025, 2732.051, 2366.025, 1866.025, 1366.025, 1000.000, 866.025, 1000.000, 1366.025, 1866.025, 2366.025, 2732.051, 2866.025, + 2732.051, 2598.076, 2232.051, 1732.051, 1232.051, 866.025, 732.051, 866.025, 1232.051, 1732.051, 2232.051, 2598.076, 2732.051, + 2366.025, 2232.051, 1866.025, 1366.025, 866.025, 500.000, 366.025, 500.000, 866.025, 1366.025, 1866.025, 2232.051, 2366.025, + 1866.025, 1732.051, 1366.025, 866.025, 366.025, 0.000, -133.975, 0.000, 366.025, 866.025, 1366.025, 1732.051, 1866.025, + 1366.025, 1232.051, 866.025, 366.025, -133.975, -500.000, -633.975, -500.000, -133.975, 366.025, 866.025, 1232.051, 1366.025, + 1000.000, 866.025, 500.000, 0.000, -500.000, -866.025, -1000.000, -866.025, -500.000, -0.000, 500.000, 866.025, 1000.000, + 866.025, 732.051, 366.025, -133.975, -633.975, -1000.000, -1133.975, -1000.000, -633.975, -133.975, 366.025, 732.051, 866.025, + 1000.000, 866.025, 500.000, 0.000, -500.000, -866.025, -1000.000, -866.025, -500.000, -0.000, 500.000, 866.025, 1000.000, + 1366.025, 1232.051, 866.025, 366.025, -133.975, -500.000, -633.975, -500.000, -133.975, 366.025, 866.025, 1232.051, 1366.025, + 1866.025, 1732.051, 1366.025, 866.025, 366.025, -0.000, -133.975, -0.000, 366.025, 866.025, 1366.025, 1732.051, 1866.025, + + 2000.000, 1866.025, 1500.000, 1000.000, 500.000, 133.975, 0.000, 133.975, 500.000, 1000.000, 1500.000, 1866.025, 2000.000, + 2500.000, 2366.025, 2000.000, 1500.000, 1000.000, 633.975, 500.000, 633.975, 1000.000, 1500.000, 2000.000, 2366.025, 2500.000, + 2866.025, 2732.051, 2366.025, 1866.025, 1366.025, 1000.000, 866.025, 1000.000, 1366.025, 1866.025, 2366.025, 2732.051, 2866.025, + 3000.000, 2866.025, 2500.000, 2000.000, 1500.000, 1133.975, 1000.000, 1133.975, 1500.000, 2000.000, 2500.000, 2866.025, 3000.000, + 2866.025, 2732.051, 2366.025, 1866.025, 1366.025, 1000.000, 866.025, 1000.000, 1366.025, 1866.025, 2366.025, 2732.051, 2866.025, + 2500.000, 2366.025, 2000.000, 1500.000, 1000.000, 633.975, 500.000, 633.975, 1000.000, 1500.000, 2000.000, 2366.025, 2500.000, + 2000.000, 1866.025, 1500.000, 1000.000, 500.000, 133.975, 0.000, 133.975, 500.000, 1000.000, 1500.000, 1866.025, 2000.000, + 1500.000, 1366.025, 1000.000, 500.000, 0.000, -366.025, -500.000, -366.025, -0.000, 500.000, 1000.000, 1366.025, 1500.000, + 1133.975, 1000.000, 633.975, 133.975, -366.025, -732.051, -866.025, -732.051, -366.025, 133.975, 633.975, 1000.000, 1133.975, + 1000.000, 866.025, 500.000, 0.000, -500.000, -866.025, -1000.000, -866.025, -500.000, -0.000, 500.000, 866.025, 1000.000, + 1133.975, 1000.000, 633.975, 133.975, -366.025, -732.051, -866.025, -732.051, -366.025, 133.975, 633.975, 1000.000, 1133.975, + 1500.000, 1366.025, 1000.000, 500.000, -0.000, -366.025, -500.000, -366.025, -0.000, 500.000, 1000.000, 1366.025, 1500.000, + 2000.000, 1866.025, 1500.000, 1000.000, 500.000, 133.975, -0.000, 133.975, 500.000, 1000.000, 1500.000, 1866.025, 2000.000, + + 1866.025, 1732.051, 1366.025, 866.025, 366.025, 0.000, -133.975, 0.000, 366.025, 866.025, 1366.025, 1732.051, 1866.025, + 2366.025, 2232.051, 1866.025, 1366.025, 866.025, 500.000, 366.025, 500.000, 866.025, 1366.025, 1866.025, 2232.051, 2366.025, + 2732.051, 2598.076, 2232.051, 1732.051, 1232.051, 866.025, 732.051, 866.025, 1232.051, 1732.051, 2232.051, 2598.076, 2732.051, + 2866.025, 2732.051, 2366.025, 1866.025, 1366.025, 1000.000, 866.025, 1000.000, 1366.025, 1866.025, 2366.025, 2732.051, 2866.025, + 2732.051, 2598.076, 2232.051, 1732.051, 1232.051, 866.025, 732.051, 866.025, 1232.051, 1732.051, 2232.051, 2598.076, 2732.051, + 2366.025, 2232.051, 1866.025, 1366.025, 866.025, 500.000, 366.025, 500.000, 866.025, 1366.025, 1866.025, 2232.051, 2366.025, + 1866.025, 1732.051, 1366.025, 866.025, 366.025, 0.000, -133.975, 0.000, 366.025, 866.025, 1366.025, 1732.051, 1866.025, + 1366.025, 1232.051, 866.025, 366.025, -133.975, -500.000, -633.975, -500.000, -133.975, 366.025, 866.025, 1232.051, 1366.025, + 1000.000, 866.025, 500.000, 0.000, -500.000, -866.025, -1000.000, -866.025, -500.000, 0.000, 500.000, 866.025, 1000.000, + 866.025, 732.051, 366.025, -133.975, -633.975, -1000.000, -1133.975, -1000.000, -633.975, -133.975, 366.025, 732.051, 866.025, + 1000.000, 866.025, 500.000, 0.000, -500.000, -866.025, -1000.000, -866.025, -500.000, -0.000, 500.000, 866.025, 1000.000, + 1366.025, 1232.051, 866.025, 366.025, -133.975, -500.000, -633.975, -500.000, -133.975, 366.025, 866.025, 1232.051, 1366.025, + 1866.025, 1732.051, 1366.025, 866.025, 366.025, -0.000, -133.975, -0.000, 366.025, 866.025, 1366.025, 1732.051, 1866.025, + + 1500.000, 1366.025, 1000.000, 500.000, 0.000, -366.025, -500.000, -366.025, -0.000, 500.000, 1000.000, 1366.025, 1500.000, + 2000.000, 1866.025, 1500.000, 1000.000, 500.000, 133.975, -0.000, 133.975, 500.000, 1000.000, 1500.000, 1866.025, 2000.000, + 2366.025, 2232.051, 1866.025, 1366.025, 866.025, 500.000, 366.025, 500.000, 866.025, 1366.025, 1866.025, 2232.051, 2366.025, + 2500.000, 2366.025, 2000.000, 1500.000, 1000.000, 633.975, 500.000, 633.975, 1000.000, 1500.000, 2000.000, 2366.025, 2500.000, + 2366.025, 2232.051, 1866.025, 1366.025, 866.025, 500.000, 366.025, 500.000, 866.025, 1366.025, 1866.025, 2232.051, 2366.025, + 2000.000, 1866.025, 1500.000, 1000.000, 500.000, 133.975, -0.000, 133.975, 500.000, 1000.000, 1500.000, 1866.025, 2000.000, + 1500.000, 1366.025, 1000.000, 500.000, 0.000, -366.025, -500.000, -366.025, -0.000, 500.000, 1000.000, 1366.025, 1500.000, + 1000.000, 866.025, 500.000, -0.000, -500.000, -866.025, -1000.000, -866.025, -500.000, -0.000, 500.000, 866.025, 1000.000, + 633.975, 500.000, 133.975, -366.025, -866.025, -1232.051, -1366.025, -1232.051, -866.025, -366.025, 133.975, 500.000, 633.975, + 500.000, 366.025, 0.000, -500.000, -1000.000, -1366.025, -1500.000, -1366.025, -1000.000, -500.000, 0.000, 366.025, 500.000, + 633.975, 500.000, 133.975, -366.025, -866.025, -1232.051, -1366.025, -1232.051, -866.025, -366.025, 133.975, 500.000, 633.975, + 1000.000, 866.025, 500.000, -0.000, -500.000, -866.025, -1000.000, -866.025, -500.000, -0.000, 500.000, 866.025, 1000.000, + 1500.000, 1366.025, 1000.000, 500.000, -0.000, -366.025, -500.000, -366.025, -0.000, 500.000, 1000.000, 1366.025, 1500.000, + + 1000.000, 866.025, 500.000, 0.000, -500.000, -866.025, -1000.000, -866.025, -500.000, -0.000, 500.000, 866.025, 1000.000, + 1500.000, 1366.025, 1000.000, 500.000, 0.000, -366.025, -500.000, -366.025, -0.000, 500.000, 1000.000, 1366.025, 1500.000, + 1866.025, 1732.051, 1366.025, 866.025, 366.025, 0.000, -133.975, 0.000, 366.025, 866.025, 1366.025, 1732.051, 1866.025, + 2000.000, 1866.025, 1500.000, 1000.000, 500.000, 133.975, 0.000, 133.975, 500.000, 1000.000, 1500.000, 1866.025, 2000.000, + 1866.025, 1732.051, 1366.025, 866.025, 366.025, 0.000, -133.975, 0.000, 366.025, 866.025, 1366.025, 1732.051, 1866.025, + 1500.000, 1366.025, 1000.000, 500.000, 0.000, -366.025, -500.000, -366.025, -0.000, 500.000, 1000.000, 1366.025, 1500.000, + 1000.000, 866.025, 500.000, 0.000, -500.000, -866.025, -1000.000, -866.025, -500.000, 0.000, 500.000, 866.025, 1000.000, + 500.000, 366.025, 0.000, -500.000, -1000.000, -1366.025, -1500.000, -1366.025, -1000.000, -500.000, 0.000, 366.025, 500.000, + 133.975, 0.000, -366.025, -866.025, -1366.025, -1732.051, -1866.025, -1732.051, -1366.025, -866.025, -366.025, 0.000, 133.975, + 0.000, -133.975, -500.000, -1000.000, -1500.000, -1866.025, -2000.000, -1866.025, -1500.000, -1000.000, -500.000, -133.975, 0.000, + 133.975, 0.000, -366.025, -866.025, -1366.025, -1732.051, -1866.025, -1732.051, -1366.025, -866.025, -366.025, -0.000, 133.975, + 500.000, 366.025, -0.000, -500.000, -1000.000, -1366.025, -1500.000, -1366.025, -1000.000, -500.000, -0.000, 366.025, 500.000, + 1000.000, 866.025, 500.000, -0.000, -500.000, -866.025, -1000.000, -866.025, -500.000, -0.000, 500.000, 866.025, 1000.000, + + 500.000, 366.025, 0.000, -500.000, -1000.000, -1366.025, -1500.000, -1366.025, -1000.000, -500.000, 0.000, 366.025, 500.000, + 1000.000, 866.025, 500.000, -0.000, -500.000, -866.025, -1000.000, -866.025, -500.000, -0.000, 500.000, 866.025, 1000.000, + 1366.025, 1232.051, 866.025, 366.025, -133.975, -500.000, -633.975, -500.000, -133.975, 366.025, 866.025, 1232.051, 1366.025, + 1500.000, 1366.025, 1000.000, 500.000, 0.000, -366.025, -500.000, -366.025, -0.000, 500.000, 1000.000, 1366.025, 1500.000, + 1366.025, 1232.051, 866.025, 366.025, -133.975, -500.000, -633.975, -500.000, -133.975, 366.025, 866.025, 1232.051, 1366.025, + 1000.000, 866.025, 500.000, -0.000, -500.000, -866.025, -1000.000, -866.025, -500.000, -0.000, 500.000, 866.025, 1000.000, + 500.000, 366.025, 0.000, -500.000, -1000.000, -1366.025, -1500.000, -1366.025, -1000.000, -500.000, 0.000, 366.025, 500.000, + -0.000, -133.975, -500.000, -1000.000, -1500.000, -1866.025, -2000.000, -1866.025, -1500.000, -1000.000, -500.000, -133.975, -0.000, + -366.025, -500.000, -866.025, -1366.025, -1866.025, -2232.051, -2366.025, -2232.051, -1866.025, -1366.025, -866.025, -500.000, -366.025, + -500.000, -633.975, -1000.000, -1500.000, -2000.000, -2366.025, -2500.000, -2366.025, -2000.000, -1500.000, -1000.000, -633.975, -500.000, + -366.025, -500.000, -866.025, -1366.025, -1866.025, -2232.051, -2366.025, -2232.051, -1866.025, -1366.025, -866.025, -500.000, -366.025, + -0.000, -133.975, -500.000, -1000.000, -1500.000, -1866.025, -2000.000, -1866.025, -1500.000, -1000.000, -500.000, -133.975, -0.000, + 500.000, 366.025, -0.000, -500.000, -1000.000, -1366.025, -1500.000, -1366.025, -1000.000, -500.000, -0.000, 366.025, 500.000, + + 133.975, 0.000, -366.025, -866.025, -1366.025, -1732.051, -1866.025, -1732.051, -1366.025, -866.025, -366.025, -0.000, 133.975, + 633.975, 500.000, 133.975, -366.025, -866.025, -1232.051, -1366.025, -1232.051, -866.025, -366.025, 133.975, 500.000, 633.975, + 1000.000, 866.025, 500.000, 0.000, -500.000, -866.025, -1000.000, -866.025, -500.000, -0.000, 500.000, 866.025, 1000.000, + 1133.975, 1000.000, 633.975, 133.975, -366.025, -732.051, -866.025, -732.051, -366.025, 133.975, 633.975, 1000.000, 1133.975, + 1000.000, 866.025, 500.000, 0.000, -500.000, -866.025, -1000.000, -866.025, -500.000, 0.000, 500.000, 866.025, 1000.000, + 633.975, 500.000, 133.975, -366.025, -866.025, -1232.051, -1366.025, -1232.051, -866.025, -366.025, 133.975, 500.000, 633.975, + 133.975, 0.000, -366.025, -866.025, -1366.025, -1732.051, -1866.025, -1732.051, -1366.025, -866.025, -366.025, 0.000, 133.975, + -366.025, -500.000, -866.025, -1366.025, -1866.025, -2232.051, -2366.025, -2232.051, -1866.025, -1366.025, -866.025, -500.000, -366.025, + -732.051, -866.025, -1232.051, -1732.051, -2232.051, -2598.076, -2732.051, -2598.076, -2232.051, -1732.051, -1232.051, -866.025, -732.051, + -866.025, -1000.000, -1366.025, -1866.025, -2366.025, -2732.051, -2866.025, -2732.051, -2366.025, -1866.025, -1366.025, -1000.000, -866.025, + -732.051, -866.025, -1232.051, -1732.051, -2232.051, -2598.076, -2732.051, -2598.076, -2232.051, -1732.051, -1232.051, -866.025, -732.051, + -366.025, -500.000, -866.025, -1366.025, -1866.025, -2232.051, -2366.025, -2232.051, -1866.025, -1366.025, -866.025, -500.000, -366.025, + 133.975, 0.000, -366.025, -866.025, -1366.025, -1732.051, -1866.025, -1732.051, -1366.025, -866.025, -366.025, -0.000, 133.975, + + 0.000, -133.975, -500.000, -1000.000, -1500.000, -1866.025, -2000.000, -1866.025, -1500.000, -1000.000, -500.000, -133.975, 0.000, + 500.000, 366.025, 0.000, -500.000, -1000.000, -1366.025, -1500.000, -1366.025, -1000.000, -500.000, 0.000, 366.025, 500.000, + 866.025, 732.051, 366.025, -133.975, -633.975, -1000.000, -1133.975, -1000.000, -633.975, -133.975, 366.025, 732.051, 866.025, + 1000.000, 866.025, 500.000, 0.000, -500.000, -866.025, -1000.000, -866.025, -500.000, -0.000, 500.000, 866.025, 1000.000, + 866.025, 732.051, 366.025, -133.975, -633.975, -1000.000, -1133.975, -1000.000, -633.975, -133.975, 366.025, 732.051, 866.025, + 500.000, 366.025, 0.000, -500.000, -1000.000, -1366.025, -1500.000, -1366.025, -1000.000, -500.000, 0.000, 366.025, 500.000, + 0.000, -133.975, -500.000, -1000.000, -1500.000, -1866.025, -2000.000, -1866.025, -1500.000, -1000.000, -500.000, -133.975, 0.000, + -500.000, -633.975, -1000.000, -1500.000, -2000.000, -2366.025, -2500.000, -2366.025, -2000.000, -1500.000, -1000.000, -633.975, -500.000, + -866.025, -1000.000, -1366.025, -1866.025, -2366.025, -2732.051, -2866.025, -2732.051, -2366.025, -1866.025, -1366.025, -1000.000, -866.025, + -1000.000, -1133.975, -1500.000, -2000.000, -2500.000, -2866.025, -3000.000, -2866.025, -2500.000, -2000.000, -1500.000, -1133.975, -1000.000, + -866.025, -1000.000, -1366.025, -1866.025, -2366.025, -2732.051, -2866.025, -2732.051, -2366.025, -1866.025, -1366.025, -1000.000, -866.025, + -500.000, -633.975, -1000.000, -1500.000, -2000.000, -2366.025, -2500.000, -2366.025, -2000.000, -1500.000, -1000.000, -633.975, -500.000, + -0.000, -133.975, -500.000, -1000.000, -1500.000, -1866.025, -2000.000, -1866.025, -1500.000, -1000.000, -500.000, -133.975, -0.000, + + 133.975, 0.000, -366.025, -866.025, -1366.025, -1732.051, -1866.025, -1732.051, -1366.025, -866.025, -366.025, -0.000, 133.975, + 633.975, 500.000, 133.975, -366.025, -866.025, -1232.051, -1366.025, -1232.051, -866.025, -366.025, 133.975, 500.000, 633.975, + 1000.000, 866.025, 500.000, 0.000, -500.000, -866.025, -1000.000, -866.025, -500.000, -0.000, 500.000, 866.025, 1000.000, + 1133.975, 1000.000, 633.975, 133.975, -366.025, -732.051, -866.025, -732.051, -366.025, 133.975, 633.975, 1000.000, 1133.975, + 1000.000, 866.025, 500.000, 0.000, -500.000, -866.025, -1000.000, -866.025, -500.000, -0.000, 500.000, 866.025, 1000.000, + 633.975, 500.000, 133.975, -366.025, -866.025, -1232.051, -1366.025, -1232.051, -866.025, -366.025, 133.975, 500.000, 633.975, + 133.975, 0.000, -366.025, -866.025, -1366.025, -1732.051, -1866.025, -1732.051, -1366.025, -866.025, -366.025, -0.000, 133.975, + -366.025, -500.000, -866.025, -1366.025, -1866.025, -2232.051, -2366.025, -2232.051, -1866.025, -1366.025, -866.025, -500.000, -366.025, + -732.051, -866.025, -1232.051, -1732.051, -2232.051, -2598.076, -2732.051, -2598.076, -2232.051, -1732.051, -1232.051, -866.025, -732.051, + -866.025, -1000.000, -1366.025, -1866.025, -2366.025, -2732.051, -2866.025, -2732.051, -2366.025, -1866.025, -1366.025, -1000.000, -866.025, + -732.051, -866.025, -1232.051, -1732.051, -2232.051, -2598.076, -2732.051, -2598.076, -2232.051, -1732.051, -1232.051, -866.025, -732.051, + -366.025, -500.000, -866.025, -1366.025, -1866.025, -2232.051, -2366.025, -2232.051, -1866.025, -1366.025, -866.025, -500.000, -366.025, + 133.975, -0.000, -366.025, -866.025, -1366.025, -1732.051, -1866.025, -1732.051, -1366.025, -866.025, -366.025, -0.000, 133.975, + + 500.000, 366.025, -0.000, -500.000, -1000.000, -1366.025, -1500.000, -1366.025, -1000.000, -500.000, -0.000, 366.025, 500.000, + 1000.000, 866.025, 500.000, -0.000, -500.000, -866.025, -1000.000, -866.025, -500.000, -0.000, 500.000, 866.025, 1000.000, + 1366.025, 1232.051, 866.025, 366.025, -133.975, -500.000, -633.975, -500.000, -133.975, 366.025, 866.025, 1232.051, 1366.025, + 1500.000, 1366.025, 1000.000, 500.000, -0.000, -366.025, -500.000, -366.025, -0.000, 500.000, 1000.000, 1366.025, 1500.000, + 1366.025, 1232.051, 866.025, 366.025, -133.975, -500.000, -633.975, -500.000, -133.975, 366.025, 866.025, 1232.051, 1366.025, + 1000.000, 866.025, 500.000, -0.000, -500.000, -866.025, -1000.000, -866.025, -500.000, -0.000, 500.000, 866.025, 1000.000, + 500.000, 366.025, -0.000, -500.000, -1000.000, -1366.025, -1500.000, -1366.025, -1000.000, -500.000, -0.000, 366.025, 500.000, + -0.000, -133.975, -500.000, -1000.000, -1500.000, -1866.025, -2000.000, -1866.025, -1500.000, -1000.000, -500.000, -133.975, -0.000, + -366.025, -500.000, -866.025, -1366.025, -1866.025, -2232.051, -2366.025, -2232.051, -1866.025, -1366.025, -866.025, -500.000, -366.025, + -500.000, -633.975, -1000.000, -1500.000, -2000.000, -2366.025, -2500.000, -2366.025, -2000.000, -1500.000, -1000.000, -633.975, -500.000, + -366.025, -500.000, -866.025, -1366.025, -1866.025, -2232.051, -2366.025, -2232.051, -1866.025, -1366.025, -866.025, -500.000, -366.025, + -0.000, -133.975, -500.000, -1000.000, -1500.000, -1866.025, -2000.000, -1866.025, -1500.000, -1000.000, -500.000, -133.975, -0.000, + 500.000, 366.025, -0.000, -500.000, -1000.000, -1366.025, -1500.000, -1366.025, -1000.000, -500.000, -0.000, 366.025, 500.000, + + 1000.000, 866.025, 500.000, -0.000, -500.000, -866.025, -1000.000, -866.025, -500.000, -0.000, 500.000, 866.025, 1000.000, + 1500.000, 1366.025, 1000.000, 500.000, -0.000, -366.025, -500.000, -366.025, -0.000, 500.000, 1000.000, 1366.025, 1500.000, + 1866.025, 1732.051, 1366.025, 866.025, 366.025, -0.000, -133.975, -0.000, 366.025, 866.025, 1366.025, 1732.051, 1866.025, + 2000.000, 1866.025, 1500.000, 1000.000, 500.000, 133.975, -0.000, 133.975, 500.000, 1000.000, 1500.000, 1866.025, 2000.000, + 1866.025, 1732.051, 1366.025, 866.025, 366.025, -0.000, -133.975, -0.000, 366.025, 866.025, 1366.025, 1732.051, 1866.025, + 1500.000, 1366.025, 1000.000, 500.000, -0.000, -366.025, -500.000, -366.025, -0.000, 500.000, 1000.000, 1366.025, 1500.000, + 1000.000, 866.025, 500.000, -0.000, -500.000, -866.025, -1000.000, -866.025, -500.000, -0.000, 500.000, 866.025, 1000.000, + 500.000, 366.025, -0.000, -500.000, -1000.000, -1366.025, -1500.000, -1366.025, -1000.000, -500.000, -0.000, 366.025, 500.000, + 133.975, 0.000, -366.025, -866.025, -1366.025, -1732.051, -1866.025, -1732.051, -1366.025, -866.025, -366.025, -0.000, 133.975, + -0.000, -133.975, -500.000, -1000.000, -1500.000, -1866.025, -2000.000, -1866.025, -1500.000, -1000.000, -500.000, -133.975, -0.000, + 133.975, -0.000, -366.025, -866.025, -1366.025, -1732.051, -1866.025, -1732.051, -1366.025, -866.025, -366.025, -0.000, 133.975, + 500.000, 366.025, -0.000, -500.000, -1000.000, -1366.025, -1500.000, -1366.025, -1000.000, -500.000, -0.000, 366.025, 500.000, + 1000.000, 866.025, 500.000, -0.000, -500.000, -866.025, -1000.000, -866.025, -500.000, -0.000, 500.000, 866.025, 1000.000 + ], + "x": [ + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, + + 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, + 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, + 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, + 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, + 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, + 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, + 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, + 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, + 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, + 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, + 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, + 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, + 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, + + 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, + 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, + 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, + 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, + 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, + 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, + 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, + 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, + 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, + 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, + 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, + 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, + 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, + + 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, + 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, + 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, + 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, + 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, + 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, + 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, + 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, + 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, + 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, + 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, + 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, + 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, + + 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, + 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, + 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, + 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, + 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, + 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, + 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, + 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, + 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, + 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, + 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, + 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, + 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, + + 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, + 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, + 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, + 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, + 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, + 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, + 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, + 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, + 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, + 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, + 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, + 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, + 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, + + 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, + 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, + 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, + 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, + 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, + 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, + 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, + 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, + 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, + 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, + 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, + 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, + 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, + + 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, + 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, + 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, + 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, + 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, + 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, + 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, + 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, + 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, + 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, + 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, + 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, + 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, + + 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, + 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, + 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, + 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, + 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, + 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, + 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, + 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, + 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, + 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, + 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, + 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, + 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, + + 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, + 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, + 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, + 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, + 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, + 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, + 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, + 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, + 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, + 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, + 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, + 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, + 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, + + 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, + 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, + 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, + 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, + 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, + 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, + 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, + 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, + 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, + 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, + 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, + 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, + 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, + + 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, + 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, + 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, + 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, + 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, + 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, + 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, + 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, + 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, + 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, + 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, + 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, + 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, + + 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, + 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, + 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, + 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, + 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, + 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, + 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, + 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, + 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, + 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, + 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, + 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, + 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000 + ], + "y": [ + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, + 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, + 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, + 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, + 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, + 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, + 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, + 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, + 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, + 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, + 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, + 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, + 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, + + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, + 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, + 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, + 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, + 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, + 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, + 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, + 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, + 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, + 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, + 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, + 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, + 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, + + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, + 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, + 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, + 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, + 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, + 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, + 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, + 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, + 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, + 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, + 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, + 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, + 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, + + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, + 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, + 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, + 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, + 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, + 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, + 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, + 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, + 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, + 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, + 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, + 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, + 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, + + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, + 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, + 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, + 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, + 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, + 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, + 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, + 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, + 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, + 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, + 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, + 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, + 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, + + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, + 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, + 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, + 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, + 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, + 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, + 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, + 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, + 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, + 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, + 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, + 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, + 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, + + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, + 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, + 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, + 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, + 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, + 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, + 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, + 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, + 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, + 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, + 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, + 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, + 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, + + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, + 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, + 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, + 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, + 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, + 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, + 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, + 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, + 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, + 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, + 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, + 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, + 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, + + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, + 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, + 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, + 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, + 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, + 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, + 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, + 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, + 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, + 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, + 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, + 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, + 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, + + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, + 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, + 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, + 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, + 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, + 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, + 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, + 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, + 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, + 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, + 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, + 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, + 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, + + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, + 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, + 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, + 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, + 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, + 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, + 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, + 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, + 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, + 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, + 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, + 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, + 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, + + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, + 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, + 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, + 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, + 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, + 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, + 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, + 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, + 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, + 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, + 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, + 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, + 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, + + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, + 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, 0.083, + 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, + 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, 0.250, + 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, 0.333, + 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, 0.417, + 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, + 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, 0.583, + 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, + 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, 0.750, + 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, 0.833, + 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, 0.917, + 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000 + ], + "z": [ + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000, + 0.000, 0.007, 0.028, 0.063, 0.111, 0.174, 0.250, 0.340, 0.444, 0.563, 0.694, 0.840, 1.000 + ], + + "scene": "scene2", + "coloraxis": "coloraxis2" + }], + + "layout": { + "title": "gl3d trace with shared coloraxes", + + "coloraxis": { + "colorscale": "Viridis", + "colorbar": { + "x": -0.1, + "xanchor": "right" + } + }, + "coloraxis2": { + "colorscale": "Viridis", + "colorbar": { + "x": 1.1, + "xanchor": "left" + } + } + } +} diff --git a/test/image/mocks/gl3d_ribbons.json b/test/image/mocks/gl3d_ribbons.json index 0aa647b52b1..dd993dc2b0a 100644 --- a/test/image/mocks/gl3d_ribbons.json +++ b/test/image/mocks/gl3d_ribbons.json @@ -607,7 +607,8 @@ 0.75 ] ], - "type": "surface" + "type": "surface", + "coloraxis": "coloraxis" }, { "z": [ @@ -1216,7 +1217,8 @@ 1.75 ] ], - "type": "surface" + "type": "surface", + "coloraxis": "coloraxis" }, { "z": [ @@ -1825,7 +1827,8 @@ 2.75 ] ], - "type": "surface" + "type": "surface", + "coloraxis": "coloraxis" }, { "z": [ @@ -2434,7 +2437,8 @@ 3.75 ] ], - "type": "surface" + "type": "surface", + "coloraxis": "coloraxis" }, { "z": [ @@ -3043,7 +3047,8 @@ 4.75 ] ], - "type": "surface" + "type": "surface", + "coloraxis": "coloraxis" }, { "z": [ @@ -3652,7 +3657,8 @@ 5.75 ] ], - "type": "surface" + "type": "surface", + "coloraxis": "coloraxis" }, { "z": [ @@ -4261,7 +4267,8 @@ 6.75 ] ], - "type": "surface" + "type": "surface", + "coloraxis": "coloraxis" }, { "z": [ @@ -4870,7 +4877,8 @@ 7.75 ] ], - "type": "surface" + "type": "surface", + "coloraxis": "coloraxis" }, { "z": [ @@ -5479,7 +5487,8 @@ 8.75 ] ], - "type": "surface" + "type": "surface", + "coloraxis": "coloraxis" }, { "z": [ @@ -6088,7 +6097,8 @@ 9.75 ] ], - "type": "surface" + "type": "surface", + "coloraxis": "coloraxis" }, { "z": [ @@ -6697,7 +6707,8 @@ 10.75 ] ], - "type": "surface" + "type": "surface", + "coloraxis": "coloraxis" }, { "z": [ @@ -7306,7 +7317,8 @@ 11.75 ] ], - "type": "surface" + "type": "surface", + "coloraxis": "coloraxis" }, { "z": [ @@ -7915,7 +7927,8 @@ 12.75 ] ], - "type": "surface" + "type": "surface", + "coloraxis": "coloraxis" }, { "z": [ @@ -8524,7 +8537,8 @@ 13.75 ] ], - "type": "surface" + "type": "surface", + "coloraxis": "coloraxis" }, { "z": [ @@ -9133,7 +9147,8 @@ 14.75 ] ], - "type": "surface" + "type": "surface", + "coloraxis": "coloraxis" }, { "z": [ @@ -9742,7 +9757,8 @@ 15.75 ] ], - "type": "surface" + "type": "surface", + "coloraxis": "coloraxis" }, { "z": [ @@ -10351,7 +10367,8 @@ 16.75 ] ], - "type": "surface" + "type": "surface", + "coloraxis": "coloraxis" }, { "z": [ @@ -10960,7 +10977,8 @@ 17.75 ] ], - "type": "surface" + "type": "surface", + "coloraxis": "coloraxis" }, { "z": [ @@ -11569,7 +11587,8 @@ 18.75 ] ], - "type": "surface" + "type": "surface", + "coloraxis": "coloraxis" } ], "layout": { diff --git a/test/image/mocks/gl3d_scatter3d-colorscale-marker-and-line.json b/test/image/mocks/gl3d_scatter3d-colorscale-marker-and-line.json new file mode 100644 index 00000000000..6e08b7f8c23 --- /dev/null +++ b/test/image/mocks/gl3d_scatter3d-colorscale-marker-and-line.json @@ -0,0 +1,39 @@ +{ + "data": [ + { + "x": [1, 2, 4, 8, 16], + "y": [-1, -2, -4, -8, -16], + "z": [0, 1, 0, 1, 0], + "type": "scatter3d", + "mode": "lines+markers", + "line": { + "color": [0, 0.25, 0.5, 0.75, 1.0], + "width": 10, + "colorscale": "Blues", + "colorbar": { + "len": 0.5, + "y": 1, + "yanchor": "top", + "title": {"text": "line colorscale", "side": "right"} + } + }, + "marker": { + "color": [1.0, 0.75, 0.5, 0.25, 0], + "size": 10, + "colorscale": "Reds", + "colorbar": { + "len": 0.5, + "y": 0, + "yanchor": "bottom", + "title": {"text": "marker colorscale", "side": "right"} + } + + } + } + ], + "layout": { + "title": "Scatter3d show line AND marker color scales", + "width": 600, + "height": 600 + } +} diff --git a/test/image/mocks/shared_coloraxes.json b/test/image/mocks/shared_coloraxes.json new file mode 100644 index 00000000000..43634c68042 --- /dev/null +++ b/test/image/mocks/shared_coloraxes.json @@ -0,0 +1,125 @@ +{ + "data": [{ + "name": "heatmap 1 - coloraxis 1", + "type": "heatmap", + "x": [1, 2], + "z": [[1, 2], [4, -3]], + "coloraxis": "coloraxis" + }, { + "name": "heatmap 2 - coloraxis 1", + "type": "heatmap", + "x": [3, 4], + "z": [[10, 2], [4, 3]], + "coloraxis": "coloraxis" + }, { + "name": "heatmap 3 - coloraxis 1", + "type": "heatmap", + "x": [5, 6], + "z": [[3, -2], [4, 5]], + "coloraxis": "coloraxis" + }, + + { + "name": "bar marker.color scale - coloraxis 2", + "type": "bar", + "y": [1, 2, 1], + "marker": { + "color": [20, 2, 30], + "coloraxis": "coloraxis2" + }, + "xaxis": "x2", + "yaxis": "y2" + }, { + "name": "marker.line.color scale - coloraxis 2", + "mode": "markers", + "y": [1.5, 2.5, 1.5], + "marker": { + "color": "#444", + "size": 10, + "line": { + "width": 2, + "color": [12, 2, 10], + "coloraxis": "coloraxis2" + } + }, + "xaxis": "x2", + "yaxis": "y2" + }, + + { + "name": "histogram2d 1 - coloraxis 3", + "type": "histogram2d", + "x": [1, 2, 3, 3, 3, 4, 5], + "y": [1, 2, 5, 5, 5, 2, 1], + "coloraxis": "coloraxis3", + "xaxis": "x3", + "yaxis": "y3" + }, { + "name": "histogram2d 1 - coloraxis 3", + "type": "histogram2d", + "x": [1, 2, 5, 5, 5, 2, 1], + "y": [1, 2, 3, 3, 3, 4, 5], + "coloraxis": "coloraxis3", + "xaxis": "x3", + "yaxis": "y3" + }, + + { + "name": "scatterpolar marker.color - coloraxis 3 N.B. across subplots!", + "type": "scatterpolar", + "mode": "markers", + "r": [1, 2, 3], + "marker": { + "symbol": "diamond", + "size": 10, + "color": [2, 3, 4], + "coloraxis": "coloraxis3" + } + }], + "layout": { + "showlegend": false, + "grid": {"rows": 2, "columns": 2, "pattern": "independent"}, + "polar": {"domain": {"row": 1, "column": 1}}, + + "coloraxis": { + "colorbar": { + "len": 0.5, + "x": -0.05, "xanchor": "right", + "y": 1, "yanchor": "top" + } + }, + "coloraxis2": { + "colorbar": { + "len": 0.5, + "x": 1.05, "xanchor": "left", + "y": 1, "yanchor": "top" + } + }, + "coloraxis3": { + "cauto": false, + "cmax": 5, + "colorscale": "Viridis", + "colorbar": { + "len": 0.5, + "x": -0.05, "xanchor": "right", + "y": 0, "yanchor": "bottom", + "dtick": 1 + } + }, + + "colorscale": { + "sequential": "Greens" + }, + + "template": { + "layout": { + "coloraxis": { + "colorbar": {"outlinewidth": 2} + }, + "coloraxis3": { + "colorbar": {"outlinecolor": "blue", "outlinewidth": 4} + } + } + } + } +} diff --git a/test/image/mocks/shared_coloraxes_contour.json b/test/image/mocks/shared_coloraxes_contour.json new file mode 100644 index 00000000000..7f5df767f46 --- /dev/null +++ b/test/image/mocks/shared_coloraxes_contour.json @@ -0,0 +1,138 @@ +{ + "data": [{ + "name": "contour coloring:heatmap 1 - coloraxis 1", + "type": "contour", + "x": [1, 2], + "z": [[1, 2], [10, -3]], + "contours": {"coloring": "heatmap"}, + "coloraxis": "coloraxis" + }, { + "name": "heatmap - coloraxis 1", + "type": "heatmap", + "x": [3, 4], + "z": [[4, 2], [4, 3]], + "coloraxis": "coloraxis" + }, { + "name": "markers - coloraxis 1", + "mode": "markers", + "x": [1, 3, 5], + "y": [1, 2, 1], + "marker": { + "size": 20, + "symbol": "diamond", + "color": [1, 2, 0], + "coloraxis": "coloraxis" + } + }, { + "name": "contour coloring:heatmap 2 - coloraxis 1", + "type": "contour", + "x": [5, 6], + "z": [[3, -6], [4, 5]], + "contours": {"coloring": "heatmap"}, + "coloraxis": "coloraxis" + }, + + { + "name": "contour 1 - coloraxis 2", + "type": "contour", + "x": [1, 2], + "z": [[3, -6], [4, 5]], + "coloraxis": "coloraxis2", + "xaxis": "x2", + "yaxis": "y2" + }, { + + "name": "contour 2 - coloraxis 2", + "type": "contour", + "x": [2, 3], + "z": [[1, 2], [10, -3]], + "coloraxis": "coloraxis2", + "xaxis": "x2", + "yaxis": "y2" + }, + + { + "name": "contour coloring:lines - coloraxis 3", + "type": "contour", + "x": [1, 2], + "z": [[3, -6], [4, 5]], + "contours": {"coloring": "lines"}, + "line": {"width": 2}, + "coloraxis": "coloraxis3", + "xaxis": "x3", + "yaxis": "y3" + }, { + + "name": "contour coloring:lines 2 - coloraxis 3", + "type": "contour", + "x": [2, 3], + "z": [[1, 2], [10, -3]], + "contours": {"coloring": "lines"}, + "line": {"width": 2}, + "coloraxis": "coloraxis3", + "xaxis": "x3", + "yaxis": "y3" + }, + + { + "name": "contour coloring:heatmap edge case - coloraxis 4", + "type": "contour", + "x": [1, 2, 3], + "z": [[1, 2, 3], [1, 2, 3]], + "contours": { + "coloring": "heatmap", + "start": 1, "end": 5 + }, + "coloraxis": "coloraxis4", + "xaxis": "x4", + "yaxis": "y4" + }, { + "name": "contour coloring:heatmap edge case 2 - coloraxis 4", + "type": "contour", + "x": [5, 6, 7], + "z": [[2, 3, 4], [2, 3, 4]], + "contours": { + "coloring": "heatmap", + "start": 0, "end": 3 + }, + "coloraxis": "coloraxis4", + "xaxis": "x4", + "yaxis": "y4" + }], + + "layout": { + "showlegend": false, + "grid": {"rows": 2, "columns": 2, "pattern": "independent"}, + + "coloraxis": { + "colorbar": { + "len": 0.5, + "x": -0.05, "xanchor": "right", + "y": 1, "yanchor": "top" + } + }, + "coloraxis2": { + "colorbar": { + "dtick": 1, + "len": 0.5, + "x": 1.05, "xanchor": "left", + "y": 1, "yanchor": "top" + } + }, + "coloraxis3": { + "colorbar": { + "len": 0.5, + "x": -0.05, "xanchor": "right", + "y": 0, "yanchor": "bottom" + } + }, + "coloraxis4": { + "colorscale": "Viridis", + "colorbar": { + "len": 0.5, + "x": 1.05, "xanchor": "left", + "y": 0, "yanchor": "bottom" + } + } + } +} diff --git a/test/jasmine/bundle_tests/plotschema_test.js b/test/jasmine/bundle_tests/plotschema_test.js index a515f5523cd..b92a9ec9b62 100644 --- a/test/jasmine/bundle_tests/plotschema_test.js +++ b/test/jasmine/bundle_tests/plotschema_test.js @@ -136,7 +136,8 @@ describe('plot schema', function() { 'xaxis', 'yaxis', 'scene', 'geo', 'ternary', 'mapbox', 'polar', // not really a 'subplot' object but supports yaxis, yaxis2, yaxis3, // ... counters, so list it here - 'xaxis.rangeslider.yaxis' + 'xaxis.rangeslider.yaxis', + 'coloraxis' ]; // check if the subplot objects have '_isSubplotObj' @@ -146,7 +147,7 @@ describe('plot schema', function() { plotSchema.layout.layoutAttributes, astr + '.' + IS_SUBPLOT_OBJ ).get() - ).toBe(true); + ).toBe(true, astr); }); // check that no other object has '_isSubplotObj' diff --git a/test/jasmine/tests/colorbar_test.js b/test/jasmine/tests/colorbar_test.js index 9468df91489..1314d3b6b7c 100644 --- a/test/jasmine/tests/colorbar_test.js +++ b/test/jasmine/tests/colorbar_test.js @@ -2,6 +2,8 @@ var d3 = require('d3'); var Plotly = require('@lib/index'); var Colorbar = require('@src/components/colorbar'); +var Plots = require('@src/plots/plots'); +var subroutines = require('@src/plot_api/subroutines'); var createGraphDiv = require('../assets/create_graph_div'); var destroyGraphDiv = require('../assets/destroy_graph_div'); @@ -10,7 +12,6 @@ var supplyAllDefaults = require('../assets/supply_defaults'); var assertPlotSize = require('../assets/custom_assertions').assertPlotSize; var drag = require('../assets/drag'); - describe('Test colorbar:', function() { 'use strict'; @@ -226,6 +227,41 @@ describe('Test colorbar:', function() { .then(done); }); + it('can show and hide colorbars of shared color axes', function(done) { + Plotly.newPlot(gd, [{ + y: [1, 2, 3], + marker: {color: [1, 2, 3], coloraxis: 'coloraxis'} + }, { + y: [1, 2, 3], + marker: {color: [1, 0, 3], coloraxis: 'coloraxis'} + }], { + showlegend: false, + height: 500, + width: 500, + margin: {l: 50, r: 50, t: 50, b: 50} + }) + .then(function() { + assertCB('initial', true, {expandedMarginR: true}); + + return Plotly.relayout(gd, {'coloraxis.showscale': false}); + }) + .then(function() { + assertCB('hidden', false, {expandedMarginR: false}); + + return Plotly.relayout(gd, {'coloraxis.showscale': true, 'coloraxis.colorbar.x': 0.7}); + }) + .then(function() { + assertCB('mid-plot', true, {expandedMarginR: false}); + + return Plotly.relayout(gd, {'coloraxis.colorbar.x': 1.1}); + }) + .then(function() { + assertCB('far right', true, {expandedMarginR: true}); + }) + .catch(failTest) + .then(done); + }); + // histogram colorbars could not be edited before it('can show and hide histogram colorbars', function(done) { Plotly.newPlot(gd, [{ @@ -399,5 +435,93 @@ describe('Test colorbar:', function() { .catch(failTest) .then(done); }); + + it('can drag colorbars linked to color axes in editable mode', function(done) { + Plotly.newPlot(gd, + [{z: [[1, 2], [3, 4]], type: 'heatmap', coloraxis: 'coloraxis'}], + {coloraxis: {}, width: 400, height: 400}, + {editable: true} + ) + .then(function() { + expect(gd.layout.coloraxis.colorbar).toBeUndefined(); + expect(gd._fullLayout.coloraxis.colorbar.x).toBe(1.02); + expect(gd._fullLayout.coloraxis.colorbar.y).toBe(0.5); + return drag(getCBNode(), -100, 100); + }) + .then(function() { + expect(gd.layout.coloraxis.colorbar.x).toBeWithin(0.591, 0.01); + expect(gd.layout.coloraxis.colorbar.y).toBeWithin(0.045, 0.01); + expect(gd._fullLayout.coloraxis.colorbar.x).toBeWithin(0.591, 0.01); + expect(gd._fullLayout.coloraxis.colorbar.y).toBeWithin(0.045, 0.01); + }) + .catch(failTest) + .then(done); + }); + + it('can edit colorbar visuals in optimized edit pathway', function(done) { + spyOn(subroutines, 'doColorBars').and.callThrough(); + spyOn(Plots, 'doCalcdata').and.callThrough(); + + function getOutline(cb) { + return Number(cb.select('.cboutline').node().style['stroke-width']); + } + + function _assert(msg, exp) { + var gd3 = d3.select(gd); + var cb0 = gd3.select('.cbtrace0'); + var cb1 = gd3.select('.cbcoloraxis'); + + if(msg !== 'base') { + expect(subroutines.doColorBars).toHaveBeenCalledTimes(1); + expect(Plots.doCalcdata).toHaveBeenCalledTimes(0); + } + subroutines.doColorBars.calls.reset(); + Plots.doCalcdata.calls.reset(); + + expect(getOutline(cb0)).toBe(exp.outline[0], 'trace0 cb outline'); + expect(getOutline(cb1)).toBe(exp.outline[1], 'coloraxis cb outline'); + } + + Plotly.newPlot(gd, [{ + type: 'heatmap', + z: [[1, 2, 3], [2, 1, 2]], + uid: 'trace0' + }, { + y: [1, 2, 3], + marker: {color: [2, 1, 2], coloraxis: 'coloraxis'} + }], { + width: 500, + height: 500 + }) + .then(function() { _assert('base', {outline: [1, 1]}); }) + .then(function() { + return Plotly.restyle(gd, 'colorbar.outlinewidth', 2, [0]); + }) + .then(function() { _assert('after restyle', {outline: [2, 1]}); }) + .then(function() { + return Plotly.relayout(gd, 'coloraxis.colorbar.outlinewidth', 5); + }) + .then(function() { _assert('after relayout', {outline: [2, 5]}); }) + .then(function() { + return Plotly.update(gd, {'colorbar.outlinewidth': 1}, {}, [0]); + }) + .then(function() { _assert('after trace update', {outline: [1, 5]}); }) + .then(function() { + return Plotly.update(gd, {}, {'coloraxis.colorbar.outlinewidth': 1}); + }) + .then(function() { _assert('after layout update', {outline: [1, 1]}); }) + .then(function() { + gd.data[0].colorbar = {outlinewidth: 10}; + return Plotly.react(gd, gd.data, gd.layout); + }) + .then(function() { _assert('after trace react', {outline: [10, 1]}); }) + .then(function() { + gd.layout.coloraxis = {colorbar: {outlinewidth: 10}}; + return Plotly.react(gd, gd.data, gd.layout); + }) + .then(function() { _assert('after layout trace', {outline: [10, 10]}); }) + .catch(failTest) + .then(done); + }); }); }); diff --git a/test/jasmine/tests/colorscale_test.js b/test/jasmine/tests/colorscale_test.js index 281ab5ff2b9..551050987c7 100644 --- a/test/jasmine/tests/colorscale_test.js +++ b/test/jasmine/tests/colorscale_test.js @@ -13,14 +13,12 @@ var destroyGraphDiv = require('../assets/destroy_graph_div'); var failTest = require('../assets/fail_test'); var supplyAllDefaults = require('../assets/supply_defaults'); -function _supply(trace, layout) { +function _supply(arg, layout) { var gd = { - data: [trace], + data: Array.isArray(arg) ? arg : [arg], layout: layout || {} }; - supplyAllDefaults(gd); - return gd; } @@ -259,7 +257,7 @@ describe('Test colorscale:', function() { } beforeEach(function() { - traceOut = {}; + traceOut = {_module: {}}; }); it('should set auto to true when min/max are valid', function() { @@ -330,7 +328,10 @@ describe('Test colorscale:', function() { } beforeEach(function() { - traceOut = { marker: {} }; + traceOut = { + marker: {}, + _module: {} + }; }); it('should coerce autocolorscale to true by default', function() { @@ -368,6 +369,117 @@ describe('Test colorscale:', function() { }); }); + describe('handleDefaults (coloraxis version)', function() { + it('should not coerced colorscale/colorbar attributes when referencing a shared color axis', function() { + var gd = _supply([ + {type: 'heatmap', z: [[0]]}, + {type: 'heatmap', z: [[2]], coloraxis: 'coloraxis'}, + {type: 'heatmap', z: [[2]], coloraxis: 'coloraxis'}, + ]); + + var fullData = gd._fullData; + var fullLayout = gd._fullLayout; + + var zAttrs = ['zauto', 'colorscale', 'reversescale']; + zAttrs.forEach(function(attr) { + expect(fullData[0][attr]).not.toBe(undefined, 'trace 0 ' + attr); + expect(fullData[1][attr]).toBe(undefined, 'trace 1 ' + attr); + expect(fullData[2][attr]).toBe(undefined, 'trace 2 ' + attr); + }); + + var cAttrs = ['cauto', 'colorscale', 'reversescale']; + cAttrs.forEach(function(attr) { + expect(fullLayout.coloraxis[attr]).not.toBe(undefined, 'coloraxis ' + attr); + }); + + expect(fullData[0].coloraxis).toBe(undefined); + expect(fullData[1].coloraxis).toBe('coloraxis'); + expect(fullData[2].coloraxis).toBe('coloraxis'); + expect(fullLayout.coloraxis.coloraxis).toBe(undefined); + expect(fullLayout.coloraxis.showscale).toBe(true, 'showscale is true by dflt in color axes'); + }); + + it('should keep track of all the color axes referenced in the traces', function() { + var gd = _supply([ + {type: 'heatmap', z: [[1]], coloraxis: 'coloraxis'}, + {y: [1], marker: {color: [1], coloraxis: 'coloraxis'}}, + {type: 'contour', z: [[1]], coloraxis: 'coloraxis3'}, + // invalid + {y: [1], marker: {color: [1], coloraxis: 'c1'}}, + // not coerced - visible:false trace + {marker: {color: [1], coloraxis: 'coloraxis2'}} + ], { + // not referenced in traces, shouldn't get coerced + coloraxis4: {colorscale: 'Viridis'} + }); + + var fullData = gd._fullData; + var fullLayout = gd._fullLayout; + + expect(fullData[0].coloraxis).toBe('coloraxis'); + expect(fullData[1].marker.coloraxis).toBe('coloraxis'); + expect(fullData[2].coloraxis).toBe('coloraxis3'); + expect(fullData[3].coloraxis).toBe(undefined); + + expect(fullData[0]._colorAx).toBe(fullLayout.coloraxis); + expect(fullData[1].marker._colorAx).toBe(fullLayout.coloraxis); + expect(fullData[2]._colorAx).toBe(fullLayout.coloraxis3); + + expect(fullLayout.coloraxis).not.toBe(undefined); + expect(fullLayout.coloraxis2).toBe(undefined); + expect(fullLayout.coloraxis3).not.toBe(undefined); + expect(fullLayout.coloraxis4).toBe(undefined); + + expect(Object.keys(fullLayout._colorAxes)).toEqual(['coloraxis', 'coloraxis3']); + expect(fullLayout._colorAxes.coloraxis[0]).toBe('heatmap'); + expect(fullLayout._colorAxes.coloraxis3[0]).toBe('fill'); + }); + + it('should log warning when trying to shared color axis with traces with incompatible color bars', function() { + spyOn(Lib, 'warn'); + + var gd = _supply([ + // ok + {type: 'heatmap', z: [[1]], coloraxis: 'coloraxis'}, + {y: [1], marker: {color: [1], coloraxis: 'coloraxis'}}, + {type: 'contour', z: [[1]], contours: {coloring: 'heatmap'}, coloraxis: 'coloraxis'}, + // invalid (coloring dflt is 'fill') + {type: 'heatmap', z: [[1]], coloraxis: 'coloraxis2'}, + {type: 'contour', z: [[1]], coloraxis: 'coloraxis2'}, + // invalid + {type: 'contour', z: [[1]], contours: {coloring: 'lines'}, coloraxis: 'coloraxis3'}, + {type: 'contour', z: [[1]], contours: {coloring: 'heatmap'}, coloraxis: 'coloraxis3'}, + // ok + {type: 'contour', z: [[1]], coloraxis: 'coloraxis4'}, + {type: 'contour', z: [[1]], coloraxis: 'coloraxis4'}, + // ok + {type: 'contour', z: [[1]], contours: {coloring: 'lines'}, coloraxis: 'coloraxis5'}, + {type: 'contour', z: [[1]], contours: {coloring: 'lines'}, coloraxis: 'coloraxis5'} + ]); + + var fullData = gd._fullData; + var fullLayout = gd._fullLayout; + + expect(Object.keys(fullLayout._colorAxes)).toEqual(['coloraxis', 'coloraxis4', 'coloraxis5']); + expect(fullLayout._colorAxes.coloraxis[0]).toBe('heatmap'); + expect(fullLayout._colorAxes.coloraxis4[0]).toBe('fill'); + expect(fullLayout._colorAxes.coloraxis5[0]).toBe('lines'); + expect(Lib.warn).toHaveBeenCalledTimes(2); + + var zAttrs = ['zauto', 'colorscale', 'reversescale']; + var withColorAx = [0, 1, 2, 7, 8, 9, 10]; + var woColorAx = [3, 4, 5, 6]; + zAttrs.forEach(function(attr) { + withColorAx.forEach(function(i) { + expect(fullData[i][attr]).toBe(undefined, 'trace ' + i + ' ' + attr); + }); + woColorAx.forEach(function(i) { + expect(fullData[i][attr]).not.toBe(undefined, 'trace ' + i + ' ' + attr); + }); + }); + }); + }); + describe('calc', function() { var calcColorscale = Colorscale.calc; var trace, z; @@ -520,6 +632,27 @@ describe('Test colorscale:', function() { expect(trace.autocolorscale).toBe(true); expect(trace.colorscale).toEqual(colorscale); }); + + it('should compute min/max across trace linked to same color axis', function() { + gd = _supply([ + {type: 'heatmap', z: [[1, 3, 4], [2, 3, 1]], coloraxis: 'coloraxis'}, + {y: [1, 3, 1], marker: {color: [3, 4, -2], coloraxis: 'coloraxis'}}, + ]); + + Plots.doCalcdata(gd); + + var fullData = gd._fullData; + expect(fullData[0].zmin).toBe(undefined); + expect(fullData[0].zmax).toBe(undefined); + expect(fullData[1].marker.cmin).toBe(undefined); + expect(fullData[1].marker.cmax).toBe(undefined); + + var fullLayout = gd._fullLayout; + expect(fullLayout.coloraxis.cmin).toBe(-2); + expect(fullLayout.coloraxis._cmin).toBe(-2); + expect(fullLayout.coloraxis.cmax).toBe(4); + expect(fullLayout.coloraxis._cmax).toBe(4); + }); }); describe('extractScale + makeColorScaleFunc', function() { @@ -535,11 +668,11 @@ describe('Test colorscale:', function() { it('should constrain color array values between cmin and cmax', function() { var trace = { colorscale: scale, - pmin: 2, - pmax: 3 + cmin: 2, + cmax: 3 }; - var specs = Colorscale.extractScale(trace, {cLetter: 'p'}); + var specs = Colorscale.extractScale(trace); var sclFunc = Colorscale.makeColorScaleFunc(specs); var color1 = sclFunc(1); @@ -557,11 +690,11 @@ describe('Test colorscale:', function() { var trace = { colorscale: scale, reversescale: true, - pmin: 2, - pmax: 3 + zmin: 2, + zmax: 3 }; - var specs = Colorscale.extractScale(trace, {cLetter: 'p'}); + var specs = Colorscale.extractScale(trace); var sclFunc = Colorscale.makeColorScaleFunc(specs); var color1 = sclFunc(1); @@ -574,6 +707,29 @@ describe('Test colorscale:', function() { expect(color3).toEqual(color4); expect(color4).toEqual('rgb(5, 10, 172)'); }); + + it('should extract coloraxis options, if present', function() { + var trace = { + _colorAx: { + colorscale: scale, + cmin: 2, + cmax: 3 + } + }; + + var specs = Colorscale.extractScale(trace); + var sclFunc = Colorscale.makeColorScaleFunc(specs); + + var color1 = sclFunc(1); + var color2 = sclFunc(2); + var color3 = sclFunc(3); + var color4 = sclFunc(4); + + expect(color1).toEqual(color2); + expect(color1).toEqual('rgb(5, 10, 172)'); + expect(color3).toEqual(color4); + expect(color4).toEqual('rgb(178, 10, 28)'); + }); }); }); @@ -865,6 +1021,86 @@ describe('Test colorscale restyle calls:', function() { .then(done); }); + it('should be able to toggle between autocolorscale true/false and set colorscales (coloraxis case)', function(done) { + function _assert(msg, exp) { + var mcc = []; + d3.selectAll('path.point').each(function() { mcc.push(getFill(this)); }); + expect(mcc).toEqual(exp.mcc); + + expect(gd._fullLayout.coloraxis.colorscale).toEqual(exp.colorscale); + expect(gd._fullLayout.coloraxis.autocolorscale).toBe(exp.autocolorscale, msg); + expect((gd.layout.coloraxis || {}).colorscale).toEqual(exp.colorscaleIn); + expect((gd.layout.coloraxis || {}).autocolorscale).toBe(exp.autocolorscaleIn, msg); + } + + // update via, assert then assert again (and again ;) after non-calc edits + function _run(msg, updateObj, exp) { + return Plotly.relayout(gd, updateObj) + .then(function() { _assert(msg, exp); }) + .then(function() { return Plotly.relayout(gd, 'xaxis.range', [-1, 5]); }) + .then(function() { _assert(msg + ' after axrange relayout', exp); }) + .then(function() { return Plotly.relayout(gd, 'xaxis.autorange', true); }) + .then(function() { _assert(msg + ' after autorange', exp); }) + .then(function() { return Plotly.restyle(gd, 'marker.symbol', 'square'); }) + .then(function() { _assert(msg + ' after marker.symbol restyle', exp); }) + .then(function() { return Plotly.restyle(gd, 'marker.symbol', null); }) + .then(function() { _assert(msg + ' back to original marker.symbol', exp); }); + } + + var rdbu = ['rgb(5, 10, 172)', 'rgb(53, 70, 208)', 'rgb(227, 153, 104)', + 'rgb(53, 70, 208)', 'rgb(53, 70, 208)', 'rgb(178, 10, 28)']; + var grns = ['rgb(0, 68, 27)', 'rgb(12, 119, 52)', 'rgb(174, 222, 167)', + 'rgb(12, 119, 52)', 'rgb(12, 119, 52)', 'rgb(247, 252, 245)']; + + Plotly.plot(gd, [{ + mode: 'markers', + y: [1, 2, 3], + marker: {color: [-1, 0, 3], coloraxis: 'coloraxis'} + }, { + mode: 'markers', + y: [2, 3, 4], + marker: {color: [0, 0, 5], coloraxis: 'coloraxis'} + }]) + .then(function() { + _assert('base (autocolorscale:true by dflt)', { + mcc: rdbu, + autocolorscale: true, + autocolorscaleIn: undefined, + colorscale: Colorscale.scales.RdBu, + colorscaleIn: undefined + }); + }) + .then(function() { + return _run('set *Greens* colorscale', {'coloraxis.colorscale': 'Greens'}, { + mcc: grns, + autocolorscale: false, + autocolorscaleIn: false, + colorscale: Colorscale.scales.Greens, + colorscaleIn: 'Greens' + }); + }) + .then(function() { + return _run('back to autocolorscale:true', {'coloraxis.autocolorscale': true}, { + mcc: rdbu, + autocolorscale: true, + autocolorscaleIn: true, + colorscale: Colorscale.scales.RdBu, + colorscaleIn: 'Greens' + }); + }) + .then(function() { + return _run('back to autocolorscale:false w/ colorscale set', {'coloraxis.autocolorscale': false}, { + mcc: grns, + autocolorscale: false, + autocolorscaleIn: false, + colorscale: Colorscale.scales.Greens, + colorscaleIn: 'Greens' + }); + }) + .catch(failTest) + .then(done); + }); + it('should work with templates', function(done) { function _assert(msg, exp) { var mcc = []; @@ -910,11 +1146,14 @@ describe('Test colorscale restyle calls:', function() { x: [1, 2, 3], y: [1, 2, 3], z: [1, 2, 1], - marker: {color: [1, 2, 1], showscale: true} + marker: {color: [1, 2, 1], showscale: true}, + line: {color: [2, 3, 4], showscale: true} }]) .then(function() { expect(gd._fullData[0].marker.cmin).toBe(1); expect(gd._fullData[0].marker.cmax).toBe(2); + expect(gd._fullData[0].line.cmin).toBe(2); + expect(gd._fullData[0].line.cmax).toBe(4); }) .then(function() { // some non-calc edit @@ -923,6 +1162,8 @@ describe('Test colorscale restyle calls:', function() { .then(function() { expect(gd._fullData[0].marker.cmin).toBe(1); expect(gd._fullData[0].marker.cmax).toBe(2); + expect(gd._fullData[0].line.cmin).toBe(2); + expect(gd._fullData[0].line.cmax).toBe(4); }) .catch(failTest) .then(done);