line and bar icon buttons

This commit is contained in:
Robert Elliott 2018-09-11 13:04:26 +02:00
parent ae8739d63f
commit 4d155cd015
4 changed files with 62 additions and 19 deletions

View File

@ -44,13 +44,14 @@ class D3Chart extends Component {
this.getParams = this.getParams.bind( this );
this.state = {
allData: this.getAllData( props ),
type: props.type,
width: props.width,
};
this.tooltipRef = createRef();
}
componentDidUpdate( prevProps, prevState ) {
const { width } = this.props;
const { type, width } = this.props;
/* eslint-disable react/no-did-update-set-state */
if ( width !== prevProps.width ) {
this.setState( { width } );
@ -59,6 +60,9 @@ class D3Chart extends Component {
if ( ! isEqual( [ ...nextAllData ].sort(), [ ...prevState.allData ].sort() ) ) {
this.setState( { allData: nextAllData } );
}
if ( type !== prevProps.type ) {
this.setState( { type } );
}
/* eslint-enable react/no-did-update-set-state */
}
@ -157,6 +161,7 @@ class D3Chart extends Component {
data={ this.state.allData }
drawChart={ this.drawChart }
getParams={ this.getParams }
type={ this.state.type }
width={ this.state.width }
/>
<div className="tooltip" ref={ this.tooltipRef } />

View File

@ -31,6 +31,8 @@ export default class D3Base extends Component {
data: PropTypes.any, // required to detect changes in data
drawChart: PropTypes.func.isRequired,
getParams: PropTypes.func.isRequired,
type: PropTypes.string,
width: PropTypes.number,
};
state = {
@ -38,6 +40,7 @@ export default class D3Base extends Component {
params: null,
drawChart: null,
getParams: null,
type: null,
width: null,
};
@ -62,6 +65,10 @@ export default class D3Base extends Component {
state = { ...state, width: nextProps.width };
}
if ( nextProps.type !== prevState.type ) {
state = { ...state, type: nextProps.type };
}
if ( ! isEmpty( state ) ) {
return { ...state, params: null };
}
@ -79,7 +86,8 @@ export default class D3Base extends Component {
return (
( nextState.params !== null && ! isEqual( this.state.params, nextState.params ) ) ||
! isEqual( this.state.data, nextState.data ) ||
this.state.width !== nextState.width
this.state.width !== nextState.width ||
this.state.type !== nextState.type
);
}

View File

@ -3,10 +3,12 @@
* External dependencies
*/
import classNames from 'classnames';
import { isEqual } from 'lodash';
import { isEqual, partial } from 'lodash';
import { Component, createRef } from '@wordpress/element';
import { IconButton } from '@wordpress/components';
import PropTypes from 'prop-types';
import { interpolateViridis as d3InterpolateViridis } from 'd3-scale-chromatic';
import Gridicon from 'gridicons';
/**
* Internal dependencies
@ -50,9 +52,11 @@ class Chart extends Component {
this.state = {
data: props.data,
orderedKeys: getOrderedKeys( props ),
type: props.type,
visibleData: [ ...props.data ],
width: wpBody - 2 * calcGap,
};
this.handleTypeToggle = this.handleTypeToggle.bind( this );
this.handleLegendToggle = this.handleLegendToggle.bind( this );
this.handleLegendHover = this.handleLegendHover.bind( this );
this.updateDimensions = this.updateDimensions.bind( this );
@ -80,6 +84,12 @@ class Chart extends Component {
window.removeEventListener( 'resize', this.updateDimensions );
}
handleTypeToggle( type ) {
if ( this.state.type !== type ) {
this.setState( { type } );
}
}
handleLegendToggle( event ) {
const { data } = this.props;
const orderedKeys = this.state.orderedKeys.map( d => ( {
@ -130,17 +140,8 @@ class Chart extends Component {
}
render() {
const { orderedKeys, visibleData, width } = this.state;
const {
dateParser,
layout,
title,
tooltipFormat,
type,
xFormat,
x2Format,
yFormat,
} = this.props;
const { orderedKeys, type, visibleData, width } = this.state;
const { dateParser, layout, title, tooltipFormat, xFormat, x2Format, yFormat } = this.props;
const legendDirection = layout === 'standard' && width > WIDE_BREAKPOINT ? 'row' : 'column';
const chartDirection = layout === 'comparison' && width > WIDE_BREAKPOINT ? 'row' : 'column';
const legend = (
@ -164,6 +165,22 @@ class Chart extends Component {
<div className="woocommerce-chart__header">
<span className="woocommerce-chart__title">{ title }</span>
{ 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
className={ classNames(
@ -206,10 +223,6 @@ Chart.propTypes = {
* A datetime formatting string to format the title of the toolip, passed to d3TimeFormat.
*/
tooltipFormat: PropTypes.string,
/**
* Chart type of either `line` or `bar`.
*/
type: PropTypes.oneOf( [ 'bar', 'line' ] ),
/**
* A datetime formatting string, passed to d3TimeFormat.
*/
@ -230,6 +243,10 @@ Chart.propTypes = {
* A title describing this chart.
*/
title: PropTypes.string,
/**
* Chart type of either `line` or `bar`.
*/
type: PropTypes.oneOf( [ 'bar', 'line' ] ),
};
Chart.defaultProps = {
@ -240,6 +257,7 @@ Chart.defaultProps = {
x2Format: '%b %Y',
yFormat: '$.3s',
layout: 'standard',
type: 'line',
};
export default Chart;

View File

@ -14,7 +14,7 @@
display: flex;
flex-wrap: nowrap;
flex-direction: row;
justify-content: flex-start;
justify-content: space-between;
align-items: center;
width: 100%;
@ -27,6 +27,18 @@
margin-left: $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 {