Skip to content

Commit

Permalink
refactor colorbars for simpler connection to trace attributes
Browse files Browse the repository at this point in the history
Also fixes and tests a few traces that should have supported colorbars but didn't
and some cases of editing colorbars that didn't previously work
  • Loading branch information
alexcjohnson committed May 30, 2018
1 parent 6dd68bd commit fa86147
Show file tree
Hide file tree
Showing 36 changed files with 428 additions and 331 deletions.
85 changes: 85 additions & 0 deletions src/components/colorbar/connect.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/**
* Copyright 2012-2018, 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 isNumeric = require('fast-isnumeric');

var aggNums = require('../../lib').aggNums;
var Colorscale = require('../colorscale');
var drawColorbar = require('./draw');

/**
* 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;
var containerName = moduleOpts.container;
var container = containerName ? trace[containerName] : trace;

gd._fullLayout._infolayer.selectAll('.' + cbId).remove();
if(!container || !container.showscale) return;

var zmin = container[moduleOpts.min];
var zmax = container[moduleOpts.max];

var valAttr = moduleOpts.vals;
var vals;
if(Array.isArray(valAttr)) {
for(var i = 0; i < valAttr.length; i++) {
vals = container[valAttr[i]];
if(vals) break;
}
}
else vals = container[valAttr];

if(vals) {
if(!isNumeric(zmin)) zmin = aggNums(Math.min, null, vals);
if(!isNumeric(zmax)) zmax = aggNums(Math.max, null, vals);
}

var cb = cd[0].t.cb = drawColorbar(gd, cbId);
var sclFunc = Colorscale.makeColorScaleFunc(
Colorscale.extractScale(
container.colorscale,
zmin,
zmax
),
{ noNumericCheck: true }
);

cb.fillcolor(sclFunc)
.filllevels({start: zmin, end: zmax, size: (zmax - zmin) / 254})
.options(container.colorbar)();
};
10 changes: 4 additions & 6 deletions src/components/colorbar/draw.js
Original file line number Diff line number Diff line change
Expand Up @@ -447,12 +447,10 @@ module.exports = function draw(gd, id) {
}

function drawTitle(titleClass, titleOpts) {
var trace = getTrace(),
propName;
if(Registry.traceIs(trace, 'markerColorscale')) {
propName = 'marker.colorbar.title';
}
else propName = 'colorbar.title';
var trace = getTrace();
var propName = 'colorbar.title';
var containerName = trace._module.colorbar.container;
if(containerName) propName = containerName + '.' + propName;

var dfltTitleOpts = {
propContainer: cbAxisOut,
Expand Down
4 changes: 1 addition & 3 deletions src/components/colorbar/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@


exports.attributes = require('./attributes');

exports.supplyDefaults = require('./defaults');

exports.connect = require('./connect');
exports.draw = require('./draw');

exports.hasColorbar = require('./has_colorbar');
16 changes: 8 additions & 8 deletions src/plot_api/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -274,14 +274,14 @@ exports.cleanData = function(data) {
}

// fix typo in colorscale definition
if(Registry.traceIs(trace, '2dMap')) {
if(trace.colorscale === 'YIGnBu') trace.colorscale = 'YlGnBu';
if(trace.colorscale === 'YIOrRd') trace.colorscale = 'YlOrRd';
}
if(Registry.traceIs(trace, 'markerColorscale') && trace.marker) {
var cont = trace.marker;
if(cont.colorscale === 'YIGnBu') cont.colorscale = 'YlGnBu';
if(cont.colorscale === 'YIOrRd') cont.colorscale = 'YlOrRd';
var _module = Registry.getModule(trace);
if(_module && _module.colorbar) {
var containerName = _module.colorbar.container;
var container = containerName ? trace[containerName] : trace;
if(container && container.colorscale) {
if(container.colorscale === 'YIGnBu') container.colorscale = 'YlGnBu';
if(container.colorscale === 'YIOrRd') container.colorscale = 'YlOrRd';
}
}

// fix typo in surface 'highlight*' definitions
Expand Down
56 changes: 31 additions & 25 deletions src/plot_api/plot_api.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ 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');
Expand Down Expand Up @@ -265,10 +266,11 @@ exports.plot = function(gd, data, layout, config) {
for(i = 0; i < calcdata.length; i++) {
cd = calcdata[i];
trace = cd[0].trace;
if(trace.visible !== true || !trace._module.colorbar) {
var colorbarOpts = trace._module.colorbar;
if(trace.visible !== true || !colorbarOpts) {
Plots.autoMargin(gd, 'cb' + trace.uid);
}
else trace._module.colorbar(gd, cd);
else connectColorbar(gd, cd, colorbarOpts);
}

Plots.doAutoMargin(gd);
Expand Down Expand Up @@ -1448,6 +1450,11 @@ function _restyle(gd, aobj, traces) {

if(newVal === undefined) continue;

var finalPart = param.parts[param.parts.length - 1];
var prefix = ai.substr(0, ai.length - finalPart.length - 1);
var prefixDot = prefix ? prefix + '.' : '';
var innerContFull = prefix ? Lib.nestedProperty(contFull, prefix) : contFull;

valObject = PlotSchema.getTraceValObject(contFull, param.parts);

if(valObject && valObject.impliedEdits && newVal !== null) {
Expand All @@ -1461,31 +1468,30 @@ function _restyle(gd, aobj, traces) {
// note that colorbar fractional sizing is based on the
// original plot size, before anything (like a colorbar)
// increases the margins
else if(ai === 'colorbar.thicknessmode' && param.get() !== newVal &&
['fraction', 'pixels'].indexOf(newVal) !== -1 &&
contFull.colorbar) {
var thicknorm =
['top', 'bottom'].indexOf(contFull.colorbar.orient) !== -1 ?
(fullLayout.height - fullLayout.margin.t - fullLayout.margin.b) :
(fullLayout.width - fullLayout.margin.l - fullLayout.margin.r);
doextra('colorbar.thickness', contFull.colorbar.thickness *
(newVal === 'fraction' ? 1 / thicknorm : thicknorm), i);
}
else if(ai === 'colorbar.lenmode' && param.get() !== newVal &&
['fraction', 'pixels'].indexOf(newVal) !== -1 &&
contFull.colorbar) {
var lennorm =
['top', 'bottom'].indexOf(contFull.colorbar.orient) !== -1 ?
(fullLayout.width - fullLayout.margin.l - fullLayout.margin.r) :
(fullLayout.height - fullLayout.margin.t - fullLayout.margin.b);
doextra('colorbar.len', contFull.colorbar.len *
(newVal === 'fraction' ? 1 / lennorm : lennorm), i);
}
else if(ai === 'colorbar.tick0' || ai === 'colorbar.dtick') {
doextra('colorbar.tickmode', 'linear', i);
else if((finalPart === 'thicknessmode' || finalPart === 'lenmode') &&
oldVal !== newVal &&
(newVal === 'fraction' || newVal === 'pixels') &&
innerContFull
) {
if(finalPart === 'thicknessmode') {
var thicknorm =
['top', 'bottom'].indexOf(innerContFull.orient) !== -1 ?
(fullLayout.height - fullLayout.margin.t - fullLayout.margin.b) :
(fullLayout.width - fullLayout.margin.l - fullLayout.margin.r);
doextra(prefixDot + 'thickness', innerContFull.thickness *
(newVal === 'fraction' ? 1 / thicknorm : thicknorm), i);
}
else {
var lennorm =
['top', 'bottom'].indexOf(innerContFull.orient) !== -1 ?
(fullLayout.width - fullLayout.margin.l - fullLayout.margin.r) :
(fullLayout.height - fullLayout.margin.t - fullLayout.margin.b);
doextra(prefixDot + 'len', innerContFull.len *
(newVal === 'fraction' ? 1 / lennorm : lennorm), i);
}
}

if(ai === 'type' && (newVal === 'pie') !== (oldVal === 'pie')) {
else if(ai === 'type' && (newVal === 'pie') !== (oldVal === 'pie')) {
var labelsTo = 'x',
valuesTo = 'y';
if((newVal === 'bar' || oldVal === 'bar') && cont.orientation === 'h') {
Expand Down
8 changes: 4 additions & 4 deletions src/plot_api/subroutines.js
Original file line number Diff line number Diff line change
Expand Up @@ -473,10 +473,10 @@ exports.doColorBars = function(gd) {
cb._opts.line.color : trace.line.color
});
}
if(Registry.traceIs(trace, 'markerColorscale')) {
cb.options(trace.marker.colorbar)();
}
else cb.options(trace.colorbar)();
var moduleOpts = trace._module.colorbar;
var containerName = moduleOpts.container;
var opts = (containerName ? trace[containerName] : trace).colorbar;
cb.options(opts)();
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/traces/bar/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Bar.supplyDefaults = require('./defaults');
Bar.supplyLayoutDefaults = require('./layout_defaults');
Bar.calc = require('./calc');
Bar.setPositions = require('./set_positions');
Bar.colorbar = require('../scatter/colorbar');
Bar.colorbar = require('../scatter/marker_colorbar');
Bar.arraysToCalcdata = require('./arrays_to_calcdata');
Bar.plot = require('./plot');
Bar.style = require('./style').style;
Expand All @@ -28,7 +28,7 @@ Bar.selectPoints = require('./select');
Bar.moduleType = 'trace';
Bar.name = 'bar';
Bar.basePlotModule = require('../../plots/cartesian');
Bar.categories = ['cartesian', 'svg', 'bar', 'oriented', 'markerColorscale', 'errorBarsOK', 'showLegend', 'zoomScale'];
Bar.categories = ['cartesian', 'svg', 'bar', 'oriented', 'errorBarsOK', 'showLegend', 'zoomScale'];
Bar.meta = {
description: [
'The data visualized by the span of the bars is set in `y`',
Expand Down
33 changes: 0 additions & 33 deletions src/traces/cone/colorbar.js

This file was deleted.

6 changes: 5 additions & 1 deletion src/traces/cone/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ module.exports = {

attributes: require('./attributes'),
supplyDefaults: require('./defaults'),
colorbar: require('./colorbar'),
colorbar: {
min: 'cmin',
max: 'cmax'
// no vals, these are calculated automatically from vector norms
},
calc: require('./calc'),
plot: require('./convert'),

Expand Down
38 changes: 4 additions & 34 deletions src/traces/heatmap/colorbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,40 +6,10 @@
* LICENSE file in the root directory of this source tree.
*/


