line and bar icon buttons
This commit is contained in:
parent
ae8739d63f
commit
4d155cd015
|
@ -44,13 +44,14 @@ class D3Chart extends Component {
|
||||||
this.getParams = this.getParams.bind( this );
|
this.getParams = this.getParams.bind( this );
|
||||||
this.state = {
|
this.state = {
|
||||||
allData: this.getAllData( props ),
|
allData: this.getAllData( props ),
|
||||||
|
type: props.type,
|
||||||
width: props.width,
|
width: props.width,
|
||||||
};
|
};
|
||||||
this.tooltipRef = createRef();
|
this.tooltipRef = createRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate( prevProps, prevState ) {
|
componentDidUpdate( prevProps, prevState ) {
|
||||||
const { width } = this.props;
|
const { type, width } = this.props;
|
||||||
/* eslint-disable react/no-did-update-set-state */
|
/* eslint-disable react/no-did-update-set-state */
|
||||||
if ( width !== prevProps.width ) {
|
if ( width !== prevProps.width ) {
|
||||||
this.setState( { width } );
|
this.setState( { width } );
|
||||||
|
@ -59,6 +60,9 @@ class D3Chart extends Component {
|
||||||
if ( ! isEqual( [ ...nextAllData ].sort(), [ ...prevState.allData ].sort() ) ) {
|
if ( ! isEqual( [ ...nextAllData ].sort(), [ ...prevState.allData ].sort() ) ) {
|
||||||
this.setState( { allData: nextAllData } );
|
this.setState( { allData: nextAllData } );
|
||||||
}
|
}
|
||||||
|
if ( type !== prevProps.type ) {
|
||||||
|
this.setState( { type } );
|
||||||
|
}
|
||||||
/* eslint-enable react/no-did-update-set-state */
|
/* eslint-enable react/no-did-update-set-state */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,6 +161,7 @@ class D3Chart extends Component {
|
||||||
data={ this.state.allData }
|
data={ this.state.allData }
|
||||||
drawChart={ this.drawChart }
|
drawChart={ this.drawChart }
|
||||||
getParams={ this.getParams }
|
getParams={ this.getParams }
|
||||||
|
type={ this.state.type }
|
||||||
width={ this.state.width }
|
width={ this.state.width }
|
||||||
/>
|
/>
|
||||||
<div className="tooltip" ref={ this.tooltipRef } />
|
<div className="tooltip" ref={ this.tooltipRef } />
|
||||||
|
|
|
@ -31,6 +31,8 @@ export default class D3Base extends Component {
|
||||||
data: PropTypes.any, // required to detect changes in data
|
data: PropTypes.any, // required to detect changes in data
|
||||||
drawChart: PropTypes.func.isRequired,
|
drawChart: PropTypes.func.isRequired,
|
||||||
getParams: PropTypes.func.isRequired,
|
getParams: PropTypes.func.isRequired,
|
||||||
|
type: PropTypes.string,
|
||||||
|
width: PropTypes.number,
|
||||||
};
|
};
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
|
@ -38,6 +40,7 @@ export default class D3Base extends Component {
|
||||||
params: null,
|
params: null,
|
||||||
drawChart: null,
|
drawChart: null,
|
||||||
getParams: null,
|
getParams: null,
|
||||||
|
type: null,
|
||||||
width: null,
|
width: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -62,6 +65,10 @@ export default class D3Base extends Component {
|
||||||
state = { ...state, width: nextProps.width };
|
state = { ...state, width: nextProps.width };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( nextProps.type !== prevState.type ) {
|
||||||
|
state = { ...state, type: nextProps.type };
|
||||||
|
}
|
||||||
|
|
||||||
if ( ! isEmpty( state ) ) {
|
if ( ! isEmpty( state ) ) {
|
||||||
return { ...state, params: null };
|
return { ...state, params: null };
|
||||||
}
|
}
|
||||||
|
@ -79,7 +86,8 @@ export default class D3Base extends Component {
|
||||||
return (
|
return (
|
||||||
( nextState.params !== null && ! isEqual( this.state.params, nextState.params ) ) ||
|
( nextState.params !== null && ! isEqual( this.state.params, nextState.params ) ) ||
|
||||||
! isEqual( this.state.data, nextState.data ) ||
|
! isEqual( this.state.data, nextState.data ) ||
|
||||||
this.state.width !== nextState.width
|
this.state.width !== nextState.width ||
|
||||||
|
this.state.type !== nextState.type
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,12 @@
|
||||||
* External dependencies
|
* External dependencies
|
||||||
*/
|
*/
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { isEqual } from 'lodash';
|
import { isEqual, partial } from 'lodash';
|
||||||
import { Component, createRef } from '@wordpress/element';
|
import { Component, createRef } from '@wordpress/element';
|
||||||
|
import { IconButton } from '@wordpress/components';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { interpolateViridis as d3InterpolateViridis } from 'd3-scale-chromatic';
|
import { interpolateViridis as d3InterpolateViridis } from 'd3-scale-chromatic';
|
||||||
|
import Gridicon from 'gridicons';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
|
@ -50,9 +52,11 @@ class Chart extends Component {
|
||||||
this.state = {
|
this.state = {
|
||||||
data: props.data,
|
data: props.data,
|
||||||
orderedKeys: getOrderedKeys( props ),
|
orderedKeys: getOrderedKeys( props ),
|
||||||
|
type: props.type,
|
||||||
visibleData: [ ...props.data ],
|
visibleData: [ ...props.data ],
|
||||||
width: wpBody - 2 * calcGap,
|
width: wpBody - 2 * calcGap,
|
||||||
};
|
};
|
||||||
|
this.handleTypeToggle = this.handleTypeToggle.bind( this );
|
||||||
this.handleLegendToggle = this.handleLegendToggle.bind( this );
|
this.handleLegendToggle = this.handleLegendToggle.bind( this );
|
||||||
this.handleLegendHover = this.handleLegendHover.bind( this );
|
this.handleLegendHover = this.handleLegendHover.bind( this );
|
||||||
this.updateDimensions = this.updateDimensions.bind( this );
|
this.updateDimensions = this.updateDimensions.bind( this );
|
||||||
|
@ -80,6 +84,12 @@ class Chart extends Component {
|
||||||
window.removeEventListener( 'resize', this.updateDimensions );
|
window.removeEventListener( 'resize', this.updateDimensions );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleTypeToggle( type ) {
|
||||||
|
if ( this.state.type !== type ) {
|
||||||
|
this.setState( { type } );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
handleLegendToggle( event ) {
|
handleLegendToggle( event ) {
|
||||||
const { data } = this.props;
|
const { data } = this.props;
|
||||||
const orderedKeys = this.state.orderedKeys.map( d => ( {
|
const orderedKeys = this.state.orderedKeys.map( d => ( {
|
||||||
|
@ -130,17 +140,8 @@ class Chart extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { orderedKeys, visibleData, width } = this.state;
|
const { orderedKeys, type, visibleData, width } = this.state;
|
||||||
const {
|
const { dateParser, layout, title, tooltipFormat, xFormat, x2Format, yFormat } = this.props;
|
||||||
dateParser,
|
|
||||||
layout,
|
|
||||||
title,
|
|
||||||
tooltipFormat,
|
|
||||||
type,
|
|
||||||
xFormat,
|
|
||||||
x2Format,
|
|
||||||
yFormat,
|
|
||||||
} = this.props;
|
|
||||||
const legendDirection = layout === 'standard' && width > WIDE_BREAKPOINT ? 'row' : 'column';
|
const legendDirection = layout === 'standard' && width > WIDE_BREAKPOINT ? 'row' : 'column';
|
||||||
const chartDirection = layout === 'comparison' && width > WIDE_BREAKPOINT ? 'row' : 'column';
|
const chartDirection = layout === 'comparison' && width > WIDE_BREAKPOINT ? 'row' : 'column';
|
||||||
const legend = (
|
const legend = (
|
||||||
|
@ -164,6 +165,22 @@ class Chart extends Component {
|
||||||
<div className="woocommerce-chart__header">
|
<div className="woocommerce-chart__header">
|
||||||
<span className="woocommerce-chart__title">{ title }</span>
|
<span className="woocommerce-chart__title">{ title }</span>
|
||||||
{ width > WIDE_BREAKPOINT && legendDirection === 'row' && legend }
|
{ width > WIDE_BREAKPOINT && legendDirection === 'row' && legend }
|
||||||
|
<div className="woocommerce-chart__types">
|
||||||
|
<IconButton
|
||||||
|
className={ classNames( 'woocommerce-chart__type-button', {
|
||||||
|
'woocommerce-chart__type-button-selected': type === 'line',
|
||||||
|
} ) }
|
||||||
|
icon={ <Gridicon icon="line-graph" /> }
|
||||||
|
onClick={ partial( this.handleTypeToggle, 'line' ) }
|
||||||
|
/>
|
||||||
|
<IconButton
|
||||||
|
className={ classNames( 'woocommerce-chart__type-button', {
|
||||||
|
'woocommerce-chart__type-button-selected': type === 'bar',
|
||||||
|
} ) }
|
||||||
|
icon={ <Gridicon icon="stats-alt" /> }
|
||||||
|
onClick={ partial( this.handleTypeToggle, 'bar' ) }
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className={ classNames(
|
className={ classNames(
|
||||||
|
@ -206,10 +223,6 @@ Chart.propTypes = {
|
||||||
* A datetime formatting string to format the title of the toolip, passed to d3TimeFormat.
|
* A datetime formatting string to format the title of the toolip, passed to d3TimeFormat.
|
||||||
*/
|
*/
|
||||||
tooltipFormat: PropTypes.string,
|
tooltipFormat: PropTypes.string,
|
||||||
/**
|
|
||||||
* Chart type of either `line` or `bar`.
|
|
||||||
*/
|
|
||||||
type: PropTypes.oneOf( [ 'bar', 'line' ] ),
|
|
||||||
/**
|
/**
|
||||||
* A datetime formatting string, passed to d3TimeFormat.
|
* A datetime formatting string, passed to d3TimeFormat.
|
||||||
*/
|
*/
|
||||||
|
@ -230,6 +243,10 @@ Chart.propTypes = {
|
||||||
* A title describing this chart.
|
* A title describing this chart.
|
||||||
*/
|
*/
|
||||||
title: PropTypes.string,
|
title: PropTypes.string,
|
||||||
|
/**
|
||||||
|
* Chart type of either `line` or `bar`.
|
||||||
|
*/
|
||||||
|
type: PropTypes.oneOf( [ 'bar', 'line' ] ),
|
||||||
};
|
};
|
||||||
|
|
||||||
Chart.defaultProps = {
|
Chart.defaultProps = {
|
||||||
|
@ -240,6 +257,7 @@ Chart.defaultProps = {
|
||||||
x2Format: '%b %Y',
|
x2Format: '%b %Y',
|
||||||
yFormat: '$.3s',
|
yFormat: '$.3s',
|
||||||
layout: 'standard',
|
layout: 'standard',
|
||||||
|
type: 'line',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Chart;
|
export default Chart;
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
justify-content: flex-start;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
|
@ -27,6 +27,18 @@
|
||||||
margin-left: $gap;
|
margin-left: $gap;
|
||||||
margin-right: $gap;
|
margin-right: $gap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.woocommerce-chart__type-button {
|
||||||
|
&.components-icon-button {
|
||||||
|
color: $core-grey-light-700;
|
||||||
|
&.woocommerce-chart__type-button-selected {
|
||||||
|
color: $core-grey-dark-500;
|
||||||
|
}
|
||||||
|
&:hover {
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.woocommerce-chart__body {
|
.woocommerce-chart__body {
|
||||||
|
|
Loading…
Reference in New Issue