diff --git a/src/components/colorbar/connect.js b/src/components/colorbar/connect.js
deleted file mode 100644
index 7afd261873b..00000000000
--- a/src/components/colorbar/connect.js
+++ /dev/null
@@ -1,66 +0,0 @@
-/**
-* Copyright 2012-2019, Plotly, Inc.
-* All rights reserved.
-*
-* This source code is licensed under the MIT license found in the
-* LICENSE file in the root directory of this source tree.
-*/
-
-'use strict';
-
-var drawColorbar = require('./draw');
-var flipScale = require('../colorscale/helpers').flipScale;
-
-/**
- * connectColorbar: create a colorbar from a trace, using its module to
- * describe the connection.
- *
- * @param {DOM element} gd
- *
- * @param {Array} cd
- * calcdata entry for this trace. cd[0].trace is the trace itself, and the
- * colorbar object will be stashed in cd[0].t.cb
- *
- * @param {object|function} moduleOpts
- * may be a function(gd, cd) to override the standard handling below. If
- * an object, should have these keys:
- * @param {Optional(string)} moduleOpts.container
- * name of the container inside the trace where the colorbar and colorscale
- * attributes live (ie 'marker', 'line') - omit if they're at the trace root.
- * @param {string} moduleOpts.min
- * name of the attribute holding the value of the minimum color
- * @param {string} moduleOpts.max
- * name of the attribute holding the value of the maximum color
- * @param {Optional(string)} moduleOpts.vals
- * name of the attribute holding the (numeric) color data
- * used only if min/max fail. May be omitted if these are always
- * pre-calculated.
- */
-module.exports = function connectColorbar(gd, cd, moduleOpts) {
- if(typeof moduleOpts === 'function') return moduleOpts(gd, cd);
-
- var trace = cd[0].trace;
- var cbId = 'cb' + trace.uid;
- moduleOpts = Array.isArray(moduleOpts) ? moduleOpts : [moduleOpts];
-
- for(var i = 0; i < moduleOpts.length; i++) {
- var containerName = moduleOpts[i].container;
-
- var container = containerName ? trace[containerName] : trace;
-
- gd._fullLayout._infolayer.selectAll('.' + cbId).remove();
- if(!container || !container.showscale) continue;
-
- var cb = cd[0].t.cb = drawColorbar(gd, cbId);
-
- var scl = container.reversescale ?
- flipScale(container.colorscale) :
- container.colorscale;
-
- cb.fillgradient(scl)
- .zrange([container[moduleOpts[i].min], container[moduleOpts[i].max]])
- .options(container.colorbar)();
-
- return;
- }
-};
diff --git a/src/components/colorbar/draw.js b/src/components/colorbar/draw.js
index 6354ab471dd..95b9660b447 100644
--- a/src/components/colorbar/draw.js
+++ b/src/components/colorbar/draw.js
@@ -6,7 +6,6 @@
* LICENSE file in the root directory of this source tree.
*/
-
'use strict';
var d3 = require('d3');
@@ -23,661 +22,699 @@ var Drawing = require('../drawing');
var Color = require('../color');
var Titles = require('../titles');
var svgTextUtils = require('../../lib/svg_text_utils');
-var alignmentConstants = require('../../constants/alignment');
-var LINE_SPACING = alignmentConstants.LINE_SPACING;
-var FROM_TL = alignmentConstants.FROM_TL;
-var FROM_BR = alignmentConstants.FROM_BR;
+var flipScale = require('../colorscale/helpers').flipScale;
var handleAxisDefaults = require('../../plots/cartesian/axis_defaults');
var handleAxisPositionDefaults = require('../../plots/cartesian/position_defaults');
var axisLayoutAttrs = require('../../plots/cartesian/layout_attributes');
-var attributes = require('./attributes');
+var alignmentConstants = require('../../constants/alignment');
+var LINE_SPACING = alignmentConstants.LINE_SPACING;
+var FROM_TL = alignmentConstants.FROM_TL;
+var FROM_BR = alignmentConstants.FROM_BR;
+
var cn = require('./constants').cn;
-module.exports = function draw(gd, id) {
- // opts: options object, containing everything from attributes
- // plus a few others that are the equivalent of the colorbar "data"
- var opts = {};
- for(var k in attributes) {
- opts[k] = null;
- }
- // 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
- opts.fillcolor = null;
- // line.color has the same options as fillcolor
- opts.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)
- opts.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
- opts.filllevels = null;
- // for continuous colorscales: fill with a gradient instead of explicit levels
- // value should be the colorscale [[0, c0], [v1, c1], ..., [1, cEnd]]
- opts.fillgradient = null;
- // when using a gradient, we need the data range specified separately
- opts.zrange = null;
-
- function component() {
- var fullLayout = gd._fullLayout;
- var gs = fullLayout._size;
- if((typeof opts.fillcolor !== 'function') &&
- (typeof opts.line.color !== 'function') &&
- !opts.fillgradient) {
- fullLayout._infolayer.selectAll('g.' + id).remove();
- return;
+function draw(gd) {
+ var fullLayout = gd._fullLayout;
+
+ var colorBars = fullLayout._infolayer
+ .selectAll('g.' + cn.colorbar)
+ .data(makeColorBarData(gd), function(opts) { return opts._id; });
+
+ colorBars.enter().append('g')
+ .attr('class', function(opts) { return opts._id; })
+ .classed(cn.colorbar, true);
+
+ colorBars.each(function(opts) {
+ var g = d3.select(this);
+
+ Lib.ensureSingle(g, 'rect', cn.cbbg);
+ Lib.ensureSingle(g, 'g', cn.cbfills);
+ Lib.ensureSingle(g, 'g', cn.cblines);
+ Lib.ensureSingle(g, 'g', cn.cbaxis, function(s) { s.classed(cn.crisp, true); });
+ Lib.ensureSingle(g, 'g', cn.cbtitleunshift, function(s) { s.append('g').classed(cn.cbtitle, true); });
+ Lib.ensureSingle(g, 'rect', cn.cboutline);
+
+ var done = drawColorBar(g, opts, gd);
+ if(done && done.then) (gd._promises || []).push(done);
+
+ if(gd._context.edits.colorbarPosition) {
+ makeEditable(g, opts, gd);
}
- var zrange = opts.zrange || (d3.extent(((typeof opts.fillcolor === 'function') ?
- opts.fillcolor : opts.line.color).domain()));
- var linelevels = [];
- var filllevels = [];
- var linecolormap = typeof opts.line.color === 'function' ?
- opts.line.color : function() { return opts.line.color; };
- var fillcolormap = typeof opts.fillcolor === 'function' ?
- opts.fillcolor : function() { return opts.fillcolor; };
- var l;
- var i;
-
- var l0 = opts.levels.end + opts.levels.size / 100;
- var ls = opts.levels.size;
- var zr0 = (1.001 * zrange[0] - 0.001 * zrange[1]);
- var zr1 = (1.001 * zrange[1] - 0.001 * zrange[0]);
- for(i = 0; i < 1e5; i++) {
- l = opts.levels.start + i * ls;
- if(ls > 0 ? (l >= l0) : (l <= l0)) break;
- if(l > zr0 && l < zr1) linelevels.push(l);
+ });
+
+ colorBars.exit()
+ .each(function(opts) { Plots.autoMargin(gd, opts._id); })
+ .remove();
+
+ colorBars.order();
+}
+
+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]];
}
+ }
- if(opts.fillgradient) {
- filllevels = [0];
- } else if(typeof opts.fillcolor === 'function') {
- if(opts.filllevels) {
- l0 = opts.filllevels.end + opts.filllevels.size / 100;
- ls = opts.filllevels.size;
- for(i = 0; i < 1e5; i++) {
- l = opts.filllevels.start + i * ls;
- if(ls > 0 ? (l >= l0) : (l <= l0)) break;
- if(l > zrange[0] && l < zrange[1]) filllevels.push(l);
+ for(var i = 0; i < calcdata.length; i++) {
+ var cd = calcdata[i];
+ trace = cd[0].trace;
+ var moduleOpts = trace._module.colorbar;
+
+ if(trace.visible === true && moduleOpts) {
+ var allowsMultiplotCbs = Array.isArray(moduleOpts);
+ var cbOpts = allowsMultiplotCbs ? moduleOpts : [moduleOpts];
+
+ for(var j = 0; j < cbOpts.length; j++) {
+ cbOpt = cbOpts[j];
+ var contName = cbOpt.container;
+ cont = contName ? trace[contName] : trace;
+
+ if(cont && cont.showscale) {
+ opts = initOpts(cont.colorbar);
+ opts._id = 'cb' + trace.uid + (allowsMultiplotCbs && contName ? '-' + contName : '');
+ opts._traceIndex = trace.index;
+ opts._propPrefix = (contName ? contName + '.' : '') + 'colorbar.';
+ calcOpts();
+ out.push(opts);
}
- } else {
- filllevels = linelevels.map(function(v) {
- return v - opts.levels.size / 2;
- });
- filllevels.push(filllevels[filllevels.length - 1] +
- opts.levels.size);
}
- } else if(opts.fillcolor && typeof opts.fillcolor === 'string') {
- // doesn't matter what this value is, with a single value
- // we'll make a single fill rect covering the whole bar
- filllevels = [0];
}
+ }
+
+ for(var k in fullLayout._colorAxes) {
+ cont = fullLayout[k];
- if(opts.levels.size < 0) {
- linelevels.reverse();
- filllevels.reverse();
+ 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);
}
+ }
- // now make a Plotly Axes object to scale with and draw ticks
- // TODO: does not support orientation other than right
-
- // we calculate pixel sizes based on the specified graph size,
- // not the actual (in case something pushed the margins around)
- // which is a little odd but avoids an odd iterative effect
- // when the colorbar itself is pushing the margins.
- // but then the fractional size is calculated based on the
- // actual graph size, so that the axes will size correctly.
- var plotHeight = gs.h;
- var plotWidth = gs.w;
- var thickPx = Math.round(opts.thickness * (opts.thicknessmode === 'fraction' ? plotWidth : 1));
- var thickFrac = thickPx / gs.w;
- var lenPx = Math.round(opts.len * (opts.lenmode === 'fraction' ? plotHeight : 1));
- var lenFrac = lenPx / gs.h;
- var xpadFrac = opts.xpad / gs.w;
- var yExtraPx = (opts.borderwidth + opts.outlinewidth) / 2;
- var ypadFrac = opts.ypad / gs.h;
-
- // x positioning: do it initially just for left anchor,
- // then fix at the end (since we don't know the width yet)
- var xLeft = Math.round(opts.x * gs.w + opts.xpad);
- // for dragging... this is getting a little muddled...
- var xLeftFrac = opts.x - thickFrac * ({middle: 0.5, right: 1}[opts.xanchor]||0);
-
- // y positioning we can do correctly from the start
- var yBottomFrac = opts.y + lenFrac * (({top: -0.5, bottom: 0.5}[opts.yanchor] || 0) - 0.5);
- var yBottomPx = Math.round(gs.h * (1 - yBottomFrac));
- var yTopPx = yBottomPx - lenPx;
-
- var titleEl;
-
- var cbAxisIn = {
- type: 'linear',
- range: zrange,
- tickmode: opts.tickmode,
- nticks: opts.nticks,
- tick0: opts.tick0,
- dtick: opts.dtick,
- tickvals: opts.tickvals,
- ticktext: opts.ticktext,
- ticks: opts.ticks,
- ticklen: opts.ticklen,
- tickwidth: opts.tickwidth,
- tickcolor: opts.tickcolor,
- showticklabels: opts.showticklabels,
- tickfont: opts.tickfont,
- tickangle: opts.tickangle,
- tickformat: opts.tickformat,
- exponentformat: opts.exponentformat,
- separatethousands: opts.separatethousands,
- showexponent: opts.showexponent,
- showtickprefix: opts.showtickprefix,
- tickprefix: opts.tickprefix,
- showticksuffix: opts.showticksuffix,
- ticksuffix: opts.ticksuffix,
- title: opts.title,
- showline: true,
- anchor: 'free',
- side: 'right',
- position: 1
- };
- var cbAxisOut = {
- type: 'linear',
- _id: 'y' + id
- };
- var axisOptions = {
- letter: 'y',
- font: fullLayout.font,
- noHover: true,
- noTickson: true,
- calendar: fullLayout.calendar // not really necessary (yet?)
- };
+ return out;
+}
+
+function drawColorBar(g, opts, gd) {
+ var fullLayout = gd._fullLayout;
+ var gs = fullLayout._size;
+
+ var fillColor = opts._fillcolor;
+ var line = opts._line;
+ var title = opts.title;
+ var titleSide = title.side;
+
+ var zrange = opts._zrange ||
+ d3.extent((typeof fillColor === 'function' ? fillColor : line.color).domain());
+
+ var lineColormap = typeof line.color === 'function' ?
+ line.color :
+ function() { return line.color; };
+ var fillColormap = typeof fillColor === 'function' ?
+ fillColor :
+ function() { return fillColor; };
+
+ var levelsIn = opts._levels;
+ var levelsOut = calcLevels(gd, opts, zrange);
+ var fillLevels = levelsOut.fill;
+ var lineLevels = levelsOut.line;
+
+ // we calculate pixel sizes based on the specified graph size,
+ // not the actual (in case something pushed the margins around)
+ // which is a little odd but avoids an odd iterative effect
+ // when the colorbar itself is pushing the margins.
+ // but then the fractional size is calculated based on the
+ // actual graph size, so that the axes will size correctly.
+ var thickPx = Math.round(opts.thickness * (opts.thicknessmode === 'fraction' ? gs.w : 1));
+ var thickFrac = thickPx / gs.w;
+ var lenPx = Math.round(opts.len * (opts.lenmode === 'fraction' ? gs.h : 1));
+ var lenFrac = lenPx / gs.h;
+ var xpadFrac = opts.xpad / gs.w;
+ var yExtraPx = (opts.borderwidth + opts.outlinewidth) / 2;
+ var ypadFrac = opts.ypad / gs.h;
+
+ // x positioning: do it initially just for left anchor,
+ // then fix at the end (since we don't know the width yet)
+ var xLeft = Math.round(opts.x * gs.w + opts.xpad);
+ // for dragging... this is getting a little muddled...
+ var xLeftFrac = opts.x - thickFrac * ({middle: 0.5, right: 1}[opts.xanchor] || 0);
+
+ // y positioning we can do correctly from the start
+ var yBottomFrac = opts.y + lenFrac * (({top: -0.5, bottom: 0.5}[opts.yanchor] || 0) - 0.5);
+ var yBottomPx = Math.round(gs.h * (1 - yBottomFrac));
+ var yTopPx = yBottomPx - lenPx;
+
+ // stash a few things for makeEditable
+ opts._lenFrac = lenFrac;
+ opts._thickFrac = thickFrac;
+ opts._xLeftFrac = xLeftFrac;
+ opts._yBottomFrac = yBottomFrac;
+
+ var ax = mockColorBarAxis(gd, opts, zrange);
+
+ // position can't go in through supplyDefaults
+ // because that restricts it to [0,1]
+ ax.position = opts.x + xpadFrac + thickFrac;
+
+ if(['top', 'bottom'].indexOf(titleSide) !== -1) {
+ ax.title.side = titleSide;
+ ax.titlex = opts.x + xpadFrac;
+ ax.titley = yBottomFrac + (title.side === 'top' ? lenFrac - ypadFrac : ypadFrac);
+ }
- // Coerce w.r.t. Axes layoutAttributes:
- // re-use axes.js logic without updating _fullData
- function coerce(attr, dflt) {
- return Lib.coerce(cbAxisIn, cbAxisOut, axisLayoutAttrs, attr, dflt);
+ if(line.color && opts.tickmode === 'auto') {
+ ax.tickmode = 'linear';
+ ax.tick0 = levelsIn.start;
+ var dtick = levelsIn.size;
+ // expand if too many contours, so we don't get too many ticks
+ var autoNtick = Lib.constrain((yBottomPx - yTopPx) / 50, 4, 15) + 1;
+ var dtFactor = (zrange[1] - zrange[0]) / ((opts.nticks || autoNtick) * dtick);
+ if(dtFactor > 1) {
+ var dtexp = Math.pow(10, Math.floor(Math.log(dtFactor) / Math.LN10));
+ dtick *= dtexp * Lib.roundUp(dtFactor / dtexp, [2, 5, 10]);
+ // if the contours are at round multiples, reset tick0
+ // so they're still at round multiples. Otherwise,
+ // keep the first label on the first contour level
+ if((Math.abs(levelsIn.start) / levelsIn.size + 1e-6) % 1 < 2e-6) {
+ ax.tick0 = 0;
+ }
}
+ ax.dtick = dtick;
+ }
- // Prepare the Plotly axis object
- handleAxisDefaults(cbAxisIn, cbAxisOut, coerce, axisOptions, fullLayout);
- handleAxisPositionDefaults(cbAxisIn, cbAxisOut, coerce, axisOptions);
+ // set domain after init, because we may want to
+ // allow it outside [0,1]
+ ax.domain = [
+ yBottomFrac + ypadFrac,
+ yBottomFrac + lenFrac - ypadFrac
+ ];
- // position can't go in through supplyDefaults
- // because that restricts it to [0,1]
- cbAxisOut.position = opts.x + xpadFrac + thickFrac;
+ ax.setScale();
- // save for other callers to access this axis
- component.axis = cbAxisOut;
+ g.attr('transform', 'translate(' + Math.round(gs.l) + ',' + Math.round(gs.t) + ')');
- if(['top', 'bottom'].indexOf(opts.title.side) !== -1) {
- cbAxisOut.title.side = opts.title.side;
- cbAxisOut.titlex = opts.x + xpadFrac;
- cbAxisOut.titley = yBottomFrac +
- (opts.title.side === 'top' ? lenFrac - ypadFrac : ypadFrac);
- }
+ var titleCont = g.select('.' + cn.cbtitleunshift)
+ .attr('transform', 'translate(-' + Math.round(gs.l) + ',-' + Math.round(gs.t) + ')');
- if(opts.line.color && opts.tickmode === 'auto') {
- cbAxisOut.tickmode = 'linear';
- cbAxisOut.tick0 = opts.levels.start;
- var dtick = opts.levels.size;
- // expand if too many contours, so we don't get too many ticks
- var autoNtick = Lib.constrain((yBottomPx - yTopPx) / 50, 4, 15) + 1;
- var dtFactor = (zrange[1] - zrange[0]) / ((opts.nticks || autoNtick) * dtick);
- if(dtFactor > 1) {
- var dtexp = Math.pow(10, Math.floor(
- Math.log(dtFactor) / Math.LN10));
- dtick *= dtexp * Lib.roundUp(dtFactor / dtexp, [2, 5, 10]);
- // if the contours are at round multiples, reset tick0
- // so they're still at round multiples. Otherwise,
- // keep the first label on the first contour level
- if((Math.abs(opts.levels.start) /
- opts.levels.size + 1e-6) % 1 < 2e-6) {
- cbAxisOut.tick0 = 0;
- }
- }
- cbAxisOut.dtick = dtick;
- }
+ var axLayer = g.select('.' + cn.cbaxis);
+ var titleEl;
+ var titleHeight = 0;
- // set domain after init, because we may want to
- // allow it outside [0,1]
- cbAxisOut.domain = [
- yBottomFrac + ypadFrac,
- yBottomFrac + lenFrac - ypadFrac
- ];
- cbAxisOut.setScale();
-
- // now draw the elements
- var container = Lib.ensureSingle(fullLayout._infolayer, 'g', id, function(s) {
- s.classed(cn.colorbar, true)
- .each(function() {
- var s = d3.select(this);
- s.append('rect').classed(cn.cbbg, true);
- s.append('g').classed(cn.cbfills, true);
- s.append('g').classed(cn.cblines, true);
- s.append('g').classed(cn.cbaxis, true).classed(cn.crisp, true);
- s.append('g').classed(cn.cbtitleunshift, true)
- .append('g').classed(cn.cbtitle, true);
- s.append('rect').classed(cn.cboutline, true);
- s.select('.cbtitle').datum(0);
- });
- });
+ function drawTitle(titleClass, titleOpts) {
+ var dfltTitleOpts = {
+ propContainer: ax,
+ propName: opts._propPrefix + 'title',
+ traceIndex: opts._traceIndex,
+ placeholder: fullLayout._dfltTitle.colorbar,
+ containerGroup: g.select('.' + cn.cbtitle)
+ };
- container.attr('transform', 'translate(' + Math.round(gs.l) +
- ',' + Math.round(gs.t) + ')');
- // TODO: this opposite transform is a hack until we make it
- // more rational which items get this offset
- var titleCont = container.select('.cbtitleunshift')
- .attr('transform', 'translate(-' +
- Math.round(gs.l) + ',-' +
- Math.round(gs.t) + ')');
+ // this class-to-rotate thing with convertToTspans is
+ // getting hackier and hackier... delete groups with the
+ // wrong class (in case earlier the colorbar was drawn on
+ // a different side, I think?)
+ var otherClass = titleClass.charAt(0) === 'h' ?
+ titleClass.substr(1) :
+ 'h' + titleClass;
+ g.selectAll('.' + otherClass + ',.' + otherClass + '-math-group').remove();
- var axisLayer = container.select('.cbaxis');
+ Titles.draw(gd, titleClass, extendFlat(dfltTitleOpts, titleOpts || {}));
+ }
- var titleHeight = 0;
- if(['top', 'bottom'].indexOf(opts.title.side) !== -1) {
+ function drawDummyTitle() {
+ if(['top', 'bottom'].indexOf(titleSide) !== -1) {
// draw the title so we know how much room it needs
// when we squish the axis. This one only applies to
// top or bottom titles, not right side.
var x = gs.l + (opts.x + xpadFrac) * gs.w;
- var fontSize = cbAxisOut.title.font.size;
+ var fontSize = ax.title.font.size;
var y;
- if(opts.title.side === 'top') {
+ if(titleSide === 'top') {
y = (1 - (yBottomFrac + lenFrac - ypadFrac)) * gs.h +
gs.t + 3 + fontSize * 0.75;
} else {
y = (1 - (yBottomFrac + ypadFrac)) * gs.h +
gs.t - 3 - fontSize * 0.25;
}
- drawTitle(cbAxisOut._id + 'title', {
+ drawTitle(ax._id + 'title', {
attributes: {x: x, y: y, 'text-anchor': 'start'}
});
}
+ }
- function drawAxis() {
- if(['top', 'bottom'].indexOf(opts.title.side) !== -1) {
- // squish the axis top to make room for the title
- var titleGroup = container.select('.cbtitle');
- var titleText = titleGroup.select('text');
- var titleTrans = [-opts.outlinewidth / 2, opts.outlinewidth / 2];
- var mathJaxNode = titleGroup
- .select('.h' + cbAxisOut._id + 'title-math-group')
- .node();
- var lineSize = 15.6;
- if(titleText.node()) {
- lineSize =
- parseInt(titleText.node().style.fontSize, 10) * LINE_SPACING;
- }
- if(mathJaxNode) {
- titleHeight = Drawing.bBox(mathJaxNode).height;
- if(titleHeight > lineSize) {
- // not entirely sure how mathjax is doing
- // vertical alignment, but this seems to work.
- titleTrans[1] -= (titleHeight - lineSize) / 2;
- }
- } else if(titleText.node() &&
- !titleText.classed(cn.jsPlaceholder)) {
- titleHeight = Drawing.bBox(titleText.node()).height;
- }
- if(titleHeight) {
- // buffer btwn colorbar and title
- // TODO: configurable
- titleHeight += 5;
-
- if(opts.title.side === 'top') {
- cbAxisOut.domain[1] -= titleHeight / gs.h;
- titleTrans[1] *= -1;
- } else {
- cbAxisOut.domain[0] += titleHeight / gs.h;
- var nlines = svgTextUtils.lineCount(titleText);
- titleTrans[1] += (1 - nlines) * lineSize;
- }
-
- titleGroup.attr('transform',
- 'translate(' + titleTrans + ')');
-
- cbAxisOut.setScale();
+ function drawCbTitle() {
+ if(['top', 'bottom'].indexOf(titleSide) === -1) {
+ var fontSize = ax.title.font.size;
+ var y = ax._offset + ax._length / 2;
+ var x = gs.l + (ax.position || 0) * gs.w + ((ax.side === 'right') ?
+ 10 + fontSize * ((ax.showticklabels ? 1 : 0.5)) :
+ -10 - fontSize * ((ax.showticklabels ? 0.5 : 0)));
+
+ // the 'h' + is a hack to get around the fact that
+ // convertToTspans rotates any 'y...' class by 90 degrees.
+ // TODO: find a better way to control this.
+ drawTitle('h' + ax._id + 'title', {
+ avoid: {
+ selection: d3.select(gd).selectAll('g.' + ax._id + 'tick'),
+ side: titleSide,
+ offsetLeft: gs.l,
+ offsetTop: 0,
+ maxShift: fullLayout.width
+ },
+ attributes: {x: x, y: y, 'text-anchor': 'middle'},
+ transform: {rotate: '-90', offset: 0}
+ });
+ }
+ }
+
+ function drawAxis() {
+ if(['top', 'bottom'].indexOf(titleSide) !== -1) {
+ // squish the axis top to make room for the title
+ var titleGroup = g.select('.' + cn.cbtitle);
+ var titleText = titleGroup.select('text');
+ var titleTrans = [-opts.outlinewidth / 2, opts.outlinewidth / 2];
+ var mathJaxNode = titleGroup
+ .select('.h' + ax._id + 'title-math-group')
+ .node();
+ var lineSize = 15.6;
+ if(titleText.node()) {
+ lineSize = parseInt(titleText.node().style.fontSize, 10) * LINE_SPACING;
+ }
+ if(mathJaxNode) {
+ titleHeight = Drawing.bBox(mathJaxNode).height;
+ if(titleHeight > lineSize) {
+ // not entirely sure how mathjax is doing
+ // vertical alignment, but this seems to work.
+ titleTrans[1] -= (titleHeight - lineSize) / 2;
}
+ } else if(titleText.node() && !titleText.classed(cn.jsPlaceholder)) {
+ titleHeight = Drawing.bBox(titleText.node()).height;
}
-
- container.selectAll('.cbfills,.cblines')
- .attr('transform', 'translate(0,' +
- Math.round(gs.h * (1 - cbAxisOut.domain[1])) + ')');
-
- axisLayer.attr('transform', 'translate(0,' + Math.round(-gs.t) + ')');
-
- var fills = container.select('.cbfills')
- .selectAll('rect.cbfill')
- .data(filllevels);
- fills.enter().append('rect')
- .classed(cn.cbfill, true)
- .style('stroke', 'none');
- fills.exit().remove();
-
- var zBounds = zrange
- .map(cbAxisOut.c2p)
- .map(Math.round)
- .sort(function(a, b) { return a - b; });
-
- fills.each(function(d, i) {
- var z = [
- (i === 0) ? zrange[0] :
- (filllevels[i] + filllevels[i - 1]) / 2,
- (i === filllevels.length - 1) ? zrange[1] :
- (filllevels[i] + filllevels[i + 1]) / 2
- ]
- .map(cbAxisOut.c2p)
- .map(Math.round);
-
- // offset the side adjoining the next rectangle so they
- // overlap, to prevent antialiasing gaps
- z[1] = Lib.constrain(z[1] + (z[1] > z[0]) ? 1 : -1, zBounds[0], zBounds[1]);
-
- // Colorbar cannot currently support opacities so we
- // use an opaque fill even when alpha channels present
- var fillEl = d3.select(this).attr({
- x: xLeft,
- width: Math.max(thickPx, 2),
- y: d3.min(z),
- height: Math.max(d3.max(z) - d3.min(z), 2),
- });
-
- if(opts.fillgradient) {
- Drawing.gradient(fillEl, gd, id, 'vertical',
- opts.fillgradient, 'fill');
+ if(titleHeight) {
+ // buffer btwn colorbar and title
+ // TODO: configurable
+ titleHeight += 5;
+
+ if(titleSide === 'top') {
+ ax.domain[1] -= titleHeight / gs.h;
+ titleTrans[1] *= -1;
} else {
- // Tinycolor can't handle exponents and
- // at this scale, removing it makes no difference.
- var colorString = fillcolormap(d).replace('e-', '');
- fillEl.attr('fill', tinycolor(colorString).toHexString());
+ ax.domain[0] += titleHeight / gs.h;
+ var nlines = svgTextUtils.lineCount(titleText);
+ titleTrans[1] += (1 - nlines) * lineSize;
}
- });
- var lines = container.select('.cblines')
- .selectAll('path.cbline')
- .data(opts.line.color && opts.line.width ?
- linelevels : []);
- lines.enter().append('path')
- .classed(cn.cbline, true);
- lines.exit().remove();
- lines.each(function(d) {
- d3.select(this)
- .attr('d', 'M' + xLeft + ',' +
- (Math.round(cbAxisOut.c2p(d)) + (opts.line.width / 2) % 1) +
- 'h' + thickPx)
- .call(Drawing.lineGroupStyle,
- opts.line.width, linecolormap(d), opts.line.dash);
- });
-
- // force full redraw of labels and ticks
- axisLayer.selectAll('g.' + cbAxisOut._id + 'tick,path').remove();
-
- // separate out axis and title drawing,
- // so we don't need such complicated logic in Titles.draw
- // if title is on the top or bottom, we've already drawn it
- // this title call only handles side=right
- return Lib.syncOrAsync([
- function() {
- var shift = xLeft + thickPx +
- (opts.outlinewidth || 0) / 2 - (opts.ticks === 'outside' ? 1 : 0);
-
- var vals = Axes.calcTicks(cbAxisOut);
- var transFn = Axes.makeTransFn(cbAxisOut);
- var tickSign = Axes.getTickSigns(cbAxisOut)[2];
-
- Axes.drawTicks(gd, cbAxisOut, {
- vals: cbAxisOut.ticks === 'inside' ? Axes.clipEnds(cbAxisOut, vals) : vals,
- layer: axisLayer,
- path: Axes.makeTickPath(cbAxisOut, shift, tickSign),
- transFn: transFn
- });
-
- return Axes.drawLabels(gd, cbAxisOut, {
- vals: vals,
- layer: axisLayer,
- transFn: transFn,
- labelFns: Axes.makeLabelFns(cbAxisOut, shift)
- });
- },
- function() {
- if(['top', 'bottom'].indexOf(opts.title.side) === -1) {
- var fontSize = cbAxisOut.title.font.size;
- var y = cbAxisOut._offset + cbAxisOut._length / 2;
- var x = gs.l + (cbAxisOut.position || 0) * gs.w + ((cbAxisOut.side === 'right') ?
- 10 + fontSize * ((cbAxisOut.showticklabels ? 1 : 0.5)) :
- -10 - fontSize * ((cbAxisOut.showticklabels ? 0.5 : 0)));
-
- // the 'h' + is a hack to get around the fact that
- // convertToTspans rotates any 'y...' class by 90 degrees.
- // TODO: find a better way to control this.
- drawTitle('h' + cbAxisOut._id + 'title', {
- avoid: {
- selection: d3.select(gd).selectAll('g.' + cbAxisOut._id + 'tick'),
- side: opts.title.side,
- offsetLeft: gs.l,
- offsetTop: 0,
- maxShift: fullLayout.width
- },
- attributes: {x: x, y: y, 'text-anchor': 'middle'},
- transform: {rotate: '-90', offset: 0}
- });
- }
- }]);
+ titleGroup.attr('transform', 'translate(' + titleTrans + ')');
+ ax.setScale();
+ }
}
- function drawTitle(titleClass, titleOpts) {
- var dfltTitleOpts = {
- propContainer: cbAxisOut,
- propName: getPropName('title'),
- traceIndex: getTrace().index,
- placeholder: fullLayout._dfltTitle.colorbar,
- containerGroup: container.select('.cbtitle')
- };
-
- // this class-to-rotate thing with convertToTspans is
- // getting hackier and hackier... delete groups with the
- // wrong class (in case earlier the colorbar was drawn on
- // a different side, I think?)
- var otherClass = titleClass.charAt(0) === 'h' ?
- titleClass.substr(1) : ('h' + titleClass);
- container.selectAll('.' + otherClass + ',.' + otherClass + '-math-group')
- .remove();
-
- Titles.draw(gd, titleClass,
- extendFlat(dfltTitleOpts, titleOpts || {}));
- }
+ g.selectAll('.' + cn.cbfills + ',.' + cn.cblines)
+ .attr('transform', 'translate(0,' + Math.round(gs.h * (1 - ax.domain[1])) + ')');
- function positionCB() {
- // wait for the axis & title to finish rendering before
- // continuing positioning
- // TODO: why are we redrawing multiple times now with this?
- // I guess autoMargin doesn't like being post-promise?
- var innerWidth = thickPx + opts.outlinewidth / 2 +
- Drawing.bBox(axisLayer.node()).width;
- titleEl = titleCont.select('text');
- if(titleEl.node() && !titleEl.classed(cn.jsPlaceholder)) {
- var mathJaxNode = titleCont
- .select('.h' + cbAxisOut._id + 'title-math-group')
- .node();
- var titleWidth;
- if(mathJaxNode &&
- ['top', 'bottom'].indexOf(opts.title.side) !== -1) {
- titleWidth = Drawing.bBox(mathJaxNode).width;
- } else {
- // note: the formula below works for all title sides,
- // (except for top/bottom mathjax, above)
- // but the weird gs.l is because the titleunshift
- // transform gets removed by Drawing.bBox
- titleWidth =
- Drawing.bBox(titleCont.node()).right -
- xLeft - gs.l;
- }
- innerWidth = Math.max(innerWidth, titleWidth);
- }
+ axLayer.attr('transform', 'translate(0,' + Math.round(-gs.t) + ')');
+
+ var fills = g.select('.' + cn.cbfills)
+ .selectAll('rect.' + cn.cbfill)
+ .data(fillLevels);
+ fills.enter().append('rect')
+ .classed(cn.cbfill, true)
+ .style('stroke', 'none');
+ fills.exit().remove();
+
+ var zBounds = zrange
+ .map(ax.c2p)
+ .map(Math.round)
+ .sort(function(a, b) { return a - b; });
- var outerwidth = 2 * opts.xpad + innerWidth +
- opts.borderwidth + opts.outlinewidth / 2;
- var outerheight = yBottomPx - yTopPx;
-
- container.select('.cbbg').attr({
- x: xLeft - opts.xpad -
- (opts.borderwidth + opts.outlinewidth) / 2,
- y: yTopPx - yExtraPx,
- width: Math.max(outerwidth, 2),
- height: Math.max(outerheight + 2 * yExtraPx, 2)
- })
- .call(Color.fill, opts.bgcolor)
- .call(Color.stroke, opts.bordercolor)
- .style({'stroke-width': opts.borderwidth});
-
- container.selectAll('.cboutline').attr({
+ fills.each(function(d, i) {
+ var z = [
+ (i === 0) ? zrange[0] : (fillLevels[i] + fillLevels[i - 1]) / 2,
+ (i === fillLevels.length - 1) ? zrange[1] : (fillLevels[i] + fillLevels[i + 1]) / 2
+ ]
+ .map(ax.c2p)
+ .map(Math.round);
+
+ // offset the side adjoining the next rectangle so they
+ // overlap, to prevent antialiasing gaps
+ z[1] = Lib.constrain(z[1] + (z[1] > z[0]) ? 1 : -1, zBounds[0], zBounds[1]);
+
+
+ // Colorbar cannot currently support opacities so we
+ // use an opaque fill even when alpha channels present
+ var fillEl = d3.select(this).attr({
x: xLeft,
- y: yTopPx + opts.ypad +
- (opts.title.side === 'top' ? titleHeight : 0),
width: Math.max(thickPx, 2),
- height: Math.max(outerheight - 2 * opts.ypad - titleHeight, 2)
- })
- .call(Color.stroke, opts.outlinecolor)
- .style({
- fill: 'None',
- 'stroke-width': opts.outlinewidth
+ y: d3.min(z),
+ height: Math.max(d3.max(z) - d3.min(z), 2),
});
- // fix positioning for xanchor!='left'
- var xoffset = ({center: 0.5, right: 1}[opts.xanchor] || 0) *
- outerwidth;
- container.attr('transform',
- 'translate(' + (gs.l - xoffset) + ',' + gs.t + ')');
-
- // auto margin adjustment
- var marginOpts = {};
- var tFrac = FROM_TL[opts.yanchor];
- var bFrac = FROM_BR[opts.yanchor];
- if(opts.lenmode === 'pixels') {
- marginOpts.y = opts.y;
- marginOpts.t = outerheight * tFrac;
- marginOpts.b = outerheight * bFrac;
+ if(opts._fillgradient) {
+ Drawing.gradient(fillEl, gd, opts._id, 'vertical', opts._fillgradient, 'fill');
} else {
- marginOpts.t = marginOpts.b = 0;
- marginOpts.yt = opts.y + opts.len * tFrac;
- marginOpts.yb = opts.y - opts.len * bFrac;
+ // tinycolor can't handle exponents and
+ // at this scale, removing it makes no difference.
+ var colorString = fillColormap(d).replace('e-', '');
+ fillEl.attr('fill', tinycolor(colorString).toHexString());
}
+ });
+
+ var lines = g.select('.' + cn.cblines)
+ .selectAll('path.' + cn.cbline)
+ .data(line.color && line.width ? lineLevels : []);
+ lines.enter().append('path')
+ .classed(cn.cbline, true);
+ lines.exit().remove();
+ lines.each(function(d) {
+ d3.select(this)
+ .attr('d', 'M' + xLeft + ',' +
+ (Math.round(ax.c2p(d)) + (line.width / 2) % 1) + 'h' + thickPx)
+ .call(Drawing.lineGroupStyle, line.width, lineColormap(d), line.dash);
+ });
+
+ // force full redraw of labels and ticks
+ axLayer.selectAll('g.' + ax._id + 'tick,path').remove();
+
+ var shift = xLeft + thickPx +
+ (opts.outlinewidth || 0) / 2 - (opts.ticks === 'outside' ? 1 : 0);
+
+ var vals = Axes.calcTicks(ax);
+ var transFn = Axes.makeTransFn(ax);
+ var tickSign = Axes.getTickSigns(ax)[2];
+
+ Axes.drawTicks(gd, ax, {
+ vals: ax.ticks === 'inside' ? Axes.clipEnds(ax, vals) : vals,
+ layer: axLayer,
+ path: Axes.makeTickPath(ax, shift, tickSign),
+ transFn: transFn
+ });
+
+ return Axes.drawLabels(gd, ax, {
+ vals: vals,
+ layer: axLayer,
+ transFn: transFn,
+ labelFns: Axes.makeLabelFns(ax, shift)
+ });
+ }
- var lFrac = FROM_TL[opts.xanchor];
- var rFrac = FROM_BR[opts.xanchor];
- if(opts.thicknessmode === 'pixels') {
- marginOpts.x = opts.x;
- marginOpts.l = outerwidth * lFrac;
- marginOpts.r = outerwidth * rFrac;
+ // wait for the axis & title to finish rendering before
+ // continuing positioning
+ // TODO: why are we redrawing multiple times now with this?
+ // I guess autoMargin doesn't like being post-promise?
+ function positionCB() {
+ var innerWidth = thickPx + opts.outlinewidth / 2 + Drawing.bBox(axLayer.node()).width;
+ titleEl = titleCont.select('text');
+
+ if(titleEl.node() && !titleEl.classed(cn.jsPlaceholder)) {
+ var mathJaxNode = titleCont.select('.h' + ax._id + 'title-math-group').node();
+ var titleWidth;
+ if(mathJaxNode && ['top', 'bottom'].indexOf(titleSide) !== -1) {
+ titleWidth = Drawing.bBox(mathJaxNode).width;
} else {
- var extraThickness = outerwidth - thickPx;
- marginOpts.l = extraThickness * lFrac;
- marginOpts.r = extraThickness * rFrac;
- marginOpts.xl = opts.x - opts.thickness * lFrac;
- marginOpts.xr = opts.x + opts.thickness * rFrac;
+ // note: the formula below works for all title sides,
+ // (except for top/bottom mathjax, above)
+ // but the weird gs.l is because the titleunshift
+ // transform gets removed by Drawing.bBox
+ titleWidth = Drawing.bBox(titleCont.node()).right - xLeft - gs.l;
}
- Plots.autoMargin(gd, id, marginOpts);
+ innerWidth = Math.max(innerWidth, titleWidth);
}
- var cbDone = Lib.syncOrAsync([
- Plots.previousPromises,
- drawAxis,
- Plots.previousPromises,
- positionCB
- ], gd);
+ var outerwidth = 2 * opts.xpad + innerWidth + opts.borderwidth + opts.outlinewidth / 2;
+ var outerheight = yBottomPx - yTopPx;
+
+ g.select('.' + cn.cbbg).attr({
+ x: xLeft - opts.xpad - (opts.borderwidth + opts.outlinewidth) / 2,
+ y: yTopPx - yExtraPx,
+ width: Math.max(outerwidth, 2),
+ height: Math.max(outerheight + 2 * yExtraPx, 2)
+ })
+ .call(Color.fill, opts.bgcolor)
+ .call(Color.stroke, opts.bordercolor)
+ .style('stroke-width', opts.borderwidth);
+
+ g.selectAll('.' + cn.cboutline).attr({
+ x: xLeft,
+ y: yTopPx + opts.ypad + (titleSide === 'top' ? titleHeight : 0),
+ width: Math.max(thickPx, 2),
+ height: Math.max(outerheight - 2 * opts.ypad - titleHeight, 2)
+ })
+ .call(Color.stroke, opts.outlinecolor)
+ .style({
+ fill: 'none',
+ 'stroke-width': opts.outlinewidth
+ });
- if(cbDone && cbDone.then) (gd._promises || []).push(cbDone);
+ // fix positioning for xanchor!='left'
+ var xoffset = ({center: 0.5, right: 1}[opts.xanchor] || 0) * outerwidth;
+ g.attr('transform', 'translate(' + (gs.l - xoffset) + ',' + gs.t + ')');
+
+ // auto margin adjustment
+ var marginOpts = {};
+ var tFrac = FROM_TL[opts.yanchor];
+ var bFrac = FROM_BR[opts.yanchor];
+ if(opts.lenmode === 'pixels') {
+ marginOpts.y = opts.y;
+ marginOpts.t = outerheight * tFrac;
+ marginOpts.b = outerheight * bFrac;
+ } else {
+ marginOpts.t = marginOpts.b = 0;
+ marginOpts.yt = opts.y + opts.len * tFrac;
+ marginOpts.yb = opts.y - opts.len * bFrac;
+ }
- // dragging...
- if(gd._context.edits.colorbarPosition) {
- var t0,
- xf,
- yf;
-
- dragElement.init({
- element: container.node(),
- gd: gd,
- prepFn: function() {
- t0 = container.attr('transform');
- setCursor(container);
- },
- moveFn: function(dx, dy) {
- container.attr('transform',
- t0 + ' ' + 'translate(' + dx + ',' + dy + ')');
-
- xf = dragElement.align(xLeftFrac + (dx / gs.w), thickFrac,
- 0, 1, opts.xanchor);
- yf = dragElement.align(yBottomFrac - (dy / gs.h), lenFrac,
- 0, 1, opts.yanchor);
-
- var csr = dragElement.getCursor(xf, yf,
- opts.xanchor, opts.yanchor);
- setCursor(container, csr);
- },
- doneFn: function() {
- setCursor(container);
-
- if(xf !== undefined && yf !== undefined) {
- var update = {};
- update[getPropName('x')] = xf;
- update[getPropName('y')] = yf;
- Registry.call('_guiRestyle', gd, update, getTrace().index);
- }
- }
- });
+ var lFrac = FROM_TL[opts.xanchor];
+ var rFrac = FROM_BR[opts.xanchor];
+ if(opts.thicknessmode === 'pixels') {
+ marginOpts.x = opts.x;
+ marginOpts.l = outerwidth * lFrac;
+ marginOpts.r = outerwidth * rFrac;
+ } else {
+ var extraThickness = outerwidth - thickPx;
+ marginOpts.l = extraThickness * lFrac;
+ marginOpts.r = extraThickness * rFrac;
+ marginOpts.xl = opts.x - opts.thickness * lFrac;
+ marginOpts.xr = opts.x + opts.thickness * rFrac;
}
- return cbDone;
+
+ Plots.autoMargin(gd, opts._id, marginOpts);
}
- function getTrace() {
- var idNum = id.substr(2);
- for(var i = 0; i < gd._fullData.length; i++) {
- var trace = gd._fullData[i];
- if(trace.uid === idNum) return trace;
+ return Lib.syncOrAsync([
+ Plots.previousPromises,
+ drawDummyTitle,
+ drawAxis,
+ drawCbTitle,
+ Plots.previousPromises,
+ positionCB
+ ], gd);
+}
+
+function makeEditable(g, opts, gd) {
+ var fullLayout = gd._fullLayout;
+ var gs = fullLayout._size;
+ var t0, xf, yf;
+
+ dragElement.init({
+ element: g.node(),
+ gd: gd,
+ prepFn: function() {
+ t0 = g.attr('transform');
+ setCursor(g);
+ },
+ moveFn: function(dx, dy) {
+ g.attr('transform', t0 + ' ' + 'translate(' + dx + ',' + dy + ')');
+
+ xf = dragElement.align(opts._xLeftFrac + (dx / gs.w), opts._thickFrac,
+ 0, 1, opts.xanchor);
+ yf = dragElement.align(opts._yBottomFrac - (dy / gs.h), opts._lenFrac,
+ 0, 1, opts.yanchor);
+
+ var csr = dragElement.getCursor(xf, yf, opts.xanchor, opts.yanchor);
+ setCursor(g, csr);
+ },
+ doneFn: function() {
+ setCursor(g);
+
+ if(xf !== undefined && yf !== undefined) {
+ var update = {};
+ update[opts._propPrefix + 'x'] = xf;
+ update[opts._propPrefix + 'y'] = yf;
+ if(opts._traceIndex !== undefined) {
+ Registry.call('_guiRestyle', gd, update, opts._traceIndex);
+ } else {
+ Registry.call('_guiRelayout', gd, update);
+ }
+ }
}
+ });
+}
+
+function calcLevels(gd, opts, zrange) {
+ var levelsIn = opts._levels;
+ var lineLevels = [];
+ var fillLevels = [];
+ var l;
+ var i;
+
+ var l0 = levelsIn.end + levelsIn.size / 100;
+ var ls = levelsIn.size;
+ var zr0 = (1.001 * zrange[0] - 0.001 * zrange[1]);
+ var zr1 = (1.001 * zrange[1] - 0.001 * zrange[0]);
+
+ for(i = 0; i < 1e5; i++) {
+ l = levelsIn.start + i * ls;
+ if(ls > 0 ? (l >= l0) : (l <= l0)) break;
+ if(l > zr0 && l < zr1) lineLevels.push(l);
}
- function getPropName(suffix) {
- var trace = getTrace();
- var propName = 'colorbar.';
- var containerName = trace._module.colorbar.container;
- if(containerName) propName = containerName + '.' + propName;
- return propName + suffix;
+ if(opts._fillgradient) {
+ fillLevels = [0];
+ } else if(typeof opts._fillcolor === 'function') {
+ var fillLevelsIn = opts._filllevels;
+
+ if(fillLevelsIn) {
+ l0 = fillLevelsIn.end + fillLevelsIn.size / 100;
+ ls = fillLevelsIn.size;
+ for(i = 0; i < 1e5; i++) {
+ l = fillLevelsIn.start + i * ls;
+ if(ls > 0 ? (l >= l0) : (l <= l0)) break;
+ if(l > zrange[0] && l < zrange[1]) fillLevels.push(l);
+ }
+ } else {
+ fillLevels = lineLevels.map(function(v) {
+ return v - levelsIn.size / 2;
+ });
+ fillLevels.push(fillLevels[fillLevels.length - 1] + levelsIn.size);
+ }
+ } else if(opts._fillcolor && typeof opts._fillcolor === 'string') {
+ // doesn't matter what this value is, with a single value
+ // we'll make a single fill rect covering the whole bar
+ fillLevels = [0];
}
- // setter/getters for every item defined in opts
- Object.keys(opts).forEach(function(name) {
- component[name] = function(v) {
- // getter
- if(!arguments.length) return opts[name];
+ if(levelsIn.size < 0) {
+ lineLevels.reverse();
+ fillLevels.reverse();
+ }
- // setter - for multi-part properties,
- // set only the parts that are provided
- opts[name] = Lib.isPlainObject(opts[name]) ?
- Lib.extendFlat(opts[name], v) :
- v;
+ return {line: lineLevels, fill: fillLevels};
+}
+
+function mockColorBarAxis(gd, opts, zrange) {
+ var fullLayout = gd._fullLayout;
+
+ var cbAxisIn = {
+ type: 'linear',
+ range: zrange,
+ tickmode: opts.tickmode,
+ nticks: opts.nticks,
+ tick0: opts.tick0,
+ dtick: opts.dtick,
+ tickvals: opts.tickvals,
+ ticktext: opts.ticktext,
+ ticks: opts.ticks,
+ ticklen: opts.ticklen,
+ tickwidth: opts.tickwidth,
+ tickcolor: opts.tickcolor,
+ showticklabels: opts.showticklabels,
+ tickfont: opts.tickfont,
+ tickangle: opts.tickangle,
+ tickformat: opts.tickformat,
+ exponentformat: opts.exponentformat,
+ separatethousands: opts.separatethousands,
+ showexponent: opts.showexponent,
+ showtickprefix: opts.showtickprefix,
+ tickprefix: opts.tickprefix,
+ showticksuffix: opts.showticksuffix,
+ ticksuffix: opts.ticksuffix,
+ title: opts.title,
+ showline: true,
+ anchor: 'free',
+ side: 'right',
+ position: 1
+ };
- return component;
- };
- });
+ var cbAxisOut = {
+ type: 'linear',
+ _id: 'y' + opts._id
+ };
- // or use .options to set multiple options at once via a dictionary
- component.options = function(o) {
- for(var name in o) {
- // in case something random comes through
- // that's not an option, ignore it
- if(typeof component[name] === 'function') {
- component[name](o[name]);
- }
- }
- return component;
+ var axisOptions = {
+ letter: 'y',
+ font: fullLayout.font,
+ noHover: true,
+ noTickson: true,
+ calendar: fullLayout.calendar // not really necessary (yet?)
};
- component._opts = opts;
+ function coerce(attr, dflt) {
+ return Lib.coerce(cbAxisIn, cbAxisOut, axisLayoutAttrs, attr, dflt);
+ }
+
+ handleAxisDefaults(cbAxisIn, cbAxisOut, coerce, axisOptions, fullLayout);
+ handleAxisPositionDefaults(cbAxisIn, cbAxisOut, coerce, axisOptions);
+
+ return cbAxisOut;
+}
- return component;
+module.exports = {
+ draw: draw
};
diff --git a/src/components/colorbar/index.js b/src/components/colorbar/index.js
index b6f624ee800..51a22b8701f 100644
--- a/src/components/colorbar/index.js
+++ b/src/components/colorbar/index.js
@@ -6,12 +6,15 @@
* LICENSE file in the root directory of this source tree.
*/
-
'use strict';
+module.exports = {
+ moduleType: 'component',
+ name: 'colorbar',
+
+ attributes: require('./attributes'),
+ supplyDefaults: require('./defaults'),
-exports.attributes = require('./attributes');
-exports.supplyDefaults = require('./defaults');
-exports.connect = require('./connect');
-exports.draw = require('./draw');
-exports.hasColorbar = require('./has_colorbar');
+ draw: require('./draw').draw,
+ hasColorbar: require('./has_colorbar')
+};
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 75cd284b2be..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'];
@@ -54,11 +108,11 @@ module.exports = function colorScaleDefaults(traceIn, traceOut, layout, coerce,
coerce(prefix + 'colorscale');
coerce(prefix + 'reversescale');
- if(!opts.noScale && prefix !== 'marker.line.') {
+ if(prefix !== 'marker.line.') {
// 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 f9e262f3a18..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;
+function extractScale(cont) {
+ var cOpts = extractOpts(cont);
+ var cmin = cOpts.min;
+ var cmax = cOpts.max;
- var scl = cont.reversescale ?
- flipScale(cont.colorscale) :
- cont.colorscale;
-
- // 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) {
@@ -154,14 +207,16 @@ function makeColorScaleFunc(specs, opts) {
}
// colorbar draw looks into the d3 scale closure for domain and range
-
sclFunc.domain = _sclFunc.domain;
-
sclFunc.range = function() { return range; };
return sclFunc;
}
+function makeColorScaleFuncFromTrace(trace, opts) {
+ return makeColorScaleFunc(extractScale(trace), opts);
+}
+
function colorArray2rbga(colorArray) {
var colorObj = {
r: colorArray[0],
@@ -175,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/core.js b/src/core.js
index df42ddad33c..a463c3bbdcc 100644
--- a/src/core.js
+++ b/src/core.js
@@ -55,7 +55,8 @@ register([
require('./components/rangeselector'),
require('./components/grid'),
require('./components/errorbars'),
- require('./components/colorscale')
+ require('./components/colorscale'),
+ require('./components/colorbar')
]);
// locales en and en-US are required for default behavior
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 ad064ee5d7b..070ba387819 100644
--- a/src/plot_api/plot_api.js
+++ b/src/plot_api/plot_api.js
@@ -28,7 +28,6 @@ var Polar = require('../plots/polar/legacy');
var Axes = require('../plots/cartesian/axes');
var Drawing = require('../components/drawing');
var Color = require('../components/color');
-var connectColorbar = require('../components/colorbar/connect');
var initInteractions = require('../plots/cartesian/graph_interact').initInteractions;
var xmlnsNamespaces = require('../constants/xmlns_namespaces');
var svgTextUtils = require('../lib/svg_text_utils');
@@ -283,9 +282,6 @@ exports.plot = function(gd, data, layout, config) {
// draw anything that can affect margins.
function marginPushers() {
- var calcdata = gd.calcdata;
- var i, cd, trace;
-
// First reset the list of things that are allowed to change the margins
// So any deleted traces or components will be wiped out of the
// automargin calculation.
@@ -296,15 +292,6 @@ exports.plot = function(gd, data, layout, config) {
subroutines.drawMarginPushers(gd);
Axes.allowAutoMargin(gd);
- for(i = 0; i < calcdata.length; i++) {
- cd = calcdata[i];
- trace = cd[0].trace;
- var colorbarOpts = trace._module.colorbar;
- if(trace.visible !== true || !colorbarOpts) {
- Plots.autoMargin(gd, 'cb' + trace.uid);
- } else connectColorbar(gd, cd, colorbarOpts);
- }
-
Plots.doAutoMargin(gd);
return Plots.previousPromises(gd);
}
@@ -1884,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);
}
@@ -2395,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);
@@ -2792,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/plot_api/subroutines.js b/src/plot_api/subroutines.js
index 8607065f898..a310ae31bcc 100644
--- a/src/plot_api/subroutines.js
+++ b/src/plot_api/subroutines.js
@@ -528,29 +528,7 @@ exports.doTraceStyle = function(gd) {
};
exports.doColorBars = function(gd) {
- for(var i = 0; i < gd.calcdata.length; i++) {
- var cdi0 = gd.calcdata[i][0];
-
- if((cdi0.t || {}).cb) {
- var trace = cdi0.trace;
- var cb = cdi0.t.cb;
-
- if(Registry.traceIs(trace, 'contour')) {
- cb.line({
- width: trace.contours.showlines !== false ?
- trace.line.width : 0,
- dash: trace.line.dash,
- color: trace.contours.coloring === 'line' ?
- cb._opts.line.color : trace.line.color
- });
- }
- var moduleOpts = trace._module.colorbar;
- var containerName = moduleOpts.container;
- var opts = (containerName ? trace[containerName] : trace).colorbar;
- cb.options(opts)();
- }
- }
-
+ Registry.getComponentMethod('colorbar', 'draw')(gd);
return Plots.previousPromises(gd);
};
@@ -607,22 +585,12 @@ exports.doCamera = function(gd) {
exports.drawData = function(gd) {
var fullLayout = gd._fullLayout;
- var calcdata = gd.calcdata;
- var i;
-
- // remove old colorbars explicitly
- for(i = 0; i < calcdata.length; i++) {
- var trace = calcdata[i][0].trace;
- if(trace.visible !== true || !trace._module.colorbar) {
- fullLayout._infolayer.select('.cb' + trace.uid).remove();
- }
- }
clearGlCanvases(gd);
// loop over the base plot modules present on graph
var basePlotModules = fullLayout._basePlotModules;
- for(i = 0; i < basePlotModules.length; i++) {
+ for(var i = 0; i < basePlotModules.length; i++) {
basePlotModules[i].plot(gd);
}
@@ -768,4 +736,5 @@ exports.drawMarginPushers = function(gd) {
Registry.getComponentMethod('rangeselector', 'draw')(gd);
Registry.getComponentMethod('sliders', 'draw')(gd);
Registry.getComponentMethod('updatemenus', 'draw')(gd);
+ Registry.getComponentMethod('colorbar', 'draw')(gd);
};
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 3ac177d31bc..8a92a745911 100644
--- a/src/plots/plots.js
+++ b/src/plots/plots.js
@@ -54,18 +54,18 @@ plots.hasSimpleAPICommandBindings = commandModule.hasSimpleAPICommandBindings;
plots.redrawText = function(gd) {
gd = Lib.getGraphDiv(gd);
+ var fullLayout = gd._fullLayout || {};
+ var hasPolar = fullLayout._has && fullLayout._has('polar');
+ var hasLegacyPolar = !hasPolar && gd.data && gd.data[0] && gd.data[0].r;
+
// do not work if polar is present
- if((gd.data && gd.data[0] && gd.data[0].r)) return;
+ if(hasLegacyPolar) return;
return new Promise(function(resolve) {
setTimeout(function() {
Registry.getComponentMethod('annotations', 'draw')(gd);
Registry.getComponentMethod('legend', 'draw')(gd);
-
- (gd.calcdata || []).forEach(function(d) {
- if(d[0] && d[0].t && d[0].t.cb) d[0].t.cb();
- });
-
+ Registry.getComponentMethod('colorbar', 'draw')(gd);
resolve(plots.previousPromises(gd));
}, 300);
});
@@ -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/snapshot/helpers.js b/src/snapshot/helpers.js
index b6f6ae21423..8b10678872b 100644
--- a/src/snapshot/helpers.js
+++ b/src/snapshot/helpers.js
@@ -6,9 +6,10 @@
* LICENSE file in the root directory of this source tree.
*/
-
'use strict';
+var Registry = require('../registry');
+
exports.getDelay = function(fullLayout) {
if(!fullLayout._has) return 0;
@@ -20,16 +21,13 @@ exports.getDelay = function(fullLayout) {
};
exports.getRedrawFunc = function(gd) {
- var fullLayout = gd._fullLayout || {};
- var hasPolar = fullLayout._has && fullLayout._has('polar');
- var hasLegacyPolar = !hasPolar && gd.data && gd.data[0] && gd.data[0].r;
-
- // do not work for legacy polar
- if(hasLegacyPolar) return;
-
return function() {
- (gd.calcdata || []).forEach(function(d) {
- if(d[0] && d[0].t && d[0].t.cb) d[0].t.cb();
- });
+ var fullLayout = gd._fullLayout || {};
+ var hasPolar = fullLayout._has && fullLayout._has('polar');
+ var hasLegacyPolar = !hasPolar && gd.data && gd.data[0] && gd.data[0].r;
+
+ if(!hasLegacyPolar) {
+ Registry.getComponentMethod('colorbar', 'draw')(gd);
+ }
};
};
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 0187ed5b7d1..46514b90a78 100644
--- a/src/traces/contour/colorbar.js
+++ b/src/traces/contour/colorbar.js
@@ -6,44 +6,42 @@
* LICENSE file in the root directory of this source tree.
*/
-
'use strict';
-var drawColorbar = require('../../components/colorbar/draw');
-
+var extractOpts = require('../../components/colorscale').extractOpts;
var makeColorMap = require('./make_color_map');
var endPlus = require('./end_plus');
-
-module.exports = function colorbar(gd, cd) {
- var trace = cd[0].trace;
- var cbId = 'cb' + trace.uid;
-
- gd._fullLayout._infolayer.selectAll('.' + cbId).remove();
-
- if(!trace.showscale) return;
-
- var cb = cd[0].t.cb = drawColorbar(gd, cbId);
-
+function calc(gd, trace, opts) {
var contours = trace.contours;
var line = trace.line;
var cs = contours.size || 1;
var coloring = contours.coloring;
-
var colorMap = makeColorMap(trace, {isColorbar: true});
- cb.fillgradient(coloring === 'heatmap' ? trace.colorscale : '')
- .zrange(coloring === 'heatmap' ? [trace.zmin, trace.zmax] : '')
- .fillcolor((coloring === 'fill') ? colorMap : '')
- .line({
- color: coloring === 'lines' ? colorMap : line.color,
- width: contours.showlines !== false ? line.width : 0,
- dash: line.dash
- })
- .levels({
- start: contours.start,
- end: endPlus(contours),
- size: cs
- })
- .options(trace.colorbar)();
+ if(coloring === 'heatmap') {
+ var cOpts = extractOpts(trace);
+ opts._fillgradient = trace.colorscale;
+ opts._zrange = [cOpts.min, cOpts.max];
+ } else if(coloring === 'fill') {
+ opts._fillcolor = colorMap;
+ }
+
+ opts._line = {
+ color: coloring === 'lines' ? colorMap : line.color,
+ width: contours.showlines !== false ? line.width : 0,
+ dash: line.dash
+ };
+
+ opts._levels = {
+ start: contours.start,
+ end: endPlus(contours),
+ size: cs
+ };
+}
+
+module.exports = {
+ min: 'zmin',
+ max: 'zmax',
+ calc: calc
};
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);