Skip to content

Commit f69fc5f

Browse files
authored
Merge pull request #617 from monfera/581-scatter3d-line-color
Color gradient for `scatter3d` snail trail lines [WIP]
2 parents 7629837 + 7347847 commit f69fc5f

25 files changed

+476
-40
lines changed

src/components/colorscale/color_attributes.js

+19-9
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
var colorScaleAttributes = require('./attributes');
1212
var extendDeep = require('../../lib/extend').extendDeep;
13+
var palettes = require('./scales.js');
1314

1415
module.exports = function makeColorScaleAttributes(context) {
1516
return {
@@ -19,7 +20,7 @@ module.exports = function makeColorScaleAttributes(context) {
1920
role: 'style',
2021
description: [
2122
'Sets the ', context, ' color. It accepts either a specific color',
22-
' or an array of values that are mapped to the colorscale',
23+
' or an array of numbers that are mapped to the colorscale',
2324
' relative to the max and min values of the array or relative to',
2425
' `cmin` and `cmax` if set.'
2526
].join('')
@@ -35,14 +36,19 @@ module.exports = function makeColorScaleAttributes(context) {
3536
' values are required. For example,',
3637
' `[[0, \'rgb(0,0,255)\', [1, \'rgb(255,0,0)\']]`.',
3738
' To control the bounds of the colorscale in color space,',
38-
' use `', context, '.cmin` and `', context, '.cmax`.'
39-
].join('')
39+
' use `', context, '.cmin` and `', context, '.cmax`.',
40+
' Alternatively, `colorscale` may be a palette name string',
41+
' of the following list: '
42+
].join('').concat(Object.keys(palettes).join(', '))
4043
}),
4144
cauto: extendDeep({}, colorScaleAttributes.zauto, {
4245
description: [
43-
'Has an effect only if `', context, '.color` is set to a numerical array.',
44-
' Determines the whether or not the color domain is computed',
45-
' automatically.'
46+
'Has an effect only if `', context, '.color` is set to a numerical array',
47+
' and `cmin`, `cmax` are set by the user. In this case,',
48+
' it controls whether the range of colors in `colorscale` is mapped to',
49+
' the range of values in the `color` array (`cauto: true`), or the `cmin`/`cmax`',
50+
' values (`cauto: false`).',
51+
' Defaults to `false` when `cmin`, `cmax` are set by the user.'
4652
].join('')
4753
}),
4854
cmax: extendDeep({}, colorScaleAttributes.zmax, {
@@ -64,14 +70,18 @@ module.exports = function makeColorScaleAttributes(context) {
6470
autocolorscale: extendDeep({}, colorScaleAttributes.autocolorscale, {
6571
description: [
6672
'Has an effect only if `', context, '.color` is set to a numerical array.',
67-
' Determines whether or not the colorscale is picked using',
68-
' values inside `', context, '.color`.'
73+
' Determines whether the colorscale is a default palette (`autocolorscale: true`)',
74+
' or the palette determined by `', context, '.colorscale`.',
75+
' In case `colorscale` is unspecified or `autocolorscale` is true, the default ',
76+
' palette will be chosen according to whether numbers in the `color` array are',
77+
' all positive, all negative or mixed.'
6978
].join('')
7079
}),
7180
reversescale: extendDeep({}, colorScaleAttributes.reversescale, {
7281
description: [
7382
'Has an effect only if `', context, '.color` is set to a numerical array.',
74-
' Reverses the colorscale.'
83+
' Reverses the color mapping if true (`cmin` will correspond to the last color',
84+
' in the array and `cmax` will correspond to the first color).'
7585
].join('')
7686
})
7787
};

src/plot_api/plot_api.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -1590,7 +1590,9 @@ Plotly.restyle = function restyle(gd, astr, val, traces) {
15901590
'outsidetextfont.size', 'outsidetextfont.family', 'outsidetextfont.color',
15911591
'hole', 'scalegroup', 'domain', 'domain.x', 'domain.y',
15921592
'domain.x[0]', 'domain.x[1]', 'domain.y[0]', 'domain.y[1]',
1593-
'tilt', 'tiltaxis', 'depth', 'direction', 'rotation', 'pull'
1593+
'tilt', 'tiltaxis', 'depth', 'direction', 'rotation', 'pull',
1594+
'line.showscale', 'line.cauto', 'line.autocolorscale', 'line.reversescale',
1595+
'marker.line.showscale', 'marker.line.cauto', 'marker.line.autocolorscale', 'marker.line.reversescale'
15941596
];
15951597
for(i = 0; i < traces.length; i++) {
15961598
if(Plots.traceIs(gd._fullData[traces[i]], 'box')) {
@@ -1612,6 +1614,8 @@ Plotly.restyle = function restyle(gd, astr, val, traces) {
16121614
var replotAttrs = [
16131615
'zmin', 'zmax', 'zauto',
16141616
'marker.cmin', 'marker.cmax', 'marker.cauto',
1617+
'line.cmin', 'line.cmax',
1618+
'marker.line.cmin', 'marker.line.cmax',
16151619
'contours.start', 'contours.end', 'contours.size',
16161620
'contours.showlines',
16171621
'line', 'line.smoothing', 'line.shape',

src/traces/scatter/calc.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ var Axes = require('../../plots/cartesian/axes');
1515
var Lib = require('../../lib');
1616

1717
var subTypes = require('./subtypes');
18-
var calcMarkerColorscale = require('./marker_colorscale_calc');
18+
var calcColorscale = require('./colorscale_calc');
1919

2020

2121
module.exports = function calc(gd, trace) {
@@ -73,7 +73,7 @@ module.exports = function calc(gd, trace) {
7373
s.map(markerTrans) : markerTrans(s);
7474
}
7575

76-
calcMarkerColorscale(trace);
76+
calcColorscale(trace);
7777

7878
// TODO: text size
7979

src/traces/scatter/marker_colorscale_calc.js renamed to src/traces/scatter/colorscale_calc.js

+12-7
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,21 @@ var subTypes = require('./subtypes');
1717

1818
// common to 'scatter', 'scatter3d' and 'scattergeo'
1919
module.exports = function calcMarkerColorscale(trace) {
20-
if(!subTypes.hasMarkers(trace)) return;
21-
22-
var marker = trace.marker;
2320

2421
// auto-z and autocolorscale if applicable
25-
if(hasColorscale(trace, 'marker')) {
26-
calcColorscale(trace, marker.color, 'marker', 'c');
22+
23+
if(subTypes.hasLines(trace) && hasColorscale(trace, 'line')) {
24+
calcColorscale(trace, trace.line.color, 'line', 'c');
2725
}
2826

29-
if(hasColorscale(trace, 'marker.line')) {
30-
calcColorscale(trace, marker.line.color, 'marker.line', 'c');
27+
if(subTypes.hasMarkers(trace)) {
28+
29+
if(hasColorscale(trace, 'marker')) {
30+
calcColorscale(trace, trace.marker.color, 'marker', 'c');
31+
}
32+
33+
if(hasColorscale(trace, 'marker.line')) {
34+
calcColorscale(trace, trace.marker.line.color, 'marker.line', 'c');
35+
}
3136
}
3237
};

src/traces/scatter/defaults.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
4040
coerce('mode', defaultMode);
4141

4242
if(subTypes.hasLines(traceOut)) {
43-
handleLineDefaults(traceIn, traceOut, defaultColor, coerce);
43+
handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce);
4444
handleLineShapeDefaults(traceIn, traceOut, coerce);
4545
coerce('connectgaps');
4646
}

src/traces/scatter/line_defaults.js

+16-4
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,26 @@
99

1010
'use strict';
1111

12+
var hasColorscale = require('../../components/colorscale/has_colorscale');
13+
var colorscaleDefaults = require('../../components/colorscale/defaults');
14+
1215

1316
// common to 'scatter', 'scatter3d', 'scattergeo' and 'scattergl'
14-
module.exports = function lineDefaults(traceIn, traceOut, defaultColor, coerce) {
17+
module.exports = function lineDefaults(traceIn, traceOut, defaultColor, layout, coerce) {
18+
1519
var markerColor = (traceIn.marker || {}).color;
1620

17-
// don't try to inherit a color array
18-
coerce('line.color', (Array.isArray(markerColor) ? false : markerColor) ||
19-
defaultColor);
21+
coerce('line.color', defaultColor);
22+
if(hasColorscale(traceIn, 'line')) {
23+
colorscaleDefaults(
24+
traceIn, traceOut, layout, coerce, {prefix: 'line.', cLetter: 'c'}
25+
);
26+
} else {
27+
coerce('line.color', (Array.isArray(markerColor) ? false : markerColor) ||
28+
defaultColor);
29+
}
30+
31+
2032
coerce('line.width');
2133
coerce('line.dash');
2234
};

src/traces/scatter/marker_defaults.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ var subTypes = require('./subtypes');
1919
// common to 'scatter', 'scatter3d', 'scattergeo' and 'scattergl'
2020
module.exports = function markerDefaults(traceIn, traceOut, defaultColor, layout, coerce) {
2121
var isBubble = subTypes.isBubble(traceIn),
22-
lineColor = (traceIn.line || {}).color,
22+
lineColor = !Array.isArray(traceIn.line) ? (traceIn.line || {}).color : undefined,
2323
defaultMLC;
2424

2525
if(lineColor) defaultColor = lineColor;

src/traces/scatter3d/attributes.js

+13-3
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,21 @@ module.exports = {
9797
z: makeProjectionAttr('z')
9898
},
9999
connectgaps: scatterAttrs.connectgaps,
100-
line: {
101-
color: scatterLineAttrs.color,
100+
line: extendFlat({}, {
102101
width: scatterLineAttrs.width,
103-
dash: scatterLineAttrs.dash
102+
dash: scatterLineAttrs.dash,
103+
showscale: {
104+
valType: 'boolean',
105+
role: 'info',
106+
dflt: false,
107+
description: [
108+
'Has an effect only if `line.color` is set to a numerical array.',
109+
'Determines whether or not a colorbar is displayed.'
110+
].join(' ')
111+
}
104112
},
113+
colorAttributes('line')
114+
),
105115
marker: extendFlat({}, { // Parity with scatter.js?
106116
symbol: {
107117
valType: 'enumerated',

src/traces/scatter3d/calc.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
'use strict';
1010

1111
var arraysToCalcdata = require('../scatter/arrays_to_calcdata');
12-
var calcMarkerColorscale = require('../scatter/marker_colorscale_calc');
12+
var calcColorscales = require('../scatter/colorscale_calc');
1313

1414

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

2323
arraysToCalcdata(cd);
24-
calcMarkerColorscale(trace);
24+
calcColorscales(trace);
2525

2626
return cd;
2727
};

src/traces/scatter3d/convert.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ function convertPlotlyOptions(scene, data) {
204204
};
205205

206206
if('line' in data) {
207-
params.lineColor = str2RgbaArray(line.color);
207+
params.lineColor = formatColor(line, 1, len);
208208
params.lineWidth = line.width;
209209
params.lineDashes = line.dash;
210210
}

src/traces/scatter3d/defaults.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
3737

3838
if(subTypes.hasLines(traceOut)) {
3939
coerce('connectgaps');
40-
handleLineDefaults(traceIn, traceOut, defaultColor, coerce);
40+
handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce);
4141
}
4242

4343
if(subTypes.hasMarkers(traceOut)) {

src/traces/scattergeo/calc.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@
99

1010
'use strict';
1111

12-
var calcMarkerColorscale = require('../scatter/marker_colorscale_calc');
12+
var calcColorscale = require('../scatter/colorscale_calc');
1313

1414

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

18-
calcMarkerColorscale(trace);
18+
calcColorscale(trace);
1919

2020
return cd;
2121
};

src/traces/scattergeo/defaults.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
3434
coerce('mode');
3535

3636
if(subTypes.hasLines(traceOut)) {
37-
handleLineDefaults(traceIn, traceOut, defaultColor, coerce);
37+
handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce);
3838
}
3939

4040
if(subTypes.hasMarkers(traceOut)) {

src/traces/scattergl/defaults.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
3838

3939
if(subTypes.hasLines(traceOut)) {
4040
coerce('connectgaps');
41-
handleLineDefaults(traceIn, traceOut, defaultColor, coerce);
41+
handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce);
4242
}
4343

4444
if(subTypes.hasMarkers(traceOut)) {

src/traces/scattermapbox/calc.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ var Lib = require('../../lib');
1515
var hasColorscale = require('../../components/colorscale/has_colorscale');
1616
var makeColorScaleFn = require('../../components/colorscale/make_scale_function');
1717
var subtypes = require('../scatter/subtypes');
18-
var calcMarkerColorscale = require('../scatter/marker_colorscale_calc');
18+
var calcMarkerColorscale = require('../scatter/colorscale_calc');
1919
var makeBubbleSizeFn = require('../scatter/make_bubble_size_func');
2020

2121

src/traces/scatterternary/calc.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ var Axes = require('../../plots/cartesian/axes');
1515
var Lib = require('../../lib');
1616

1717
var subTypes = require('../scatter/subtypes');
18-
var calcMarkerColorscale = require('../scatter/marker_colorscale_calc');
18+
var calcColorscale = require('../scatter/colorscale_calc');
1919

2020
var dataArrays = ['a', 'b', 'c'];
2121
var arraysToFill = {a: ['b', 'c'], b: ['a', 'c'], c: ['a', 'b']};
@@ -88,7 +88,7 @@ module.exports = function calc(gd, trace) {
8888
}
8989
}
9090

91-
calcMarkerColorscale(trace);
91+
calcColorscale(trace);
9292

9393
// this has migrated up from arraysToCalcdata as we have a reference to 's' here
9494
if(typeof s !== undefined) Lib.mergeArray(s, cd, 'ms');

src/traces/scatterternary/defaults.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
6868
coerce('mode', defaultMode);
6969

7070
if(subTypes.hasLines(traceOut)) {
71-
handleLineDefaults(traceIn, traceOut, defaultColor, coerce);
71+
handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce);
7272
handleLineShapeDefaults(traceIn, traceOut, coerce);
7373
coerce('connectgaps');
7474
}
Loading
Loading
Loading
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
{
2+
"data": [
3+
{
4+
"x":[-4,-3,-2,-1,0,1,2,3,4,5,6],
5+
"y":[11,10,9,7,5,6,4,2,3,1,3],
6+
"z":[4,5,4,3,2,1,0,-1,-2,-3,-4],
7+
"mode": "lines",
8+
"line": {
9+
"width": 5,
10+
"color": [
11+
"#67001f",
12+
"#b2182b",
13+
"#d6604d",
14+
"#f4a582",
15+
"#fddbc7",
16+
"#d1e5f0",
17+
"#92c5de",
18+
"#4393c3",
19+
"#2166ac",
20+
"#053061"
21+
]
22+
},
23+
"type":"scatter3d"
24+
},
25+
{
26+
"x":[-4,-3,-2,-1,0,1,2,3,4,5,6],
27+
"y":[7,5,6,4,2,3,1,3,-1,-4,-2],
28+
"z":[2,3,4,5,4,3,2,1,0,-1,-2],
29+
"mode": "lines+markers",
30+
"line": {
31+
"width": 5,
32+
"color": [
33+
"#67001f",
34+
"#b2182b",
35+
"#d6604d",
36+
"#f4a582",
37+
"#fddbc7",
38+
"#d1e5f0",
39+
"#92c5de",
40+
"#4393c3",
41+
"#2166ac",
42+
"#053061"
43+
]
44+
},
45+
"type":"scatter3d"
46+
}
47+
],
48+
"layout": {
49+
"title": "Markers should default to line color",
50+
"height":758,
51+
"width":1310
52+
}
53+
}

0 commit comments

Comments
 (0)