mirror of https://gitlab.com/ecentrics/concordia
Ezerous
4 years ago
7 changed files with 175 additions and 69 deletions
@ -0,0 +1,56 @@ |
|||
import React, { useMemo } from 'react'; |
|||
import Chart from 'react-apexcharts'; |
|||
import PropTypes from 'prop-types'; |
|||
import { CHART_TYPE_BAR } from '../../../../constants/polls/PollGraph'; |
|||
|
|||
const PollChartBar = (props) => { |
|||
const { pollOptions, voteCounts } = props; |
|||
|
|||
const chartOptions = useMemo(() => ({ |
|||
chart: { |
|||
id: 'chart-bar', |
|||
}, |
|||
theme: { |
|||
palette: 'palette8', |
|||
}, |
|||
plotOptions: { |
|||
bar: { |
|||
horizontal: true, |
|||
distributed: true, |
|||
}, |
|||
}, |
|||
xaxis: { |
|||
categories: pollOptions, |
|||
tickAmount: 1, |
|||
labels: { |
|||
formatter(val) { |
|||
if (val.toFixed) return val.toFixed(0); |
|||
return val; |
|||
}, |
|||
}, |
|||
}, |
|||
tooltip: { |
|||
enabled: false, |
|||
}, |
|||
}), [pollOptions]); |
|||
|
|||
const chartSeries = useMemo(() => [{ |
|||
name: 'Votes', |
|||
data: voteCounts, |
|||
}], [voteCounts]); |
|||
|
|||
return ( |
|||
<Chart |
|||
options={chartOptions} |
|||
series={chartSeries} |
|||
type={CHART_TYPE_BAR} |
|||
/> |
|||
); |
|||
}; |
|||
|
|||
PollChartBar.propTypes = { |
|||
pollOptions: PropTypes.arrayOf(PropTypes.string).isRequired, |
|||
voteCounts: PropTypes.arrayOf(PropTypes.number).isRequired, |
|||
}; |
|||
|
|||
export default PollChartBar; |
@ -0,0 +1,49 @@ |
|||
import React, { useMemo } from 'react'; |
|||
import Chart from 'react-apexcharts'; |
|||
import PropTypes from 'prop-types'; |
|||
import { CHART_TYPE_DONUT } from '../../../../constants/polls/PollGraph'; |
|||
|
|||
const PollChartDonut = (props) => { |
|||
const { pollOptions, voteCounts } = props; |
|||
|
|||
const chartOptions = useMemo(() => ({ |
|||
chart: { |
|||
id: 'chart-donut', |
|||
}, |
|||
theme: { |
|||
palette: 'palette8', |
|||
}, |
|||
plotOptions: { |
|||
pie: { |
|||
donut: { |
|||
labels: { |
|||
show: true, |
|||
total: { |
|||
show: true, |
|||
label: 'Total Votes', |
|||
}, |
|||
}, |
|||
}, |
|||
}, |
|||
}, |
|||
labels: pollOptions, |
|||
tooltip: { |
|||
enabled: false, |
|||
}, |
|||
}), [pollOptions]); |
|||
|
|||
return ( |
|||
<Chart |
|||
options={chartOptions} |
|||
series={voteCounts} |
|||
type={CHART_TYPE_DONUT} |
|||
/> |
|||
); |
|||
}; |
|||
|
|||
PollChartDonut.propTypes = { |
|||
pollOptions: PropTypes.arrayOf(PropTypes.string).isRequired, |
|||
voteCounts: PropTypes.arrayOf(PropTypes.number).isRequired, |
|||
}; |
|||
|
|||
export default PollChartDonut; |
@ -1,79 +1,76 @@ |
|||
import React, { useMemo } from 'react'; |
|||
import Chart from 'react-apexcharts'; |
|||
import { Grid, Header } from 'semantic-ui-react'; |
|||
import { Grid, Header, Tab } from 'semantic-ui-react'; |
|||
import PropTypes from 'prop-types'; |
|||
import { useTranslation } from 'react-i18next'; |
|||
import { CASTED_OPTION_COLOR, DEFAULT_OPTION_COLOR } from '../../../constants/polls/PollGraph'; |
|||
import PollChartBar from './PollChartBar'; |
|||
import PollChartDonut from './PollChartDonut'; |
|||
import './styles.css'; |
|||
|
|||
const PollGraph = (props) => { |
|||
const { |
|||
pollOptions, voteCounts, hasUserVoted, selectedOptionIndex, |
|||
} = props; |
|||
const { pollOptions, voteCounts } = props; |
|||
const { t } = useTranslation(); |
|||
|
|||
const chartOptions = useMemo(() => ({ |
|||
chart: { |
|||
id: 'topic-poll', |
|||
}, |
|||
plotOptions: { |
|||
bar: { |
|||
horizontal: true, |
|||
}, |
|||
}, |
|||
colors: [ |
|||
(value) => { |
|||
if (hasUserVoted && value.dataPointIndex === selectedOptionIndex) { |
|||
return CASTED_OPTION_COLOR; |
|||
} |
|||
return DEFAULT_OPTION_COLOR; |
|||
}, |
|||
], |
|||
xaxis: { |
|||
categories: pollOptions, |
|||
}, |
|||
}), [hasUserVoted, pollOptions, selectedOptionIndex]); |
|||
const panes = useMemo(() => { |
|||
const chartBarPane = ( |
|||
<Tab.Pane attached={false}> |
|||
<Grid columns="equal"> |
|||
<Grid.Row> |
|||
<Grid.Column /> |
|||
<Grid.Column width={8}> |
|||
<PollChartBar |
|||
pollOptions={pollOptions} |
|||
voteCounts={voteCounts} |
|||
/> |
|||
</Grid.Column> |
|||
<Grid.Column /> |
|||
</Grid.Row> |
|||
<Grid.Row> |
|||
<Grid.Column textAlign="center"> |
|||
<Header as="h4"> |
|||
{t('topic.poll.tab.results.votes.count', { |
|||
totalVotes: voteCounts.reduce((accumulator, voteCount) => accumulator + voteCount, 0), |
|||
})} |
|||
</Header> |
|||
</Grid.Column> |
|||
</Grid.Row> |
|||
</Grid> |
|||
</Tab.Pane> |
|||
); |
|||
const chartDonutPane = ( |
|||
<Tab.Pane attached={false}> |
|||
<Grid columns="equal"> |
|||
<Grid.Row> |
|||
<Grid.Column /> |
|||
<Grid.Column width={8}> |
|||
<PollChartDonut |
|||
pollOptions={pollOptions} |
|||
voteCounts={voteCounts} |
|||
/> |
|||
</Grid.Column> |
|||
<Grid.Column /> |
|||
</Grid.Row> |
|||
<Grid.Row /> |
|||
</Grid> |
|||
</Tab.Pane> |
|||
); |
|||
|
|||
const chartSeries = useMemo(() => [{ |
|||
name: 'votes', |
|||
data: voteCounts, |
|||
}], [voteCounts]); |
|||
return ([ |
|||
{ menuItem: { key: 'chart-bar', icon: 'chart bar' }, render: () => chartBarPane }, |
|||
{ menuItem: { key: 'chart-donut', icon: 'chart pie' }, render: () => chartDonutPane }, |
|||
]); |
|||
}, [pollOptions, t, voteCounts]); |
|||
|
|||
return ( |
|||
<Grid columns="equal"> |
|||
<Grid.Row> |
|||
<Grid.Column /> |
|||
<Grid.Column width={8}> |
|||
<Chart |
|||
options={chartOptions} |
|||
series={chartSeries} |
|||
type="bar" |
|||
/> |
|||
</Grid.Column> |
|||
<Grid.Column /> |
|||
</Grid.Row> |
|||
<Grid.Row> |
|||
<Grid.Column textAlign="center"> |
|||
<Header as="h4"> |
|||
{t('topic.poll.tab.results.votes.count', { |
|||
totalVotes: voteCounts.reduce((accumulator, voteCount) => accumulator + voteCount, 0), |
|||
})} |
|||
</Header> |
|||
</Grid.Column> |
|||
</Grid.Row> |
|||
</Grid> |
|||
<Tab |
|||
menu={{ secondary: true }} |
|||
panes={panes} |
|||
/> |
|||
); |
|||
}; |
|||
|
|||
PollGraph.defaultProps = { |
|||
hasUserVoted: false, |
|||
selectedOptionIndex: '', |
|||
}; |
|||
|
|||
PollGraph.propTypes = { |
|||
pollOptions: PropTypes.arrayOf(PropTypes.string).isRequired, |
|||
voteCounts: PropTypes.arrayOf(PropTypes.number).isRequired, |
|||
hasUserVoted: PropTypes.bool, |
|||
selectedOptionIndex: PropTypes.string, |
|||
}; |
|||
|
|||
export default PollGraph; |
|||
|
@ -0,0 +1,4 @@ |
|||
#topic-poll-container .ui.segment.tab { |
|||
box-shadow: none; |
|||
border: none; |
|||
} |
@ -1,2 +1,2 @@ |
|||
export const DEFAULT_OPTION_COLOR = '#3B5066'; |
|||
export const CASTED_OPTION_COLOR = '#0b2540'; |
|||
export const CHART_TYPE_BAR = 'bar'; |
|||
export const CHART_TYPE_DONUT = 'donut'; |
|||
|
Loading…
Reference in new issue