Skip to content

Commit f9a8a57

Browse files
authored
Merge pull request #840 from plotly/v0.35.2
V0.35.2
2 parents b73380b + 900d761 commit f9a8a57

File tree

12 files changed

+310
-177
lines changed

12 files changed

+310
-177
lines changed

dev/dataSources.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1745,4 +1745,5 @@ export default {
17451745
],
17461746
'countries iso': ['AGO', 'ALB', 'ARE', 'ARG', 'ARM', 'AUS', 'AUT', 'AZE'],
17471747
states: ['AL', 'AK', 'AZ', 'AR', 'CA', 'CO', 'CT', 'DE', 'FL', 'GA'],
1748+
textpositions: ['bottom', 'bottom right', 'left', 'right', 'left'],
17481749
};

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "react-chart-editor",
33
"description": "plotly.js chart editor react component UI",
4-
"version": "0.35.1",
4+
"version": "0.35.2",
55
"author": "Plotly, Inc.",
66
"bugs": {
77
"url": "https://github.com/plotly/react-chart-editor/issues"
@@ -126,4 +126,4 @@
126126
"watch": "babel src --watch --out-dir lib --source-maps | node-sass -w src/styles/main.scss lib/react-chart-editor.css",
127127
"watch-test": "jest --watch"
128128
}
129-
}
129+
}

scripts/translationKeys/combined-translation-keys.txt

Lines changed: 68 additions & 63 deletions
Large diffs are not rendered by default.

scripts/translationKeys/translation-keys.txt

Lines changed: 68 additions & 63 deletions
Large diffs are not rendered by default.

src/components/fields/TextPosition.js

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import Dropdown from './Dropdown';
2+
import RadioBlocks from '../widgets/RadioBlocks';
3+
import Field from './Field';
4+
import PropTypes from 'prop-types';
5+
import React, {Component, Fragment} from 'react';
6+
import {connectToContainer} from 'lib';
7+
import Info from './Info';
8+
import DataSelector from './DataSelector';
9+
10+
export class UnconnectedTextPosition extends Component {
11+
constructor(props) {
12+
super(props);
13+
this.state = {
14+
posType: typeof props.fullValue === 'string' ? 'simple' : 'custom',
15+
};
16+
}
17+
18+
render() {
19+
const _ = this.context.localize;
20+
const radioOptions = [
21+
{label: _('All'), value: 'simple'},
22+
{label: _('Custom'), value: 'custom'},
23+
];
24+
const control =
25+
this.state.posType === 'simple' ? (
26+
<Fragment>
27+
<Info>
28+
{_(
29+
'This will position all text values on the plot according to the selected position.'
30+
)}
31+
</Info>
32+
<Dropdown options={this.props.options} attr="textposition" />
33+
</Fragment>
34+
) : (
35+
<Fragment>
36+
<Info>
37+
<div>
38+
{_(
39+
'This will position text values individually, according to the provided data positions array. '
40+
)}
41+
</div>
42+
</Info>
43+
<DataSelector attr="textposition" />
44+
<Info>
45+
<div>{_('("Top", "Middle", "Bottom") + ("Left", "Center", "Right")')}</div>
46+
</Info>
47+
</Fragment>
48+
);
49+
50+
return (
51+
<Field {...this.props}>
52+
<RadioBlocks
53+
options={radioOptions}
54+
activeOption={this.state.posType}
55+
onOptionChange={value => {
56+
this.setState({posType: value});
57+
if (value === 'simple') {
58+
this.props.updatePlot('middle center');
59+
} else {
60+
this.props.updateContainer({textpositionsrc: null});
61+
}
62+
}}
63+
/>
64+
{control}
65+
</Field>
66+
);
67+
}
68+
}
69+
70+
UnconnectedTextPosition.propTypes = {
71+
...Field.propTypes,
72+
options: PropTypes.array,
73+
fullValue: PropTypes.oneOfType([PropTypes.array, PropTypes.string]),
74+
};
75+
76+
UnconnectedTextPosition.contextTypes = {
77+
localize: PropTypes.func,
78+
};
79+
80+
export default connectToContainer(UnconnectedTextPosition, {
81+
modifyPlotProps: (props, context, plotProps) => {
82+
const {localize: _} = context;
83+
let options = [
84+
{label: _('Top Left'), value: 'top left'},
85+
{label: _('Top Center'), value: 'top center'},
86+
{label: _('Top Right'), value: 'top right'},
87+
{label: _('Middle Left'), value: 'middle left'},
88+
{label: _('Middle Center'), value: 'middle center'},
89+
{label: _('Middle Right'), value: 'middle right'},
90+
{label: _('Bottom Left'), value: 'bottom left'},
91+
{label: _('Bottom Center'), value: 'bottom center'},
92+
{label: _('Bottom Right'), value: 'bottom right'},
93+
];
94+
if (context.container.type === 'pie' || context.container.type === 'bar') {
95+
options = [
96+
{label: _('Inside'), value: 'inside'},
97+
{label: _('Outside'), value: 'outside'},
98+
{label: _('Auto'), value: 'auto'},
99+
{label: _('None'), value: 'none'},
100+
];
101+
}
102+
plotProps.options = options;
103+
plotProps.clearable = false;
104+
},
105+
});

