Skip to content

Commit

Permalink
feat(bar): adjust legend data according to layout/mode/reverse
Browse files Browse the repository at this point in the history
  • Loading branch information
Raphaël Benitte authored and Raphaël Benitte committed Mar 21, 2019
1 parent 4568516 commit 0c0a6a1
Show file tree
Hide file tree
Showing 4 changed files with 175 additions and 30 deletions.
38 changes: 8 additions & 30 deletions packages/bar/src/Bar.js
Expand Up @@ -7,12 +7,11 @@
* file that was distributed with this source code.
*/
import React, { Fragment } from 'react'
import uniqBy from 'lodash/uniqBy'
import { TransitionMotion, spring } from 'react-motion'
import { bindDefs, Container, SvgWrapper, Grid, CartesianMarkers } from '@nivo/core'
import { Axes } from '@nivo/axes'
import { BoxLegendSvg } from '@nivo/legends'
import { generateGroupedBars, generateStackedBars } from './compute'
import { generateGroupedBars, generateStackedBars, getLegendData } from './compute'
import setDisplayName from 'recompose/setDisplayName'
import enhance from './enhance'
import { BarPropTypes } from './props'
Expand Down Expand Up @@ -153,28 +152,6 @@ const Bar = props => {
targetKey: 'data.fill',
})

const legendDataForKeys = uniqBy(
result.bars
.map(bar => ({
id: bar.data.id,
label: bar.data.id,
color: bar.color,
fill: bar.data.fill,
}))
.reverse(),
({ id }) => id
)

const legendDataForIndexes = uniqBy(
result.bars.map(bar => ({
id: bar.data.indexValue,
label: bar.data.indexValue,
color: bar.color,
fill: bar.data.fill,
})),
({ id }) => id
)

return (
<Container isInteractive={isInteractive} theme={theme}>
{({ showTooltip, hideTooltip }) => {
Expand Down Expand Up @@ -292,12 +269,13 @@ const Bar = props => {
/>
),
legends: legends.map((legend, i) => {
let legendData
if (legend.dataFrom === 'keys') {
legendData = legendDataForKeys
} else if (legend.dataFrom === 'indexes') {
legendData = legendDataForIndexes
}
const legendData = getLegendData({
from: legend.dataFrom,
bars: result.bars,
layout,
groupMode,
reverse,
})

if (legendData === undefined) return null

Expand Down
1 change: 1 addition & 0 deletions packages/bar/src/compute/index.js
Expand Up @@ -8,3 +8,4 @@
*/
export * from './grouped'
export * from './stacked'
export * from './legends'
50 changes: 50 additions & 0 deletions packages/bar/src/compute/legends.js
@@ -0,0 +1,50 @@
/*
* This file is part of the nivo project.
*
* Copyright 2016-present, Raphaël Benitte.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { uniqBy } from 'lodash'

export const getLegendDataForKeys = (bars, layout, groupMode, reverse) => {
const data = uniqBy(
bars.map(bar => ({
id: bar.data.id,
label: bar.data.id,
color: bar.color,
fill: bar.data.fill,
})),
({ id }) => id
)

if (
(layout === 'vertical' && groupMode === 'stacked' && reverse !== true) ||
(layout === 'horizontal' && groupMode === 'stacked' && reverse === true)
) {
data.reverse()
}

return data
}

export const getLegendDataForIndexes = bars => {
return uniqBy(
bars.map(bar => ({
id: bar.data.indexValue,
label: bar.data.indexValue,
color: bar.color,
fill: bar.data.fill,
})),
({ id }) => id
)
}

export const getLegendData = ({ from, bars, layout, groupMode, reverse }) => {
if (from === 'indexes') {
return getLegendDataForIndexes(bars)
}

return getLegendDataForKeys(bars, layout, groupMode, reverse)
}
116 changes: 116 additions & 0 deletions packages/bar/tests/Bar.test.js
@@ -1,5 +1,7 @@
import React from 'react'
import renderer from 'react-test-renderer'
import { mount } from 'enzyme'
import { LegendSvg, LegendSvgItem } from '@nivo/legends'
import Bar from '../src/Bar'

it('should render a basic bar chart', () => {
Expand Down Expand Up @@ -74,3 +76,117 @@ it('should allow grouped horizontal layout', () => {
let tree = component.toJSON()
expect(tree).toMatchSnapshot()
})

it(`should reverse legend items if chart layout is vertical`, () => {
const wrapper = mount(
<Bar
width={500}
height={300}
data={[{ id: 'one', A: 10, B: 13 }, { id: 'two', A: 12, B: 9 }]}
keys={['A', 'B']}
layout="vertical"
legends={[
{
dataFrom: 'keys',
anchor: 'top-left',
direction: 'column',
itemWidth: 100,
itemHeight: 20,
},
]}
/>
)

expect(wrapper.find(LegendSvg)).toHaveLength(1)

const legendItems = wrapper.find(LegendSvgItem)
expect(legendItems).toHaveLength(2)
expect(legendItems.at(0).prop('data').id).toEqual('B')
expect(legendItems.at(1).prop('data').id).toEqual('A')
})

it(`should not reverse legend items if chart layout is vertical reversed`, () => {
const wrapper = mount(
<Bar
width={500}
height={300}
data={[{ id: 'one', A: 10, B: 13 }, { id: 'two', A: 12, B: 9 }]}
keys={['A', 'B']}
layout="vertical"
reverse={true}
legends={[
{
dataFrom: 'keys',
anchor: 'top-left',
direction: 'column',
itemWidth: 100,
itemHeight: 20,
},
]}
/>
)

expect(wrapper.find(LegendSvg)).toHaveLength(1)

const legendItems = wrapper.find(LegendSvgItem)
expect(legendItems).toHaveLength(2)
expect(legendItems.at(0).prop('data').id).toEqual('A')
expect(legendItems.at(1).prop('data').id).toEqual('B')
})

it(`should not reverse legend items if chart layout is horizontal`, () => {
const wrapper = mount(
<Bar
width={500}
height={300}
data={[{ id: 'one', A: 10, B: 13 }, { id: 'two', A: 12, B: 9 }]}
keys={['A', 'B']}
layout="horizontal"
legends={[
{
dataFrom: 'keys',
anchor: 'top-left',
direction: 'column',
itemWidth: 100,
itemHeight: 20,
},
]}
/>
)

expect(wrapper.find(LegendSvg)).toHaveLength(1)

const legendItems = wrapper.find(LegendSvgItem)
expect(legendItems).toHaveLength(2)
expect(legendItems.at(0).prop('data').id).toEqual('A')
expect(legendItems.at(1).prop('data').id).toEqual('B')
})

it(`should reverse legend items if chart layout is horizontal reversed`, () => {
const wrapper = mount(
<Bar
width={500}
height={300}
data={[{ id: 'one', A: 10, B: 13 }, { id: 'two', A: 12, B: 9 }]}
keys={['A', 'B']}
layout="horizontal"
reverse={true}
legends={[
{
dataFrom: 'keys',
anchor: 'top-left',
direction: 'column',
itemWidth: 100,
itemHeight: 20,
},
]}
/>
)

expect(wrapper.find(LegendSvg)).toHaveLength(1)

const legendItems = wrapper.find(LegendSvgItem)
expect(legendItems).toHaveLength(2)
expect(legendItems.at(0).prop('data').id).toEqual('B')
expect(legendItems.at(1).prop('data').id).toEqual('A')
})

0 comments on commit 0c0a6a1

Please sign in to comment.