Chart: Persist orderedKeys between state changes

This commit is contained in:
Paul Sealock 2018-11-21 14:19:33 +13:00
parent 92763e69bb
commit 7d65df783c
2 changed files with 48 additions and 38 deletions

View File

@ -2,8 +2,7 @@
/** /**
* External dependencies * External dependencies
*/ */
import { __ } from '@wordpress/i18n'; import { Component } from '@wordpress/element';
import { Component, Fragment } from '@wordpress/element';
import { compose } from '@wordpress/compose'; import { compose } from '@wordpress/compose';
import { format as formatDate } from '@wordpress/date'; import { format as formatDate } from '@wordpress/date';
import { withSelect } from '@wordpress/data'; import { withSelect } from '@wordpress/data';
@ -26,7 +25,7 @@ import {
/** /**
* Internal dependencies * Internal dependencies
*/ */
import { Chart, ChartPlaceholder } from 'components'; import { Chart } from 'components';
import { getReportChartData, getTooltipValueFormat } from 'store/reports/utils'; import { getReportChartData, getTooltipValueFormat } from 'store/reports/utils';
import ReportError from 'analytics/components/report-error'; import ReportError from 'analytics/components/report-error';
@ -72,17 +71,6 @@ export class ReportChart extends Component {
return <ReportError isError />; return <ReportError isError />;
} }
if ( primaryData.isRequesting || secondaryData.isRequesting ) {
return (
<Fragment>
<span className="screen-reader-text">
{ __( 'Your requested data is loading', 'wc-admin' ) }
</span>
<ChartPlaceholder />
</Fragment>
);
}
const currentInterval = getIntervalForQuery( query ); const currentInterval = getIntervalForQuery( query );
const allowedIntervals = getAllowedIntervalsForQuery( query ); const allowedIntervals = getAllowedIntervalsForQuery( query );
const formats = getDateFormatsForInterval( currentInterval, primaryData.data.intervals.length ); const formats = getDateFormatsForInterval( currentInterval, primaryData.data.intervals.length );
@ -131,6 +119,7 @@ export class ReportChart extends Component {
x2Format={ formats.x2Format } x2Format={ formats.x2Format }
dateParser={ '%Y-%m-%dT%H:%M:%S' } dateParser={ '%Y-%m-%dT%H:%M:%S' }
valueType={ selectedChart.type } valueType={ selectedChart.type }
isRequesting={ primaryData.isRequesting || secondaryData.isRequesting }
/> />
); );
} }

View File

