Add `hidden` legendPosition to `Chart`. (https://github.com/woocommerce/woocommerce-admin/pull/7378)
* Add `hidden` legendPosition to `Chart`. Sometimes, for example, when there is a single data set, there is no need for rendering the legend. It may even introduce more confusion than value. It seems interactive, but there is nothing you can do with it. Fixes: https://github.com/woocommerce/google-listings-and-ads/issues/618 * Add `@storybook/addon-knobs` to devDependencies. It was used but not explicitely stated. * Add a changelog entry. * Add tests for legendPosition in Chart component Co-authored-by: Lourens Schep <lourensschep@gmail.com>
This commit is contained in:
parent
17c1b38781
commit
afd6693718
|
@ -1,6 +1,7 @@
|
||||||
# Unreleased
|
# Unreleased
|
||||||
|
|
||||||
- Fix a bug in the deprecated callback handlers of Form component. #7356
|
- Fix a bug in the deprecated callback handlers of Form component. #7356
|
||||||
|
- Add `hidden` legend position to `Chart`. #7378
|
||||||
|
|
||||||
# 8.0.0
|
# 8.0.0
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
"src/**/*.scss"
|
"src/**/*.scss"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@storybook/addon-knobs": "^6.3.0",
|
||||||
"@woocommerce/csv-export": "file:../csv-export",
|
"@woocommerce/csv-export": "file:../csv-export",
|
||||||
"@woocommerce/currency": "file:../currency",
|
"@woocommerce/currency": "file:../currency",
|
||||||
"@woocommerce/data": "file:../data",
|
"@woocommerce/data": "file:../data",
|
||||||
|
|
|
@ -91,7 +91,7 @@ Name | Type | Default | Description
|
||||||
`interval` | One of: 'hour', 'day', 'week', 'month', 'quarter', 'year' | `'day'` | Interval specification (hourly, daily, weekly etc)
|
`interval` | One of: 'hour', 'day', 'week', 'month', 'quarter', 'year' | `'day'` | Interval specification (hourly, daily, weekly etc)
|
||||||
`intervalData` | Object | `null` | Information about the currently selected interval, and set of allowed intervals for the chart. See `getIntervalsForQuery`
|
`intervalData` | Object | `null` | Information about the currently selected interval, and set of allowed intervals for the chart. See `getIntervalsForQuery`
|
||||||
`isRequesting` | Boolean | `false` | Render a chart placeholder to signify an in-flight data request
|
`isRequesting` | Boolean | `false` | Render a chart placeholder to signify an in-flight data request
|
||||||
`legendPosition` | One of: 'bottom', 'side', 'top' | `null` | Position the legend must be displayed in. If it's not defined, it's calculated depending on the viewport width and the mode
|
`legendPosition` | One of: 'bottom', 'side', 'top', 'hidden' | `null` | Position the legend must be displayed in. If it's not defined, it's calculated depending on the viewport width and the mode
|
||||||
`legendTotals` | Object | `null` | Values to overwrite the legend totals. If not defined, the sum of all line values will be used
|
`legendTotals` | Object | `null` | Values to overwrite the legend totals. If not defined, the sum of all line values will be used
|
||||||
`screenReaderFormat` | One of type: string, func | `'%B %-d, %Y'` | A datetime formatting string or overriding function to format the screen reader labels
|
`screenReaderFormat` | One of type: string, func | `'%B %-d, %Y'` | A datetime formatting string or overriding function to format the screen reader labels
|
||||||
`showHeaderControls` | Boolean | `true` | Wether header UI controls must be displayed
|
`showHeaderControls` | Boolean | `true` | Wether header UI controls must be displayed
|
||||||
|
|
|
@ -334,18 +334,19 @@ class Chart extends Component {
|
||||||
const chartDirection = legendPosition === 'side' ? 'row' : 'column';
|
const chartDirection = legendPosition === 'side' ? 'row' : 'column';
|
||||||
|
|
||||||
const chartHeight = this.getChartHeight();
|
const chartHeight = this.getChartHeight();
|
||||||
const legend = isRequesting ? null : (
|
const legend =
|
||||||
<D3Legend
|
legendPosition !== 'hidden' && isRequesting ? null : (
|
||||||
colorScheme={ d3InterpolateViridis }
|
<D3Legend
|
||||||
data={ orderedKeys }
|
colorScheme={ d3InterpolateViridis }
|
||||||
handleLegendHover={ this.handleLegendHover }
|
data={ orderedKeys }
|
||||||
handleLegendToggle={ this.handleLegendToggle }
|
handleLegendHover={ this.handleLegendHover }
|
||||||
interactive={ interactiveLegend }
|
handleLegendToggle={ this.handleLegendToggle }
|
||||||
legendDirection={ legendDirection }
|
interactive={ interactiveLegend }
|
||||||
legendValueFormat={ tooltipValueFormat }
|
legendDirection={ legendDirection }
|
||||||
totalLabel={ sprintf( itemsLabel, orderedKeys.length ) }
|
legendValueFormat={ tooltipValueFormat }
|
||||||
/>
|
totalLabel={ sprintf( itemsLabel, orderedKeys.length ) }
|
||||||
);
|
/>
|
||||||
|
);
|
||||||
const margin = {
|
const margin = {
|
||||||
bottom: 50,
|
bottom: 50,
|
||||||
left: 80,
|
left: 80,
|
||||||
|
@ -566,7 +567,7 @@ Chart.propTypes = {
|
||||||
* Position the legend must be displayed in. If it's not defined, it's calculated
|
* Position the legend must be displayed in. If it's not defined, it's calculated
|
||||||
* depending on the viewport width and the mode.
|
* depending on the viewport width and the mode.
|
||||||
*/
|
*/
|
||||||
legendPosition: PropTypes.oneOf( [ 'bottom', 'side', 'top' ] ),
|
legendPosition: PropTypes.oneOf( [ 'bottom', 'side', 'top', 'hidden' ] ),
|
||||||
/**
|
/**
|
||||||
* Values to overwrite the legend totals. If not defined, the sum of all line values will be used.
|
* Values to overwrite the legend totals. If not defined, the sum of all line values will be used.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
/**
|
/**
|
||||||
* External dependencies
|
* External dependencies
|
||||||
*/
|
*/
|
||||||
import { Chart } from '@woocommerce/components';
|
import { select } from '@storybook/addon-knobs';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import Chart from '../';
|
||||||
|
|
||||||
const data = [
|
const data = [
|
||||||
{
|
{
|
||||||
|
@ -66,8 +71,18 @@ const data = [
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export default () => (
|
export default {
|
||||||
<div>
|
title: 'WooCommerce Admin/components/Chart',
|
||||||
<Chart data={ data } title="Example Chart" layout="item-comparison" />
|
component: Chart,
|
||||||
</div>
|
};
|
||||||
|
|
||||||
|
export const Default = () => (
|
||||||
|
<Chart
|
||||||
|
data={ data }
|
||||||
|
legendPosition={ select(
|
||||||
|
'Legend Position',
|
||||||
|
[ undefined, 'bottom', 'side', 'top', 'hidden' ],
|
||||||
|
undefined
|
||||||
|
) }
|
||||||
|
/>
|
||||||
);
|
);
|
|
@ -0,0 +1,87 @@
|
||||||
|
/**
|
||||||
|
* @jest-environment jsdom
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import { render, within } from '@testing-library/react';
|
||||||
|
import { createElement } from '@wordpress/element';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import Chart from '../';
|
||||||
|
|
||||||
|
jest.mock( '../d3chart', () => ( {
|
||||||
|
D3Legend: jest.fn().mockReturnValue( '[D3Legend]' ),
|
||||||
|
} ) );
|
||||||
|
|
||||||
|
const data = [
|
||||||
|
{
|
||||||
|
date: '2018-05-30T00:00:00',
|
||||||
|
Hoodie: {
|
||||||
|
label: 'Hoodie',
|
||||||
|
value: 21599,
|
||||||
|
},
|
||||||
|
Sunglasses: {
|
||||||
|
label: 'Sunglasses',
|
||||||
|
value: 38537,
|
||||||
|
},
|
||||||
|
Cap: {
|
||||||
|
label: 'Cap',
|
||||||
|
value: 106010,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: '2018-05-31T00:00:00',
|
||||||
|
Hoodie: {
|
||||||
|
label: 'Hoodie',
|
||||||
|
value: 14205,
|
||||||
|
},
|
||||||
|
Sunglasses: {
|
||||||
|
label: 'Sunglasses',
|
||||||
|
value: 24721,
|
||||||
|
},
|
||||||
|
Cap: {
|
||||||
|
label: 'Cap',
|
||||||
|
value: 70131,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
describe( 'Chart', () => {
|
||||||
|
test( '<Chart legendPosition="hidden" /> should not render any legend', () => {
|
||||||
|
const { queryByText } = render(
|
||||||
|
<Chart data={ data } legendPosition="hidden" />
|
||||||
|
);
|
||||||
|
expect( queryByText( '[D3Legend]' ) ).not.toBeInTheDocument();
|
||||||
|
} );
|
||||||
|
|
||||||
|
test( '<Chart legendPosition="bottom" /> should render the legend at the bottom', () => {
|
||||||
|
const { container } = render(
|
||||||
|
<Chart data={ data } legendPosition="bottom" />
|
||||||
|
);
|
||||||
|
const footer = container.querySelector( '.woocommerce-chart__footer' );
|
||||||
|
expect(
|
||||||
|
within( footer ).queryByText( '[D3Legend]' )
|
||||||
|
).toBeInTheDocument();
|
||||||
|
} );
|
||||||
|
|
||||||
|
test( '<Chart legendPosition="side" /> should render the legend at the side', () => {
|
||||||
|
const { container } = render(
|
||||||
|
<Chart data={ data } legendPosition="side" />
|
||||||
|
);
|
||||||
|
const body = container.querySelector( '.woocommerce-chart__body' );
|
||||||
|
expect(
|
||||||
|
within( body ).queryByText( '[D3Legend]' )
|
||||||
|
).toBeInTheDocument();
|
||||||
|
} );
|
||||||
|
|
||||||
|
test( '<Chart legendPosition="top" /> should render the legend at the top', () => {
|
||||||
|
const { container } = render(
|
||||||
|
<Chart data={ data } legendPosition="top" />
|
||||||
|
);
|
||||||
|
const top = container.querySelector( '.woocommerce-chart__header' );
|
||||||
|
expect( within( top ).queryByText( '[D3Legend]' ) ).toBeInTheDocument();
|
||||||
|
} );
|
||||||
|
} );
|
Loading…
Reference in New Issue