Skip to content

Color gradient for scatter3d snail trail lines [WIP] #617

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jun 21, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 19 additions & 9 deletions src/components/colorscale/color_attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

var colorScaleAttributes = require('./attributes');
var extendDeep = require('../../lib/extend').extendDeep;
var palettes = require('./scales.js');

module.exports = function makeColorScaleAttributes(context) {
return {
Expand All @@ -19,7 +20,7 @@ module.exports = function makeColorScaleAttributes(context) {
role: 'style',
description: [
'Sets the ', context, ' color. It accepts either a specific color',
' or an array of values that are mapped to the colorscale',
' or an array of numbers that are mapped to the colorscale',
' relative to the max and min values of the array or relative to',
' `cmin` and `cmax` if set.'
].join('')
Expand All @@ -35,14 +36,19 @@ module.exports = function makeColorScaleAttributes(context) {
' values are required. For example,',
' `[[0, \'rgb(0,0,255)\', [1, \'rgb(255,0,0)\']]`.',
' To control the bounds of the colorscale in color space,',
' use `', context, '.cmin` and `', context, '.cmax`.'
].join('')
' use `', context, '.cmin` and `', context, '.cmax`.',
' Alternatively, `colorscale` may be a palette name string',
' of the following list: '
].join('').concat(Object.keys(palettes).join(', '))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice

}),
cauto: extendDeep({}, colorScaleAttributes.zauto, {
description: [
'Has an effect only if `', context, '.color` is set to a numerical array.',
' Determines the whether or not the color domain is computed',
' automatically.'
'Has an effect only if `', context, '.color` is set to a numerical array',
' and `cmin`, `cmax` are set by the user. In this case,',
' it controls whether the range of colors in `colorscale` is mapped to',
' the range of values in the `color` array (`cauto: true`), or the `cmin`/`cmax`',
' values (`cauto: false`).',
' Defaults to `false` when `cmin`, `cmax` are set by the user.'
].join('')
}),
cmax: extendDeep({}, colorScaleAttributes.zmax, {
Expand All @@ -64,14 +70,18 @@ module.exports = function makeColorScaleAttributes(context) {
autocolorscale: extendDeep({}, colorScaleAttributes.autocolorscale, {
description: [
'Has an effect only if `', context, '.color` is set to a numerical array.',
' Determines whether or not the colorscale is picked using',
' values inside `', context, '.color`.'
' Determines whether the colorscale is a default palette (`autocolorscale: true`)',
' or the palette determined by `', context, '.colorscale`.',
' In case `colorscale` is unspecified or `autocolorscale` is true, the default ',
' palette will be chosen according to whether numbers in the `color` array are',
' all positive, all negative or mixed.'
].join('')
}),
reversescale: extendDeep({}, colorScaleAttributes.reversescale, {
description: [
'Has an effect only if `', context, '.color` is set to a numerical array.',
' Reverses the colorscale.'
' Reverses the color mapping if true (`cmin` will correspond to the last color',
' in the array and `cmax` will correspond to the first color).'
].join('')
})
};
Expand Down
6 changes: 5 additions & 1 deletion src/plot_api/plot_api.js
Original file line number Diff line number Diff line change
Expand Up @@ -1590,7 +1590,9 @@ Plotly.restyle = function restyle(gd, astr, val, traces) {
'outsidetextfont.size', 'outsidetextfont.family', 'outsidetextfont.color',
'hole', 'scalegroup', 'domain', 'domain.x', 'domain.y',
'domain.x[0]', 'domain.x[1]', 'domain.y[0]', 'domain.y[1]',
'tilt', 'tiltaxis', 'depth', 'direction', 'rotation', 'pull'
'tilt', 'tiltaxis', 'depth', 'direction', 'rotation', 'pull',
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@etpinard just thinking about how these arrays could simply be done by flags in the attribute.js definitions but it's not trivial due to the irregularities:

  1. Sometimes (as domain.x[0] here) the check is below the prop level (this is easy to cover though)
  2. There are multiple sets: recalcAttrs, autorangeAttrs, replotAttrs, 'swapAttrs' (still easy to cover but not pretty)
  3. Lots of manual overrides (see elseif tree with doextras: https://github.com/plotly/plotly.js/blob/master/src/plot_api/plot_api.js#L1736-L1814
  4. Innumerable special casing for a wide diversity of things such as pie, LAYOUT, if(ai === 'orientationaxes') etc.

It's possible to first cover 1, 2 and maybe 3 but even that leaves quite a lot of entanglement.

'line.showscale', 'line.cauto', 'line.autocolorscale', 'line.reversescale',
'marker.line.showscale', 'marker.line.cauto', 'marker.line.autocolorscale', 'marker.line.reversescale'
];
for(i = 0; i < traces.length; i++) {
if(Plots.traceIs(gd._fullData[traces[i]], 'box')) {
Expand All @@ -1612,6 +1614,8 @@ Plotly.restyle = function restyle(gd, astr, val, traces) {
var replotAttrs = [
'zmin', 'zmax', 'zauto',
'marker.cmin', 'marker.cmax', 'marker.cauto',
'line.cmin', 'line.cmax',
'marker.line.cmin', 'marker.line.cmax',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ha. Good 👀 . Thanks.

This is good enough for now until #648 is addressed.

'contours.start', 'contours.end', 'contours.size',
'contours.showlines',
'line', 'line.smoothing', 'line.shape',
Expand Down
4 changes: 2 additions & 2 deletions src/traces/scatter/calc.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ var Axes = require('../../plots/cartesian/axes');
var Lib = require('../../lib');

var subTypes = require('./subtypes');
var calcMarkerColorscale = require('./marker_colorscale_calc');
var calcColorscale = require('./colorscale_calc');


module.exports = function calc(gd, trace) {
Expand Down Expand Up @@ -73,7 +73,7 @@ module.exports = function calc(gd, trace) {
s.map(markerTrans) : markerTrans(s);
}

calcMarkerColorscale(trace);
calcColorscale(trace);

// TODO: text size

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,21 @@ var subTypes = require('./subtypes');

// common to 'scatter', 'scatter3d' and 'scattergeo'
module.exports = function calcMarkerColorscale(trace) {
if(!subTypes.hasMarkers(trace)) return;

var marker = trace.marker;

// auto-z and autocolorscale if applicable
if(hasColorscale(trace, 'marker')) {
calcColorscale(trace, marker.color, 'marker', 'c');

if(subTypes.hasLines(trace) && hasColorscale(trace, 'line')) {
calcColorscale(trace, trace.line.color, 'line', 'c');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nicely done here.

}

if(hasColorscale(trace, 'marker.line')) {
calcColorscale(trace, marker.line.color, 'marker.line', 'c');
if(subTypes.hasMarkers(trace)) {

if(hasColorscale(trace, 'marker')) {
calcColorscale(trace, trace.marker.color, 'marker', 'c');
}

if(hasColorscale(trace, 'marker.line')) {
calcColorscale(trace, trace.marker.line.color, 'marker.line', 'c');
}
}
};
2 changes: 1 addition & 1 deletion src/traces/scatter/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
coerce('mode', defaultMode);

if(subTypes.hasLines(traceOut)) {
handleLineDefaults(traceIn, traceOut, defaultColor, coerce);
handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce);
handleLineShapeDefaults(traceIn, traceOut, coerce);
coerce('connectgaps');
}
Expand Down
20 changes: 16 additions & 4 deletions src/traces/scatter/line_defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,26 @@

'use strict';

var hasColorscale = require('../../components/colorscale/has_colorscale');
var colorscaleDefaults = require('../../components/colorscale/defaults');


// common to 'scatter', 'scatter3d', 'scattergeo' and 'scattergl'
module.exports = function lineDefaults(traceIn, traceOut, defaultColor, coerce) {
module.exports = function lineDefaults(traceIn, traceOut, defaultColor, layout, coerce) {

var markerColor = (traceIn.marker || {}).color;

// don't try to inherit a color array
coerce('line.color', (Array.isArray(markerColor) ? false : markerColor) ||
defaultColor);
coerce('line.color', defaultColor);
if(hasColorscale(traceIn, 'line')) {
colorscaleDefaults(
traceIn, traceOut, layout, coerce, {prefix: 'line.', cLetter: 'c'}
);
} else {
coerce('line.color', (Array.isArray(markerColor) ? false : markerColor) ||
defaultColor);
}


coerce('line.width');
coerce('line.dash');
};
2 changes: 1 addition & 1 deletion src/traces/scatter/marker_defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ var subTypes = require('./subtypes');
// common to 'scatter', 'scatter3d', 'scattergeo' and 'scattergl'
module.exports = function markerDefaults(traceIn, traceOut, defaultColor, layout, coerce) {
var isBubble = subTypes.isBubble(traceIn),
lineColor = (traceIn.line || {}).color,
lineColor = !Array.isArray(traceIn.line) ? (traceIn.line || {}).color : undefined,
defaultMLC;

if(lineColor) defaultColor = lineColor;
Expand Down
16 changes: 13 additions & 3 deletions src/traces/scatter3d/attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,21 @@ module.exports = {
z: makeProjectionAttr('z')
},
connectgaps: scatterAttrs.connectgaps,
line: {
color: scatterLineAttrs.color,
line: extendFlat({}, {
width: scatterLineAttrs.width,
dash: scatterLineAttrs.dash
dash: scatterLineAttrs.dash,
showscale: {
valType: 'boolean',
role: 'info',
dflt: false,
description: [
'Has an effect only if `line.color` is set to a numerical array.',
'Determines whether or not a colorbar is displayed.'
].join(' ')
}
},
colorAttributes('line')
),
marker: extendFlat({}, { // Parity with scatter.js?
symbol: {
valType: 'enumerated',
Expand Down
4 changes: 2 additions & 2 deletions src/traces/scatter3d/calc.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
'use strict';

var arraysToCalcdata = require('../scatter/arrays_to_calcdata');
var calcMarkerColorscale = require('../scatter/marker_colorscale_calc');
var calcColorscales = require('../scatter/colorscale_calc');


/**
Expand All @@ -21,7 +21,7 @@ module.exports = function calc(gd, trace) {
var cd = [{x: false, y: false, trace: trace, t: {}}];

arraysToCalcdata(cd);
calcMarkerColorscale(trace);
calcColorscales(trace);

return cd;
};
2 changes: 1 addition & 1 deletion src/traces/scatter3d/convert.js
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ function convertPlotlyOptions(scene, data) {
};

if('line' in data) {
params.lineColor = str2RgbaArray(line.color);
params.lineColor = formatColor(line, 1, len);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice.

params.lineWidth = line.width;
params.lineDashes = line.dash;
}
Expand Down
2 changes: 1 addition & 1 deletion src/traces/scatter3d/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout

if(subTypes.hasLines(traceOut)) {
coerce('connectgaps');
handleLineDefaults(traceIn, traceOut, defaultColor, coerce);
handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce);
}

if(subTypes.hasMarkers(traceOut)) {
Expand Down
4 changes: 2 additions & 2 deletions src/traces/scattergeo/calc.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@

'use strict';

var calcMarkerColorscale = require('../scatter/marker_colorscale_calc');
var calcColorscale = require('../scatter/colorscale_calc');


module.exports = function calc(gd, trace) {
var cd = [{x: false, y: false, trace: trace, t: {}}];

calcMarkerColorscale(trace);
calcColorscale(trace);

return cd;
};
2 changes: 1 addition & 1 deletion src/traces/scattergeo/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
coerce('mode');

if(subTypes.hasLines(traceOut)) {
handleLineDefaults(traceIn, traceOut, defaultColor, coerce);
handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce);
}

if(subTypes.hasMarkers(traceOut)) {
Expand Down
2 changes: 1 addition & 1 deletion src/traces/scattergl/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout

if(subTypes.hasLines(traceOut)) {
coerce('connectgaps');
handleLineDefaults(traceIn, traceOut, defaultColor, coerce);
handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nicely done.

}

if(subTypes.hasMarkers(traceOut)) {
Expand Down
2 changes: 1 addition & 1 deletion src/traces/scattermapbox/calc.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ var Lib = require('../../lib');
var hasColorscale = require('../../components/colorscale/has_colorscale');
var makeColorScaleFn = require('../../components/colorscale/make_scale_function');
var subtypes = require('../scatter/subtypes');
var calcMarkerColorscale = require('../scatter/marker_colorscale_calc');
var calcMarkerColorscale = require('../scatter/colorscale_calc');
var makeBubbleSizeFn = require('../scatter/make_bubble_size_func');


Expand Down
4 changes: 2 additions & 2 deletions src/traces/scatterternary/calc.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ var Axes = require('../../plots/cartesian/axes');
var Lib = require('../../lib');

var subTypes = require('../scatter/subtypes');
var calcMarkerColorscale = require('../scatter/marker_colorscale_calc');
var calcColorscale = require('../scatter/colorscale_calc');

var dataArrays = ['a', 'b', 'c'];
var arraysToFill = {a: ['b', 'c'], b: ['a', 'c'], c: ['a', 'b']};
Expand Down Expand Up @@ -88,7 +88,7 @@ module.exports = function calc(gd, trace) {
}
}

calcMarkerColorscale(trace);
calcColorscale(trace);

// this has migrated up from arraysToCalcdata as we have a reference to 's' here
if(typeof s !== undefined) Lib.mergeArray(s, cd, 'ms');
Expand Down
2 changes: 1 addition & 1 deletion src/traces/scatterternary/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
coerce('mode', defaultMode);

if(subTypes.hasLines(traceOut)) {
handleLineDefaults(traceIn, traceOut, defaultColor, coerce);
handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce);
handleLineShapeDefaults(traceIn, traceOut, coerce);
coerce('connectgaps');
}
Expand Down
Binary file added test/image/baselines/gl3d_scatter-color-array.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
53 changes: 53 additions & 0 deletions test/image/mocks/gl3d_scatter-color-array.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{
"data": [
{
"x":[-4,-3,-2,-1,0,1,2,3,4,5,6],
"y":[11,10,9,7,5,6,4,2,3,1,3],
"z":[4,5,4,3,2,1,0,-1,-2,-3,-4],
"mode": "lines",
"line": {
"width": 5,
"color": [
"#67001f",
"#b2182b",
"#d6604d",
"#f4a582",
"#fddbc7",
"#d1e5f0",
"#92c5de",
"#4393c3",
"#2166ac",
"#053061"
]
},
"type":"scatter3d"
},
{
"x":[-4,-3,-2,-1,0,1,2,3,4,5,6],
"y":[7,5,6,4,2,3,1,3,-1,-4,-2],
"z":[2,3,4,5,4,3,2,1,0,-1,-2],
"mode": "lines+markers",
"line": {
"width": 5,
"color": [
"#67001f",
"#b2182b",
"#d6604d",
"#f4a582",
"#fddbc7",
"#d1e5f0",
"#92c5de",
"#4393c3",
"#2166ac",
"#053061"
]
},
"type":"scatter3d"
}
],
"layout": {
"title": "Markers should default to line color",
"height":758,
"width":1310
}
}
Loading