Skip to content

Commit 2c60123

Browse files
committed
plotly 1.41 features
1 parent acaebc1 commit 2c60123

17 files changed

+94
-43
lines changed

Diff for: dev/percy/panelTest.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373
"sizesrc": "x1",
7474
"sizemode": "diameter"
7575
},
76-
"fill": "tozerox",
76+
"stackgroup": 1,
7777
"mode": "lines+markers+text",
7878
"line": {
7979
"dash": "solid",

Diff for: package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"fast-isnumeric": "^1.1.1",
1616
"immutability-helper": "^2.7.1",
1717
"plotly-icons": "1.2.2",
18-
"plotly.js": "1.40.1",
18+
"plotly.js": "1.41.0",
1919
"prop-types": "^15.5.10",
2020
"raf": "^3.4.0",
2121
"react-color": "^2.13.8",

Diff for: src/components/containers/__tests__/Layout-test.js

+9-10
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,16 @@ Layouts.forEach(Layout => {
1313
describe(`<${Layout.displayName}>`, () => {
1414
it(`wraps container with fullValue pointing to gd._fullLayout`, () => {
1515
const wrapper = mount(
16-
<Editor {...fixtures.scatter({layout: {width: 100}})}>
16+
<Editor {...fixtures.scatter({layout: {height: 100}})}>
1717
<PlotlyPanel>
1818
<Layout>
19-
<Numeric label="Width" min={100} step={10} attr="width" />
19+
<Numeric label="Height" min={100} step={10} attr="height" />
2020
</Layout>
2121
</PlotlyPanel>
2222
</Editor>
2323
)
24-
.find('[attr="width"]')
24+
.find('[attr="height"]')
2525
.find(NumericInput);
26-
2726
expect(wrapper.prop('value')).toBe(100);
2827
});
2928

@@ -32,22 +31,22 @@ Layouts.forEach(Layout => {
3231
const wrapper = mount(
3332
<Editor
3433
beforeUpdateLayout={beforeUpdateLayout}
35-
{...fixtures.scatter({layout: {width: 100}})}
34+
{...fixtures.scatter({layout: {height: 100}})}
3635
>
3736
<PlotlyPanel>
3837
<Layout>
39-
<Numeric label="Width" min={100} step={10} attr="width" />
38+
<Numeric label="Height" min={100} step={10} attr="height" />
4039
</Layout>
4140
</PlotlyPanel>
4241
</Editor>
4342
)
44-
.find('[attr="width"]')
43+
.find('[attr="height"]')
4544
.find(NumericInput);
4645

47-
const widthUpdate = 200;
48-
wrapper.prop('onChange')(widthUpdate);
46+
const heightUpdate = 200;
47+
wrapper.prop('onChange')(heightUpdate);
4948
const payload = beforeUpdateLayout.mock.calls[0][0];
50-
expect(payload).toEqual({update: {width: widthUpdate}});
49+
expect(payload).toEqual({update: {height: heightUpdate}});
5150
});
5251
});
5352
});

Diff for: src/components/fields/TraceSelector.js

+3-6
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,11 @@ import {
77
plotlyTraceToCustomTrace,
88
computeTraceOptionsFromSchema,
99
} from 'lib';
10+
import {TRACES_WITH_GL} from 'lib/constants';
1011
import {TraceTypeSelector, TraceTypeSelectorButton, RadioBlocks} from 'components/widgets';
1112
import Field from './Field';
1213
import {CogIcon} from 'plotly-icons';
1314

14-
export const glAvailable = type => {
15-
return ['scatter', 'scatterpolar', 'scattergl', 'scatterpolargl'].includes(type);
16-
};
17-
1815
class TraceSelector extends Component {
1916
constructor(props, context) {
2017
super(props, context);
@@ -125,14 +122,14 @@ class TraceSelector extends Component {
125122
})
126123
}
127124
/>
128-
{!glAvailable(this.props.container.type) ? (
125+
{!TRACES_WITH_GL.includes(this.props.container.type) ? (
129126
''
130127
) : (
131128
<CogIcon className="menupanel__icon" onClick={this.toggleGlControls} />
132129
)}
133130
</div>
134131
</Field>
135-
{!(glAvailable(this.props.container.type) && this.state.showGlControls) ? (
132+
{!(TRACES_WITH_GL.includes(this.props.container.type) && this.state.showGlControls) ? (
136133
''
137134
) : (
138135
<Field label={_('Rendering')}>

Diff for: src/components/fields/__tests__/TraceSelector-test.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ describe('TraceSelector', () => {
147147
});
148148
});
149149

150-
it('updates type=scatter fill=tozeroy when type=area', () => {
150+
it('updates type=scatter stackgroup=1 when type=area', () => {
151151
const beforeUpdateTraces = jest.fn();
152152
const editorProps = {
153153
...fixtures.scatter({data: [{type: 'scatter', mode: 'markers'}]}),
@@ -166,6 +166,6 @@ describe('TraceSelector', () => {
166166
innerDropdown.prop('onChange')('area');
167167

168168
const payload = beforeUpdateTraces.mock.calls[0][0];
169-
expect(payload.update).toEqual({fill: 'tozeroy', type: 'scatter'});
169+
expect(payload.update).toEqual({stackgroup: 1, type: 'scatter'});
170170
});
171171
});

Diff for: src/components/fields/derived.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -541,7 +541,7 @@ export const HoverInfo = connectToContainer(UnconnectedFlaglist, {
541541
{label: _('B'), value: 'b'},
542542
{label: _('C'), value: 'c'},
543543
];
544-
} else if (['scatterpolar', 'scatterpolargl'].includes(container.type)) {
544+
} else if (['scatterpolar', 'scatterpolargl', 'barpolar'].includes(container.type)) {
545545
options = [{label: _('R'), value: 'r'}, {label: _('Theta'), value: 'theta'}];
546546
} else if (container.type === 'pie') {
547547
options = [

Diff for: src/components/widgets/TraceTypeSelector.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import React, {Component} from 'react';
22
import PropTypes from 'prop-types';
33
import {SearchIcon, ThumnailViewIcon, GraphIcon} from 'plotly-icons';
44
import Modal from 'components/containers/Modal';
5-
import {glAvailable} from 'components/fields/TraceSelector';
65
import {traceTypeToPlotlyInitFigure, renderTraceIcon, plotlyTraceToCustomTrace} from 'lib';
6+
import {TRACES_WITH_GL} from 'lib/constants';
77

88
const renderActionItems = (actionItems, item) =>
99
actionItems
@@ -83,8 +83,8 @@ class TraceTypeSelector extends Component {
8383
} = this.props;
8484
const computedValue = traceTypeToPlotlyInitFigure(value);
8585
if (
86-
(type.endsWith('gl') || (!glAvailable(type) && glByDefault)) &&
87-
glAvailable(computedValue.type) &&
86+
(type.endsWith('gl') || (!TRACES_WITH_GL.includes(type) && glByDefault)) &&
87+
TRACES_WITH_GL.includes(computedValue.type) &&
8888
!computedValue.type.endsWith('gl')
8989
) {
9090
computedValue.type += 'gl';

Diff for: src/default_panels/GraphCreatePanel.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ const GraphCreatePanel = (props, {localize: _, setPanel}) => {
108108
<DataSelector label={_('Headers')} attr="header.values" />
109109
<DataSelector label={_('Columns')} attr="cells.values" />
110110

111-
<TraceTypeSection traceTypes={['scatterpolar', 'scatterpolargl']} mode="trace">
111+
<TraceTypeSection traceTypes={['scatterpolar', 'scatterpolargl', 'barpolar']} mode="trace">
112112
<DataSelector label={_('Radius')} attr="r" />
113113
<DataSelector label={_('Theta')} attr="theta" />
114114
<Dropdown

Diff for: src/default_panels/GraphSubplotsPanel.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
Numeric,
1414
ColorPicker,
1515
VisibilitySelect,
16+
NumericFraction,
1617
} from '../components';
1718
import {TRACE_TO_AXIS} from '../lib/constants';
1819

@@ -211,8 +212,9 @@ const GraphSubplotsPanel = (props, {localize: _}) => (
211212
</PlotlySection>
212213

213214
<PlotlySection name={_('Polar Sector')}>
214-
<Numeric label={_('Min')} attr="sector[0]" max={360} min={-360} showSlider />
215-
<Numeric label={_('Max')} attr="sector[1]" max={360} min={-360} showSlider />
215+
<Numeric label={_('Min')} attr="sector[0]" min={-360} max={360} showSlider />
216+
<Numeric label={_('Max')} attr="sector[1]" min={-360} max={360} showSlider />
217+
<NumericFraction label={_('Hole')} attr="hole" min={0} max={100} showSlider />
216218
</PlotlySection>
217219
</SubplotAccordion>
218220
);

Diff for: src/default_panels/StyleLayoutPanel.js

+11
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
TraceRequiredPanel,
1313
VisibilitySelect,
1414
HovermodeDropdown,
15+
Flaglist,
1516
} from '../components';
1617
import {HoverColor} from '../components/fields/derived';
1718

@@ -89,6 +90,16 @@ const StyleLayoutPanel = (props, {localize: _}) => (
8990
clearable={false}
9091
/>
9192
</PlotlySection>
93+
<PlotlySection name={_('Click')} attr="clickmode">
94+
<Flaglist
95+
label={_('Mode')}
96+
attr="clickmode"
97+
options={[
98+
{label: _('Click Event'), value: 'event'},
99+
{label: _('Select Data Point'), value: 'select'},
100+
]}
101+
/>
102+
</PlotlySection>
92103
<PlotlySection name={_('Hover')}>
93104
<HovermodeDropdown label={_('Mode')} attr="hovermode">
94105
<HoverColor

Diff for: src/default_panels/StyleTracesPanel.js

+32
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,12 @@ const StyleTracesPanel = (props, {localize: _}) => (
195195
<BinningNumeric label={_('Y Bin Size')} attr="ybins.size" axis="y" />
196196
<Numeric label={_('Max Y Bins')} attr="nbinsy" />
197197
</PlotlySection>
198+
<PlotlySection label={_('Bar Position')}>
199+
<Numeric label={_('Base')} attr="base" />
200+
<Numeric label={_('Offset')} attr="offset" />
201+
<Numeric label={_('Width')} attr="width" />
202+
</PlotlySection>
203+
198204
<TraceMarkerSection>
199205
<Radio
200206
label={_('Order')}
@@ -349,6 +355,31 @@ const StyleTracesPanel = (props, {localize: _}) => (
349355
<ContourNumeric label={_('Min Contour')} attr="contours.start" />
350356
<ContourNumeric label={_('Max Contour')} attr="contours.end" />
351357
</PlotlySection>
358+
<TraceTypeSection name={_('Stacking')} traceTypes={['scatter']} mode="trace">
359+
<GroupCreator label={_('Group')} prefix={_('Stack')} attr="stackgroup" />
360+
<Radio
361+
label={_('Gaps')}
362+
attr="stackgaps"
363+
options={[
364+
{label: _('Infer Zero'), value: 'infer zero'},
365+
{label: _('Interpolate'), value: 'interpolate'},
366+
]}
367+
/>
368+
<Radio
369+
label={_('Orientation')}
370+
attr="orientation"
371+
options={[{label: _('Horizontal'), value: 'h'}, {label: _('Vertical'), value: 'v'}]}
372+
/>
373+
<Radio
374+
label={_('Normalization')}
375+
attr="groupnorm"
376+
options={[
377+
{label: _('None'), value: ''},
378+
{label: _('Fraction'), value: 'fraction'},
379+
{label: _('Percent'), value: 'percent'},
380+
]}
381+
/>
382+
</TraceTypeSection>
352383
<TraceTypeSection
353384
name={_('Lines')}
354385
traceTypes={[
@@ -397,6 +428,7 @@ const StyleTracesPanel = (props, {localize: _}) => (
397428
'scattergl',
398429
'scatterpolar',
399430
'scatterpolargl',
431+
'barpolar',
400432
'pie',
401433
'scatter3d',
402434
'scatterternary',

Diff for: src/lib/__tests__/connectLayoutToPlot-test.js

+9-9
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@ Layouts.forEach(Layout => {
1313
describe(`<${Layout.displayName}>`, () => {
1414
it(`wraps container with fullValue pointing to gd._fullLayout`, () => {
1515
const wrapper = mount(
16-
<Editor {...fixtures.scatter({layout: {width: 100}})}>
16+
<Editor {...fixtures.scatter({layout: {height: 100}})}>
1717
<PlotlyPanel>
1818
<Layout>
19-
<Numeric label="Width" step={10} attr="width" />
19+
<Numeric label="Height" step={10} attr="height" />
2020
</Layout>
2121
</PlotlyPanel>
2222
</Editor>
2323
)
24-
.find('[attr="width"]')
24+
.find('[attr="height"]')
2525
.find(NumericInput);
2626

2727
expect(wrapper.prop('value')).toBe(100);
@@ -32,22 +32,22 @@ Layouts.forEach(Layout => {
3232
const wrapper = mount(
3333
<Editor
3434
beforeUpdateLayout={beforeUpdateLayout}
35-
{...fixtures.scatter({layout: {width: 100}})}
35+
{...fixtures.scatter({layout: {height: 100}})}
3636
>
3737
<PlotlyPanel>
3838
<Layout>
39-
<Numeric label="Width" step={10} attr="width" />
39+
<Numeric label="Height" step={10} attr="height" />
4040
</Layout>
4141
</PlotlyPanel>
4242
</Editor>
4343
)
44-
.find('[attr="width"]')
44+
.find('[attr="height"]')
4545
.find(NumericInput);
4646

47-
const widthUpdate = 200;
48-
wrapper.prop('onChange')(widthUpdate);
47+
const heightUpdate = 200;
48+
wrapper.prop('onChange')(heightUpdate);
4949
const payload = beforeUpdateLayout.mock.calls[0][0];
50-
expect(payload).toEqual({update: {width: widthUpdate}});
50+
expect(payload).toEqual({update: {height: heightUpdate}});
5151
});
5252

5353
it(`automatically computes min and max defaults`, () => {

Diff for: src/lib/computeTraceOptionsFromSchema.js

+4
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,10 @@ function computeTraceOptionsFromSchema(schema, _, context) {
128128
value: 'scatterpolargl',
129129
label: _('Polar Scatter GL'),
130130
},
131+
{
132+
value: 'barpolar',
133+
label: _('Polar Bar'),
134+
},
131135
].filter(obj => traceTypes.indexOf(obj.value) !== -1);
132136

133137
const traceIndex = traceType => traceOptions.findIndex(opt => opt.value === traceType);

Diff for: src/lib/constants.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ export const TRACE_TO_AXIS = {
7373
gl3d: ['scatter3d', 'surface', 'mesh3d', 'cone', 'streamtube'],
7474
geo: ['scattergeo', 'choropleth'],
7575
mapbox: ['scattermapbox'],
76-
polar: ['scatterpolar', 'scatterpolargl'],
76+
polar: ['scatterpolar', 'scatterpolargl', 'barpolar'],
7777
};
7878

7979
// Note: scene, and xaxis/yaxis were added for convenience sake even though they're not subplot types
@@ -117,6 +117,8 @@ export const TRANSFORMABLE_TRACES = [
117117
'histogram2d',
118118
];
119119

120+
export const TRACES_WITH_GL = ['scatter', 'scatterpolar', 'scattergl', 'scatterpolargl'];
121+
120122
export const COLORS = {
121123
charcoal: '#444444',
122124
white: '#ffffff',

Diff for: src/lib/customTraceType.js

+3-4
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ export function plotlyTraceToCustomTrace(trace) {
1616

1717
if (
1818
(type === 'scatter' || type === 'scattergl') &&
19-
['tozeroy', 'tozerox', 'tonexty', 'tonextx', 'toself', 'tonext'].includes(trace.fill)
19+
((trace.stackgroup !== null && trace.stackgroup !== undefined) || // eslint-disable-line no-undefined
20+
['tozeroy', 'tozerox', 'tonexty', 'tonextx', 'toself', 'tonext'].includes(trace.fill))
2021
) {
2122
return 'area';
2223
} else if (
@@ -37,7 +38,7 @@ export function traceTypeToPlotlyInitFigure(traceType, gl = '') {
3738
case 'scatter':
3839
return {type: 'scatter' + gl, mode: 'markers', fill: 'none'};
3940
case 'area':
40-
return {type: 'scatter' + gl, fill: 'tozeroy'};
41+
return {type: 'scatter' + gl, mode: 'lines', stackgroup: 1};
4142
case 'scatterpolar':
4243
return {type: 'scatterpolar' + gl};
4344
case 'ohlc':
@@ -66,8 +67,6 @@ export function traceTypeToPlotlyInitFigure(traceType, gl = '') {
6667
case 'violin':
6768
return {
6869
type: 'violin',
69-
box: {visible: false},
70-
meanline: {visible: false},
7170
bandwidth: 0,
7271
};
7372
case 'line3d':

Diff for: src/lib/test-utils.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ const fixtures = {
6565
{
6666
type: 'scatter',
6767
mode: 'markers+lines',
68-
fill: 'tozeroy',
68+
stackgroup: 1,
6969
xsrc: 'x1',
7070
ysrc: 'y1',
7171
},
@@ -136,7 +136,7 @@ function setupGraphDiv(figure) {
136136

137137
mockMissingSvgApis();
138138

139-
plotly.plot(gd, figure);
139+
plotly.newPlot(gd, figure);
140140
return gd;
141141
}
142142

Diff for: src/lib/traceTypes.js

+5
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,11 @@ export const traceTypes = _ => [
177177
label: _('Polar Scatter'),
178178
category: chartCategory(_).SPECIALIZED,
179179
},
180+
{
181+
value: 'barpolar',
182+
label: _('Polar Bar'),
183+
category: chartCategory(_).SPECIALIZED,
184+
},
180185
{
181186
value: 'scatterternary',
182187
label: _('Ternary Scatter'),

0 commit comments

Comments
 (0)