src/components/fields/derived.js

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -494,33 +494,6 @@ function computeAxesRefOptions(axes, propsAttr) {
494494
return options;
495495
}
496496

497-
export const TextPosition = connectToContainer(UnconnectedDropdown, {
498-
modifyPlotProps: (props, context, plotProps) => {
499-
const {localize: _} = context;
500-
let options = [
501-
{label: _('Top Left'), value: 'top left'},
502-
{label: _('Top Center'), value: 'top center'},
503-
{label: _('Top Right'), value: 'top right'},
504-
{label: _('Middle Left'), value: 'middle left'},
505-
{label: _('Middle Center'), value: 'middle center'},
506-
{label: _('Middle Right'), value: 'middle right'},
507-
{label: _('Bottom Left'), value: 'bottom left'},
508-
{label: _('Bottom Center'), value: 'bottom center'},
509-
{label: _('Bottom Right'), value: 'bottom right'},
510-
];
511-
if (context.container.type === 'pie' || context.container.type === 'bar') {
512-
options = [
513-
{label: _('Inside'), value: 'inside'},
514-
{label: _('Outside'), value: 'outside'},
515-
{label: _('Auto'), value: 'auto'},
516-
{label: _('None'), value: 'none'},
517-
];
518-
}
519-
plotProps.options = options;
520-
plotProps.clearable = false;
521-
},
522-
});
523-
524497
export const TextInfo = connectToContainer(UnconnectedFlaglist, {
525498
modifyPlotProps: (props, context, plotProps) => {
526499
const {localize: _, container} = context;

src/components/fields/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import RectanglePositioner from './RectanglePositioner';
3434
import LocationSelector from './LocationSelector';
3535
import AxisInterval from './AxisInterval';
3636
import DateTimePicker from './DateTimePicker';
37+
import TextPosition from './TextPosition';
3738

3839
import {
3940
AnnotationArrowRef,
@@ -57,7 +58,6 @@ import {
5758
TraceOrientation,
5859
AxisOverlayDropdown,
5960
AxisSide,
60-
TextPosition,
6161
ShowInLegend,
6262
HoveronDropdown,
6363
HovermodeDropdown,

src/default_panels/StyleAxesPanel.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ class StyleAxesPanel extends Component {
198198
attr="exponentformat"
199199
clearable={false}
200200
options={[
201-
{label: _('None'), value: '000'},
201+
{label: _('None'), value: 'none'},
202202
{label: _('e+6'), value: 'e'},
203203
{label: _('E+6'), value: 'E'},
204204
{label: _('x10^6'), value: 'power'},

src/default_panels/StyleLayoutPanel.js

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -174,17 +174,20 @@ const StyleLayoutPanel = (props, {localize: _}) => (
174174
{_(
175175
'You can refer to the items in this column in any text fields of the editor like so: '
176176
)}
177-
<span
178-
style={{
179-
lineHeight: '20px',
180-
backgroundColor: '#eadef7',
181-
borderRadius: '2px',
182-
fontStyle: 'italic',
183-
}}
184-
>
185-
{'%{meta[0]}'}
186-
</span>
187-
{' .'}
177+
<div>
178+
<span
179+
style={{
180+
lineHeight: '20px',
181+
backgroundColor: '#eadef7',
182+
borderRadius: '2px',
183+
fontStyle: 'italic',
184+
letterSpacing: '1px',
185+
}}
186+
>
187+
{'%{meta[0]}'}
188+
</span>
189+
{' .'}
190+
</div>
188191
</p>
189192
{_('Note: item count starts at 0.')}
190193
</Info>

src/default_panels/StyleNotesPanel.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,28 @@ const StyleNotesPanel = (props, {localize: _}) => (
2424
<Numeric label={_('Font Size')} attr="font.size" units="px" />
2525
<ColorPicker label={_('Font Color')} attr="font.color" />
2626
<Numeric label={_('Angle')} attr="textangle" units="°" />
27+
<Dropdown
28+
label={_('Horizontal Alignment')}
29+
clearable={false}
30+
attr="align"
31+
options={[
32+
{label: _('Left'), value: 'left'},
33+
{label: _('Center'), value: 'center'},
34+
{label: _('Right'), value: 'right'},
35+
]}
36+
/>
37+
<Dropdown
38+
label={_('Vertical Alignment')}
39+
clearable={false}
40+
attr="valign"
41+
options={[
42+
{label: _('Left'), value: 'left'},
43+
{label: _('Center'), value: 'center'},
44+
{label: _('Right'), value: 'right'},
45+
]}
46+
/>
2747
</PlotlySection>
48+
2849
<PlotlySection name={_('Arrow')}>
2950
<Radio
3051
attr="showarrow"

src/lib/__tests__/dereference-test.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import dereference from '../dereference';
2+
23
/* eslint-disable no-magic-numbers */
34
describe('dereference', () => {
45
it('does not search into data arrays', () => {
@@ -65,4 +66,13 @@ describe('dereference', () => {
6566
expect(container[0].z[2][0]).toBe(3);
6667
expect(container[0].z[2][1]).toBe(2);
6768
});
69+
70+
// TO DO: dereference all of layout
71+
it('can dereference top level layout keys', () => {
72+
const container = {metasrc: 'x1', xaxis: {ticktext: 'x2'}};
73+
dereference(container, {x1: ['yes!'], x2: ['some', 'text']});
74+
75+
expect(Array.isArray(container.meta)).toBe(true);
76+
expect(container.meta[0]).toBe('yes!');
77+
});
6878
});

src/lib/dereference.js

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ export default function dereference(container, dataSources, config = {deleteKeys
1010
}
1111

1212
const dataKey = key.replace(SRC_ATTR_PATTERN, '');
13-
const traceType = parent.type;
1413

1514
let srcRef = config.toSrc ? config.toSrc(parent[key]) : parent[key];
1615

@@ -19,7 +18,7 @@ export default function dereference(container, dataSources, config = {deleteKeys
1918
srcRef = [srcRef];
2019
}
2120

22-
let data = srcRef.map(ref => {
21+
let dereferencedData = srcRef.map(ref => {
2322
if (config.deleteKeys && !(ref in dataSources)) {
2423
delete parent[dataKey];
2524
}
@@ -28,18 +27,29 @@ export default function dereference(container, dataSources, config = {deleteKeys
2827

2928
// remove extra data wrapping
3029
if (srcRef.length === 1) {
31-
data = data[0];
30+
dereferencedData = dereferencedData[0];
3231
}
3332

34-
if (!Array.isArray(data)) {
33+
if (!Array.isArray(dereferencedData)) {
3534
return;
3635
}
3736

38-
parent[dataKey] = maybeTransposeData(data, srcPath, traceType);
37+
if (Array.isArray(container)) {
38+
// Case where we were originally given data to dereference
39+
const traceType = parent.type;
40+
parent[dataKey] = maybeTransposeData(dereferencedData, srcPath, traceType);
41+
} else {
42+
// This means we're dereferencing layout
43+
parent[dataKey] = dereferencedData;
44+
}
3945
};
4046

41-
walkObject(container, replacer, {
42-
walkArraysMatchingKeys: ['data', 'transforms'],
43-
pathType: 'nestedProperty',
44-
});
47+
if (Array.isArray(container)) {
48+
walkObject(container, replacer, {
49+
walkArraysMatchingKeys: ['data', 'transforms'],
50+
pathType: 'nestedProperty',
51+
});
52+
} else {
53+
walkObject(container, replacer, {pathType: 'nestedProperty'});
54+
}
4555
}

0 commit comments

Comments
 (0)