@ -4,10 +4,10 @@
*/ */
import { __ } from '@wordpress/i18n'; import { __ } from '@wordpress/i18n';
import classNames from 'classnames'; import classNames from 'classnames';
import { Component, createRef } from '@wordpress/element'; import { Component, createRef, Fragment } from '@wordpress/element';
import { decodeEntities } from '@wordpress/html-entities'; import { decodeEntities } from '@wordpress/html-entities';
import { formatDefaultLocale as d3FormatDefaultLocale } from 'd3-format'; import { formatDefaultLocale as d3FormatDefaultLocale } from 'd3-format';
import { get, isEqual, partial, find } from 'lodash'; import { get, isEqual, partial } from 'lodash';
import Gridicon from 'gridicons'; import Gridicon from 'gridicons';
import { IconButton, NavigableMenu, SelectControl } from '@wordpress/components'; import { IconButton, NavigableMenu, SelectControl } from '@wordpress/components';
import { interpolateViridis as d3InterpolateViridis } from 'd3-scale-chromatic'; import { interpolateViridis as d3InterpolateViridis } from 'd3-scale-chromatic';
@ -26,6 +26,7 @@ import { H, Section } from '@woocommerce/components';
import './style.scss'; import './style.scss';
import D3Chart from 'components/d3chart'; import D3Chart from 'components/d3chart';
import Legend from 'components/d3chart/legend'; import Legend from 'components/d3chart/legend';
import ChartPlaceholder from './placeholder';
d3FormatDefaultLocale( { d3FormatDefaultLocale( {
decimal: '.', decimal: '.',
@ -81,7 +82,13 @@ class Chart extends Component {
componentDidUpdate( prevProps ) { componentDidUpdate( prevProps ) {
const { data } = this.props; const { data } = this.props;
if ( ! isEqual( [ ...data ].sort(), [ ...prevProps.data ].sort() ) ) { if ( ! isEqual( [ ...data ].sort(), [ ...prevProps.data ].sort() ) ) {
const orderedKeys = getOrderedKeys( this.props, this.state.orderedKeys ); /**
* Only update the orderedKeys when data is present so that
* selection may persist while requesting new data.
*/
const orderedKeys = data.length
? getOrderedKeys( this.props, this.state.orderedKeys )
: this.state.orderedKeys;
/* eslint-disable react/no-did-update-set-state */ /* eslint-disable react/no-did-update-set-state */
this.setState( { this.setState( {
orderedKeys, orderedKeys,
@ -220,6 +227,7 @@ class Chart extends Component {
interval, interval,
valueType, valueType,
type, type,
isRequesting,
} = this.props; } = this.props;
let { yFormat } = this.props; let { yFormat } = this.props;
const legendDirection = mode === 'time-comparison' && isViewportWide ? 'row' : 'column'; const legendDirection = mode === 'time-comparison' && isViewportWide ? 'row' : 'column';
@ -299,28 +307,37 @@ class Chart extends Component {
ref={ this.chartBodyRef } ref={ this.chartBodyRef }
> >
{ isViewportWide && legendDirection === 'column' && legend } { isViewportWide && legendDirection === 'column' && legend }
{ width > 0 && ( { isRequesting && (
<D3Chart <Fragment>
colorScheme={ d3InterpolateViridis } <span className="screen-reader-text">
data={ visibleData } { __( 'Your requested data is loading', 'wc-admin' ) }
dateParser={ dateParser } </span>
height={ chartHeight } <ChartPlaceholder />
interval={ interval } </Fragment>
margin={ margin }
mode={ mode }
orderedKeys={ orderedKeys }
tooltipLabelFormat={ tooltipLabelFormat }
tooltipValueFormat={ tooltipValueFormat }
tooltipPosition={ isViewportLarge ? 'over' : 'below' }
tooltipTitle={ tooltipTitle }
type={ type }
width={ chartDirection === 'row' ? width - 320 : width }
xFormat={ xFormat }
x2Format={ x2Format }
yFormat={ yFormat }
valueType={ valueType }
/>
) } ) }
{ ! isRequesting &&
width > 0 && (
<D3Chart
colorScheme={ d3InterpolateViridis }
data={ visibleData }
dateParser={ dateParser }
height={ chartHeight }
interval={ interval }
margin={ margin }
mode={ mode }
orderedKeys={ orderedKeys }
tooltipLabelFormat={ tooltipLabelFormat }
tooltipValueFormat={ tooltipValueFormat }
tooltipPosition={ isViewportLarge ? 'over' : 'below' }
tooltipTitle={ tooltipTitle }
type={ type }
width={ chartDirection === 'row' ? width - 320 : width }
xFormat={ xFormat }
x2Format={ x2Format }
yFormat={ yFormat }
valueType={ valueType }
/>
) }
</div> </div>
{ ! isViewportWide && <div className="woocommerce-chart__footer">{ legend }</div> } { ! isViewportWide && <div className="woocommerce-chart__footer">{ legend }</div> }
</Section> </Section>
@ -399,6 +416,10 @@ Chart.propTypes = {
* What type of data is to be displayed? Number, Average, String? * What type of data is to be displayed? Number, Average, String?
*/ */
valueType: PropTypes.string, valueType: PropTypes.string,
/**
* Render a chart placeholder to signify an in-flight data request.
*/
isRequesting: PropTypes.bool,
}; };
Chart.defaultProps = { Chart.defaultProps = {