Skip to content

Commit

Permalink
Merge pull request #227 from hshoff/harry-legend-click
Browse files Browse the repository at this point in the history
[legend] make legend items clickable. fixes #209
  • Loading branch information
hshoff authored Jan 12, 2018
2 parents 6a2706d + e681253 commit 2b7935e
Show file tree
Hide file tree
Showing 7 changed files with 190 additions and 9 deletions.
59 changes: 58 additions & 1 deletion packages/vx-demo/components/tiles/legends.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,15 @@ export default ({ width, height, margin }) => {
shapeMargin="5px 0"
itemDirection="row"
scale={size}
onClick={data => event => {
alert(`clicked: ${JSON.stringify(data)}`);
}}
onMouseOver={data => event => {
console.log(
`mouse over: ${data.text}`,
`index: ${data.index}`,
);
}}
shapeStyle={props => {
return {
fill: sizeColor(props.datum),
Expand All @@ -155,7 +164,19 @@ export default ({ width, height, margin }) => {
/>
</LegendDemo>
<LegendDemo title="Quantile">
<LegendQuantile shape="circle" scale={quantile} />
<LegendQuantile
shape="circle"
scale={quantile}
onClick={data => event => {
alert(`clicked: ${JSON.stringify(data)}`);
}}
onMouseOver={data => event => {
console.log(
`mouse over: ${data.text}`,
`index: ${data.index}`,
);
}}
/>
</LegendDemo>
<LegendDemo title="Linear">
<LegendLinear
Expand All @@ -165,6 +186,15 @@ export default ({ width, height, margin }) => {
if (i % 2 === 0) return oneDecimalFormat(d);
return '';
}}
onClick={data => event => {
alert(`clicked: ${JSON.stringify(data)}`);
}}
onMouseOver={data => event => {
console.log(
`mouse over: ${data.text}`,
`index: ${data.index}`,
);
}}
/>
</LegendDemo>
<LegendDemo title="Threshold">
Expand All @@ -174,6 +204,15 @@ export default ({ width, height, margin }) => {
labelMargin="2px 0 0 10px"
shapeMargin="1px 0 0"
scale={threshold}
onClick={data => event => {
alert(`clicked: ${JSON.stringify(data)}`);
}}
onMouseOver={data => event => {
console.log(
`mouse over: ${data.text}`,
`index: ${data.index}`,
);
}}
/>
</LegendDemo>
<LegendDemo title="Ordinal">
Expand All @@ -187,6 +226,15 @@ export default ({ width, height, margin }) => {
shape="rect"
fill={({ datum }) => ordinalColor(datum)}
labelFormat={label => `${label.toUpperCase()}`}
onClick={data => event => {
alert(`clicked: ${JSON.stringify(data)}`);
}}
onMouseOver={data => event => {
console.log(
`mouse over: ${data.text}`,
`index: ${data.index}`,
);
}}
/>
</LegendDemo>
<LegendDemo title="Custom Legend">
Expand All @@ -199,6 +247,15 @@ export default ({ width, height, margin }) => {
scale={ordinalShape}
fill={({ datum }) => ordinalColor2(datum)}
shapeWidth={15}
onClick={data => event => {
alert(`clicked: ${JSON.stringify(data)}`);
}}
onMouseOver={data => event => {
console.log(
`mouse over: ${data.text}`,
`index: ${data.index}`,
);
}}
shape={props => {
return (
<svg width={props.width} height={props.height}>
Expand Down
85 changes: 80 additions & 5 deletions packages/vx-demo/pages/legends.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,16 @@ const ordinalShape = scaleOrdinal({
left={50 / 6}
fill="#df905f"
/>,
props =>
props => (
<text fontSize="12" dy="1em" dx=".33em" fill="#e0a346">
$
</text>,
</text>
),
],
});
const threshold = scaleThreshold({
domain: [0.02, 0.04, 0.06, 0.08, 0.1],
domain: [0.01, 0.02, 0.04, 0.06, 0.08, 0.1],
range: [
'#f2f0f7',
'#dadaeb',
Expand Down Expand Up @@ -118,6 +119,24 @@ function LegendDemo({ title, children }) {
<div className="legend">
<div className="title">{title}</div>
{children}
<style jsx>{\`
.legend {
line-height: 0.9em;
color: #efefef;
font-size: 10px;
font-family: arial;
padding: 10px 10px;
float: left;
border: 1px solid rgba(255, 255, 255, 0.3);
border-radius: 8px;
margin: 5px 5px;
}
.title {
font-size: 12px;
margin-bottom: 10px;
font-weight: 100;
}
\`}</style>
</div>
);
}
Expand All @@ -132,6 +151,15 @@ export default ({ width, height, margin }) => {
shapeMargin="5px 0"
itemDirection="row"
scale={size}
onClick={data => event => {
alert(\`clicked: \`\${JSON.stringify(data)}\`);
}}
onMouseOver={data => event => {
console.log(
\`mouse over: \${data.text}\`,
\`index: \${data.index}\`,
);
}}
shapeStyle={props => {
return {
fill: sizeColor(props.datum),
Expand All @@ -153,7 +181,19 @@ export default ({ width, height, margin }) => {
/>
</LegendDemo>
<LegendDemo title="Quantile">
<LegendQuantile shape="circle" scale={quantile} />
<LegendQuantile
shape="circle"
scale={quantile}
onClick={data => event => {
alert(\`clicked: \`\${JSON.stringify(data)}\`);
}}
onMouseOver={data => event => {
console.log(
\`mouse over: \${data.text}\`,
\`index: \${data.index}\`,
);
}}
/>
</LegendDemo>
<LegendDemo title="Linear">
<LegendLinear
Expand All @@ -163,6 +203,15 @@ export default ({ width, height, margin }) => {
if (i % 2 === 0) return oneDecimalFormat(d);
return '';
}}
onClick={data => event => {
alert(\`clicked: \`\${JSON.stringify(data)}\`);
}}
onMouseOver={data => event => {
console.log(
\`mouse over: \${data.text}\`,
\`index: \${data.index}\`,
);
}}
/>
</LegendDemo>
<LegendDemo title="Threshold">
Expand All @@ -172,6 +221,15 @@ export default ({ width, height, margin }) => {
labelMargin="2px 0 0 10px"
shapeMargin="1px 0 0"
scale={threshold}
onClick={data => event => {
alert(\`clicked: \`\${JSON.stringify(data)}\`);
}}
onMouseOver={data => event => {
console.log(
\`mouse over: \${data.text}\`,
\`index: \${data.index}\`,
);
}}
/>
</LegendDemo>
<LegendDemo title="Ordinal">
Expand All @@ -185,6 +243,15 @@ export default ({ width, height, margin }) => {
shape="rect"
fill={({ datum }) => ordinalColor(datum)}
labelFormat={label => \`\${label.toUpperCase()}\`}
onClick={data => event => {
alert(\`clicked: \`\${JSON.stringify(data)}\`);
}}
onMouseOver={data => event => {
console.log(
\`mouse over: \${data.text}\`,
\`index: \${data.index}\`,
);
}}
/>
</LegendDemo>
<LegendDemo title="Custom Legend">
Expand All @@ -197,6 +264,15 @@ export default ({ width, height, margin }) => {
scale={ordinalShape}
fill={({ datum }) => ordinalColor2(datum)}
shapeWidth={15}
onClick={data => event => {
alert(\`clicked: \`\${JSON.stringify(data)}\`);
}}
onMouseOver={data => event => {
console.log(
\`mouse over: \${data.text}\`,
\`index: \${data.index}\`,
);
}}
shape={props => {
return (
<svg width={props.width} height={props.height}>
Expand All @@ -221,7 +297,6 @@ export default ({ width, height, margin }) => {
</div>
);
};
`}
</Show>
);
Expand Down
2 changes: 2 additions & 0 deletions packages/vx-legend/src/legends/Legend.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ export default function Legend({
key={`legend-${label}-${i}`}
margin={itemMargin}
flexDirection={itemDirection}
label={label}
{...restProps}
>
<LegendShape
shape={shape}
Expand Down
14 changes: 12 additions & 2 deletions packages/vx-legend/src/legends/LegendItem.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,32 @@
import React from 'react';
import PropTypes from 'prop-types';
import additonalProps from '../util/additionalProps';

LegendItem.propTypes = {
flexDirection: PropTypes.string,
margin: PropTypes.string,
label: PropTypes.object.isRequired,
};

export default function LegendItem({
children,
flexDirection,
margin,
label,
...restProps
}) {
return (
<div
className='vx-legend-item'
className="vx-legend-item"
style={{
display: 'flex',
alignItems: 'center',
flexDirection,
margin,
}}
{...additonalProps(restProps, label)}
>
{children}
</div>
);
}
}
8 changes: 8 additions & 0 deletions packages/vx-legend/src/util/additionalProps.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import callOrValue from './callOrValue';

export default function additionalProps(restProps, data) {
return Object.keys(restProps).reduce((ret, cur) => {
ret[cur] = callOrValue(restProps[cur], data);
return ret;
}, {});
}
6 changes: 6 additions & 0 deletions packages/vx-legend/src/util/callOrValue.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export default function callOrValue(maybeFn, data) {
if (typeof maybeFn === 'function') {
return maybeFn(data);
}
return maybeFn;
}
25 changes: 24 additions & 1 deletion packages/vx-legend/test/Legend.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { shallow } from 'enzyme';
import { shallow, mount } from 'enzyme';
import { Legend } from '../src';
import { scaleLinear } from '../../vx-scale';

Expand Down Expand Up @@ -42,4 +42,27 @@ describe('<Legend />', () => {
flexDirection: 'row',
});
});

test('it should pass onClick prop to <LegendItem />', () => {
const event = jest.fn(event => jest.fn());
const onClick = jest.fn(data => event);
const wrapper = mount(
<Legend {...defaultProps} onClick={onClick} />,
);
wrapper
.find('LegendItem')
.last()
.simulate('click');
// called twice, once to bind data, once when click event
expect(onClick.mock.calls.length).toEqual(2);
expect(event.mock.calls.length).toEqual(1);
// called with click event
expect(event.mock.calls[0][0].type).toEqual('click');
expect(onClick.mock.calls[1][0]).toEqual({
datum: 10,
index: 1,
text: '10',
value: 0,
});
});
});

0 comments on commit 2b7935e

Please sign in to comment.