From c5a63c9517d4d0cfafd07df19800f9373e8db479 Mon Sep 17 00:00:00 2001 From: dplain90 Date: Thu, 7 Sep 2017 06:06:37 -0400 Subject: [PATCH] feat(bar): add label format support for Bar (#45) --- src/components/charts/bar/Bar.js | 4 +++ src/components/charts/bar/BarItemLabel.js | 7 +++-- src/components/charts/bar/enhance.js | 6 +++- src/components/charts/bar/props.js | 7 ++++- src/lib/propertiesConverters.js | 20 +++--------- test/lib/getLabelGenerator.test.js | 38 +++++++++++++++++++++++ 6 files changed, 61 insertions(+), 21 deletions(-) create mode 100644 test/lib/getLabelGenerator.test.js diff --git a/src/components/charts/bar/Bar.js b/src/components/charts/bar/Bar.js index 85f4a4faa..b4cc9e1fc 100644 --- a/src/components/charts/bar/Bar.js +++ b/src/components/charts/bar/Bar.js @@ -76,6 +76,9 @@ const Bar = ({ enableLabels, getLabelsLinkColor, getLabelsTextColor, + label, + labelFormat, + getLabel, // markers markers, @@ -212,6 +215,7 @@ const Bar = ({ result.bars.map(d => ( diff --git a/src/components/charts/bar/BarItemLabel.js b/src/components/charts/bar/BarItemLabel.js index 00f077e7b..64e2e9732 100644 --- a/src/components/charts/bar/BarItemLabel.js +++ b/src/components/charts/bar/BarItemLabel.js @@ -8,7 +8,7 @@ */ import React, { Component } from 'react' import PropTypes from 'prop-types' - +import { getLabelGenerator } from '../../../lib/propertiesConverters' const safeSize = 20 const labelStyle = { @@ -26,12 +26,13 @@ export default class BarItemLabel extends Component { height: PropTypes.number.isRequired, linkColor: PropTypes.string.isRequired, textColor: PropTypes.string.isRequired, + getLabel: PropTypes.func.isRequired, } static defaultProps = {} render() { - const { x: _x, y: _y, width, height, linkColor, textColor, data } = this.props + const { x: _x, y: _y, width, height, getLabel, linkColor, textColor, data } = this.props let x = _x let y = _y @@ -54,7 +55,7 @@ export default class BarItemLabel extends Component { {line} - {data.value} + {getLabel(data)} ) diff --git a/src/components/charts/bar/enhance.js b/src/components/charts/bar/enhance.js index 81697319a..dcf3524c9 100644 --- a/src/components/charts/bar/enhance.js +++ b/src/components/charts/bar/enhance.js @@ -2,7 +2,7 @@ * This file is part of the nivo project. * * Copyright 2016-present, Raphaƫl Benitte. - * + *d * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ @@ -14,6 +14,7 @@ import { withTheme, withColors, withDimensions, withMotion } from '../../../hocs import { getInheritedColorGenerator } from '../../../lib/colors' import { getAccessorFor } from '../../../lib/propertiesConverters' import { BarDefaultProps } from './props' +import { getLabelGenerator } from '../../../lib/propertiesConverters' export default Component => compose( @@ -31,5 +32,8 @@ export default Component => withPropsOnChange(['labelsLinkColor'], ({ labelsLinkColor }) => ({ getLabelsLinkColor: getInheritedColorGenerator(labelsLinkColor, 'axis.tickColor'), })), + withPropsOnChange(['label', 'labelFormat'], ({ label, labelFormat }) => ({ + getLabel: getLabelGenerator(label, labelFormat), + })), pure )(Component) diff --git a/src/components/charts/bar/props.js b/src/components/charts/bar/props.js index 5058f63a9..6d89d7953 100644 --- a/src/components/charts/bar/props.js +++ b/src/components/charts/bar/props.js @@ -37,6 +37,11 @@ export const BarPropTypes = { getLabelsTextColor: PropTypes.func.isRequired, // computed labelsLinkColor: PropTypes.oneOfType([PropTypes.string, PropTypes.func]).isRequired, getLabelsLinkColor: PropTypes.func.isRequired, // computed + label: PropTypes.oneOfType([PropTypes.string, PropTypes.func]).isRequired, + labelFormat: PropTypes.oneOfType([PropTypes.string, PropTypes.func]).isRequired, + getLabel: PropTypes.func, + // interactions + onClick: PropTypes.func, // theming getColor: PropTypes.func.isRequired, @@ -70,7 +75,7 @@ export const BarDefaultProps = { enableLabels: true, labelsLinkColor: 'theme', labelsTextColor: 'theme', - + label: 'value', // interactivity isInteractive: true, onClick: noop, diff --git a/src/lib/propertiesConverters.js b/src/lib/propertiesConverters.js index 7626693ee..0aaa23475 100644 --- a/src/lib/propertiesConverters.js +++ b/src/lib/propertiesConverters.js @@ -10,26 +10,14 @@ import _ from 'lodash' import { format } from 'd3-format' export const getLabelGenerator = (_label, labelFormat) => { - if (_.isFunction(_label)) { - return _label - } - - const label = d => _.get(d, _label) - + const getRawLabel = _.isFunction(_label) ? _label : d => _.get(d, _label) let formatter if (labelFormat) { - formatter = format(labelFormat) + formatter = _.isFunction(labelFormat) ? labelFormat : format(labelFormat) } - return data => { - let labelOutput = label(data) - - if (formatter) { - labelOutput = formatter(labelOutput) - } - - return labelOutput - } + if (formatter) return d => formatter(getRawLabel(d)) + return getRawLabel } export const getAccessorFor = directive => (_.isFunction(directive) ? directive : d => d[directive]) diff --git a/test/lib/getLabelGenerator.test.js b/test/lib/getLabelGenerator.test.js new file mode 100644 index 000000000..713931fd7 --- /dev/null +++ b/test/lib/getLabelGenerator.test.js @@ -0,0 +1,38 @@ +import { getLabelGenerator } from '../../src/lib/propertiesConverters' + +describe('getLabelGenerator()', () => { + it(`should handle simple value access`, () => { + const getLabel = getLabelGenerator('value') + expect(getLabel({ value: 12 })).toBe(12) + }) + + it(`should handle nested property access`, () => { + const getLabel = getLabelGenerator('node.value') + expect(getLabel({ node: { value: 13 } })).toBe(13) + }) + + it(`should handle simple access with d3 formatting`, () => { + const getLabel = getLabelGenerator('value', '.1f') + expect(getLabel({ value: 14 })).toBe('14.0') + }) + + it(`should handle simple access with d3 formatting`, () => { + const getLabel = getLabelGenerator('value', '.1f') + expect(getLabel({ value: 14 })).toBe('14.0') + }) + + it(`should handle custom access function`, () => { + const getLabel = getLabelGenerator(d => d.value[0]) + expect(getLabel({ value: [15, 16] })).toBe(15) + }) + + it(`should handle custom formatting function`, () => { + const getLabel = getLabelGenerator('value', v => v + 10) + expect(getLabel({ value: 17 })).toBe(27) + }) + + it(`should handle custom access & formatting functions`, () => { + const getLabel = getLabelGenerator(d => d.value[1], v => v + 10) + expect(getLabel({ value: [18, 19] })).toBe(29) + }) +})