'use strict';

var isNumeric = require('fast-isnumeric');

var Lib = require('../../lib');
var Colorscale = require('../../components/colorscale');
var drawColorbar = require('../../components/colorbar/draw');


module.exports = function colorbar(gd, cd) {
var trace = cd[0].trace,
cbId = 'cb' + trace.uid,
zmin = trace.zmin,
zmax = trace.zmax;

if(!isNumeric(zmin)) zmin = Lib.aggNums(Math.min, null, trace.z);
if(!isNumeric(zmax)) zmax = Lib.aggNums(Math.max, null, trace.z);

gd._fullLayout._infolayer.selectAll('.' + cbId).remove();

if(!trace.showscale) return;

var cb = cd[0].t.cb = drawColorbar(gd, cbId);
var sclFunc = Colorscale.makeColorScaleFunc(
Colorscale.extractScale(
trace.colorscale,
zmin,
zmax
),
{ noNumericCheck: true }
);

cb.fillcolor(sclFunc)
.filllevels({start: zmin, end: zmax, size: (zmax - zmin) / 254})
.options(trace.colorbar)();
module.exports = {
min: 'zmin',
max: 'zmax',
vals: 'z'
};
2 changes: 1 addition & 1 deletion src/traces/histogram/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Histogram.plot = require('../bar/plot');
Histogram.layerName = 'barlayer';
Histogram.style = require('../bar/style').style;
Histogram.styleOnSelect = require('../bar/style').styleOnSelect;
Histogram.colorbar = require('../scatter/colorbar');
Histogram.colorbar = require('../scatter/marker_colorbar');
Histogram.hoverPoints = require('./hover');
Histogram.selectPoints = require('../bar/select');
Histogram.eventData = require('./event_data');
Expand Down
Loading

0 comments on commit fa86147

Please sign in to comment.