Skip to content
This repository was archived by the owner on Jun 3, 2024. It is now read-only.

Commit 8a36e62

Browse files
authored
Merge pull request #850 from sleighsoft/dev
Enhancement: add property Graph.prependData to support Plotly.prependTraces
2 parents 93e3872 + 251b361 commit 8a36e62

File tree

8 files changed

+380
-209
lines changed

8 files changed

+380
-209
lines changed

Diff for: CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22
All notable changes to this project will be documented in this file.
33
This project adheres to [Semantic Versioning](http://semver.org/).
44

5+
## [Unreleased]
6+
### Added
7+
- [#850](https://github.com/plotly/dash-core-components/pull/850) Add property `prependData` to `Graph` to support `Plotly.prependTraces`
8+
+ refactored the existing `extendTraces` API to be a single `mergeTraces` API that can handle both `prepend` as well as `extend`.
9+
510
## [1.12.0] - 2020-09-03
611
### Updated
712
- [#858](https://github.com/plotly/dash-core-components/pull/858)

Diff for: src/components/Graph.react.js

+53-10
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
privateDefaultProps,
1010
} from '../fragments/Graph.privateprops';
1111

12-
const EMPTY_EXTEND_DATA = [];
12+
const EMPTY_DATA = [];
1313

1414
/**
1515
* Graph can be used to render any plotly.js-powered data visualization.
@@ -22,13 +22,19 @@ class PlotlyGraph extends Component {
2222
super(props);
2323

2424
this.state = {
25+
prependData: [],
2526
extendData: [],
2627
};
2728

28-
this.clearExtendData = this.clearExtendData.bind(this);
29+
this.clearState = this.clearState.bind(this);
2930
}
3031

3132
componentDidMount() {
33+
if (this.props.prependData) {
34+
this.setState({
35+
prependData: [this.props.prependData],
36+
});
37+
}
3238
if (this.props.extendData) {
3339
this.setState({
3440
extendData: [this.props.extendData],
@@ -38,15 +44,37 @@ class PlotlyGraph extends Component {
3844

3945
componentWillUnmount() {
4046
this.setState({
47+
prependData: [],
4148
extendData: [],
4249
});
4350
}
4451

4552
UNSAFE_componentWillReceiveProps(nextProps) {
53+
let prependData = this.state.prependData.slice(0);
54+
55+
if (this.props.figure !== nextProps.figure) {
56+
prependData = EMPTY_DATA;
57+
}
58+
59+
if (
60+
nextProps.prependData &&
61+
this.props.prependData !== nextProps.prependData
62+
) {
63+
prependData.push(nextProps.prependData);
64+
} else {
65+
prependData = EMPTY_DATA;
66+
}
67+
68+
if (prependData !== EMPTY_DATA) {
69+
this.setState({
70+
prependData,
71+
});
72+
}
73+
4674
let extendData = this.state.extendData.slice(0);
4775

4876
if (this.props.figure !== nextProps.figure) {
49-
extendData = EMPTY_EXTEND_DATA;
77+
extendData = EMPTY_DATA;
5078
}
5179

5280
if (
@@ -55,22 +83,23 @@ class PlotlyGraph extends Component {
5583
) {
5684
extendData.push(nextProps.extendData);
5785
} else {
58-
extendData = EMPTY_EXTEND_DATA;
86+
extendData = EMPTY_DATA;
5987
}
6088

61-
if (extendData !== EMPTY_EXTEND_DATA) {
89+
if (extendData !== EMPTY_DATA) {
6290
this.setState({
6391
extendData,
6492
});
6593
}
6694
}
6795

68-
clearExtendData() {
69-
this.setState(({extendData}) => {
96+
clearState(dataKey) {
97+
this.setState(props => {
98+
var data = props[dataKey];
7099
const res =
71-
extendData && extendData.length
100+
data && data.length
72101
? {
73-
extendData: EMPTY_EXTEND_DATA,
102+
[dataKey]: EMPTY_DATA,
74103
}
75104
: undefined;
76105

@@ -82,8 +111,9 @@ class PlotlyGraph extends Component {
82111
return (
83112
<ControlledPlotlyGraph
84113
{...this.props}
114+
prependData={this.state.prependData}
85115
extendData={this.state.extendData}
86-
clearExtendData={this.clearExtendData}
116+
clearState={this.clearState}
87117
/>
88118
);
89119
}
@@ -191,6 +221,18 @@ PlotlyGraph.propTypes = {
191221
*/
192222
extendData: PropTypes.oneOfType([PropTypes.array, PropTypes.object]),
193223

224+
/**
225+
* Data that should be prepended to existing traces. Has the form
226+
* `[updateData, traceIndices, maxPoints]`, where `updateData` is an object
227+
* containing the data to prepend, `traceIndices` (optional) is an array of
228+
* trace indices that should be prepended, and `maxPoints` (optional) is
229+
* either an integer defining the maximum number of points allowed or an
230+
* object with key:value pairs matching `updateData`
231+
* Reference the Plotly.prependTraces API for full usage:
232+
* https://plotly.com/javascript/plotlyjs-function-reference/#plotlyprependtraces
233+
*/
234+
prependData: PropTypes.oneOfType([PropTypes.array, PropTypes.object]),
235+
194236
/**
195237
* Data from latest restyle event which occurs
196238
* when the user toggles a legend item, changes
@@ -523,6 +565,7 @@ PlotlyGraph.defaultProps = {
523565
hoverData: null,
524566
selectedData: null,
525567
relayoutData: null,
568+
prependData: null,
526569
extendData: null,
527570
restyleData: null,
528571
figure: {

Diff for: src/fragments/Graph.react.js

+23-14
Original file line numberDiff line numberDiff line change
@@ -188,18 +188,16 @@ class PlotlyGraph extends Component {
188188
});
189189
}
190190

191-
extend(props) {
192-
const {clearExtendData, extendData: extendDataArray} = props;
191+
mergeTraces(props, dataKey, plotlyFnKey) {
192+
const clearState = props.clearState;
193+
const dataArray = props[dataKey];
193194

194-
extendDataArray.forEach(extendData => {
195+
dataArray.forEach(data => {
195196
let updateData, traceIndices, maxPoints;
196-
if (
197-
Array.isArray(extendData) &&
198-
typeof extendData[0] === 'object'
199-
) {
200-
[updateData, traceIndices, maxPoints] = extendData;
197+
if (Array.isArray(data) && typeof data[0] === 'object') {
198+
[updateData, traceIndices, maxPoints] = data;
201199
} else {
202-
updateData = extendData;
200+
updateData = data;
203201
}
204202

205203
if (!traceIndices) {
@@ -214,9 +212,9 @@ class PlotlyGraph extends Component {
214212
}
215213

216214
const gd = this.gd.current;
217-
return Plotly.extendTraces(gd, updateData, traceIndices, maxPoints);
215+
return Plotly[plotlyFnKey](gd, updateData, traceIndices, maxPoints);
218216
});
219-
clearExtendData();
217+
clearState(dataKey);
220218
}
221219

222220
getConfig(config, responsive) {
@@ -348,8 +346,11 @@ class PlotlyGraph extends Component {
348346

349347
componentDidMount() {
350348
this.plot(this.props);
349+
if (this.props.prependData) {
350+
this.mergeTraces(this.props, 'prependData', 'prependTraces');
351+
}
351352
if (this.props.extendData) {
352-
this.extend(this.props);
353+
this.mergeTraces(this.props, 'extendData', 'extendTraces');
353354
}
354355
}
355356

@@ -392,8 +393,12 @@ class PlotlyGraph extends Component {
392393
this.plot(nextProps);
393394
}
394395

396+
if (this.props.prependData !== nextProps.prependData) {
397+
this.mergeTraces(nextProps, 'prependData', 'prependTraces');
398+
}
399+
395400
if (this.props.extendData !== nextProps.extendData) {
396-
this.extend(nextProps);
401+
this.mergeTraces(nextProps, 'extendData', 'extendTraces');
397402
}
398403
}
399404

@@ -432,14 +437,18 @@ class PlotlyGraph extends Component {
432437

433438
PlotlyGraph.propTypes = {
434439
...graphPropTypes,
440+
prependData: PropTypes.arrayOf(
441+
PropTypes.oneOfType([PropTypes.array, PropTypes.object])
442+
),
435443
extendData: PropTypes.arrayOf(
436444
PropTypes.oneOfType([PropTypes.array, PropTypes.object])
437445
),
438-
clearExtendData: PropTypes.func.isRequired,
446+
clearState: PropTypes.func.isRequired,
439447
};
440448

441449
PlotlyGraph.defaultProps = {
442450
...graphDefaultProps,
451+
prependData: [],
443452
extendData: [],
444453
};
445454

0 commit comments

Comments
 (0)