Skip to content
This repository was archived by the owner on Mar 5, 2020. It is now read-only.

Feature/arc pie chart #78

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 119 additions & 0 deletions src/ArcPieChart/ArcPieChart.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import React, { PropTypes } from 'react';
import { PieChart, Pie, ResponsiveContainer, Text, Cell, Legend } from 'recharts';
import styles from './ArcPieChart.styles.css';

class ArcPieChart extends React.Component {
constructor(props) {
super(props);
this.state = {
selectedSet: props.dataSets[0],
selectedData: props.dataSets[0].data[0],
colors: ['#75568D', '#AAA4AB'],
};
this.getColor = this.getColor.bind(this);
this.pieLabel = this.pieLabel.bind(this);
this.selectData = this.selectData.bind(this);
this.selectSet = this.selectSet.bind(this);
}
getColor(name) {
return name === this.state.selectedData.name ? this.state.colors[0] : this.state.colors[1];
}
pieLabel(options) {
const { cx, cy, payload } = options;
if (payload.name !== this.state.selectedData.name) {
return null;
}
return (
<Text
x={cx}
y={cy - 20}
fontSize={28}
fill={'black'}
style={{ fontWeight: 'bold' }}
textAnchor={'middle'}
>
{`${payload.value}%`}
</Text>
);
}
selectData(payload) {
this.setState(prevState => ({
...prevState,
selectedData: this.state.selectedSet.data.find(data => data.name === payload.name),
}));
}
selectSet(name) {
const newSet = this.props.dataSets.find(set => set.name === name);
this.setState(prevState => ({
...prevState,
selectedSet: newSet,
selectedData: newSet.data[0],
}));
}
render() {
return (
<div className={styles.container} >
<div className={styles.yearsContainer}>
<ul className={styles.years}>
{
this.props.dataSets.map((data) => {
const name = data.name;
const active = name === this.state.selectedSet.name ? styles.linkActive : '';
return (
<li className={styles.listItem} key={name}>
<a
className={`${styles.link} ${active}`}
onClick={() => this.selectSet(name)}
>
{name}
</a>
</li>
);
})
}
</ul>
</div>
<ResponsiveContainer width={'100%'} height={175}>
<PieChart
margin={{ top: 0, right: 5, bottom: 100, left: 5 }}
>
<Pie
startAngle={180}
endAngle={0}
data={[...this.state.selectedSet.data]}
cy={'100%'}
labelLine={false}
innerRadius={'105%'}
outerRadius={'185%'}
fill="#e3dde8"
label={this.pieLabel}
onClick={this.selectData}
>
{
this.state.selectedSet.data.map(data =>
<Cell key={data.name} fill={this.getColor(data.name)} />)
}
</Pie>
<Legend
iconType={'circle'}
payload={this.state.selectedSet.data.map(data => ({
color: this.getColor(data.name),
type: 'circle',
value: data.name,
name: data.name,
}))}
wrapperStyle={{ bottom: '-35px' }}
onClick={this.selectData}
/>
</PieChart>
</ResponsiveContainer>
</div>
);
}
}

ArcPieChart.propTypes = {
dataSets: PropTypes.array,
};

export default ArcPieChart;
37 changes: 37 additions & 0 deletions src/ArcPieChart/ArcPieChart.styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
.container {
color:#726371;
font-weight: bold;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}

.yearsContainer {
display: flex;
justify-content: space-between;
}

.listItem {
display: inline;
padding: 10px;
color: #AAA4AB;
flex: inherit;
}

.link {
display: inline-block;
padding:5px;
font-size: 1.3em;
}

.link:hover {
color: black;
cursor: pointer;
}

.linkActive {
font-weight: bold;
color: black;
border-bottom: 3px solid black;
}
1 change: 1 addition & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export LeafletMap from './LeafletMap/LeafletMap';
export Dropdown from './Dropdown/Dropdown';
export Icon from './Icon/Icon';
export Scatterplot from './Scatterplot/Scatterplot';
export ArcPieChart from './ArcPieChart/ArcPieChart';

// export utils as well for broader use
export isClient from './utils/isClient';
44 changes: 44 additions & 0 deletions stories/ArcPieChart.story.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React from 'react';
import { storiesOf } from '@kadira/storybook';
import { ArcPieChart } from '../src';

const displayName = ArcPieChart.displayName || 'ArcPieChart';
const title = 'Simple usage';
const description = 'Arc pie chart';

const dataSets = [
{
name: 'Monsters',
data: [
{ name: 'Boggarts', value: 86 },
{ name: 'Acromantula', value: 14 },
],
},
{
name: 'People',
data: [
{ name: 'Muggles', value: 50 },
{ name: 'Witches', value: 25 },
{ name: 'Wizards', value: 25 },
],
},
{
name: 'Other',
data: [
{ name: 'Giants', value: 20 },
{ name: 'House Elves', value: 15 },
{ name: 'Goblins', value: 65 },
],
},
];

const demoCode = () => (
<ArcPieChart dataSets={dataSets} />
);

export default () => storiesOf(displayName, module)
.addWithInfo(
title,
description,
demoCode,
);
2 changes: 2 additions & 0 deletions stories/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import dropdownStory from './Dropdown.story';
import rechartsPie from './RechartsPie.story';
import heroStory from './Hero.story';
import scatterplotStory from './Scatterplot.story';
import arcPieChartStory from './ArcPieChart.story';

import '../src/global.styles.css';
import '../assets/leaflet.css';
Expand Down Expand Up @@ -48,3 +49,4 @@ rechartsPie();
leafletMap();
heroStory();
scatterplotStory();
arcPieChartStory();