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 React, { useMemo } from 'react'; |
||||
import Chart from 'react-apexcharts'; |
import { Grid, Header, Tab } from 'semantic-ui-react'; |
||||
import { Grid, Header } from 'semantic-ui-react'; |
|
||||
import PropTypes from 'prop-types'; |
import PropTypes from 'prop-types'; |
||||
import { useTranslation } from 'react-i18next'; |
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 PollGraph = (props) => { |
||||
const { |
const { pollOptions, voteCounts } = props; |
||||
pollOptions, voteCounts, hasUserVoted, selectedOptionIndex, |
|
||||
} = props; |
|
||||
const { t } = useTranslation(); |
const { t } = useTranslation(); |
||||
|
|
||||
const chartOptions = useMemo(() => ({ |
const panes = useMemo(() => { |
||||
chart: { |
const chartBarPane = ( |
||||
id: 'topic-poll', |
<Tab.Pane attached={false}> |
||||
}, |
<Grid columns="equal"> |
||||
plotOptions: { |
<Grid.Row> |
||||
bar: { |
<Grid.Column /> |
||||
horizontal: true, |
<Grid.Column width={8}> |
||||
}, |
<PollChartBar |
||||
}, |
pollOptions={pollOptions} |
||||
colors: [ |
voteCounts={voteCounts} |
||||
(value) => { |
/> |
||||
if (hasUserVoted && value.dataPointIndex === selectedOptionIndex) { |
</Grid.Column> |
||||
return CASTED_OPTION_COLOR; |
<Grid.Column /> |
||||
} |
</Grid.Row> |
||||
return DEFAULT_OPTION_COLOR; |
<Grid.Row> |
||||
}, |
<Grid.Column textAlign="center"> |
||||
], |
<Header as="h4"> |
||||
xaxis: { |
{t('topic.poll.tab.results.votes.count', { |
||||
categories: pollOptions, |
totalVotes: voteCounts.reduce((accumulator, voteCount) => accumulator + voteCount, 0), |
||||
}, |
})} |
||||
}), [hasUserVoted, pollOptions, selectedOptionIndex]); |
</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(() => [{ |
return ([ |
||||
name: 'votes', |
{ menuItem: { key: 'chart-bar', icon: 'chart bar' }, render: () => chartBarPane }, |
||||
data: voteCounts, |
{ menuItem: { key: 'chart-donut', icon: 'chart pie' }, render: () => chartDonutPane }, |
||||
}], [voteCounts]); |
]); |
||||
|
}, [pollOptions, t, voteCounts]); |
||||
|
|
||||
return ( |
return ( |
||||
<Grid columns="equal"> |
<Tab |
||||
<Grid.Row> |
menu={{ secondary: true }} |
||||
<Grid.Column /> |
panes={panes} |
||||
<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> |
|
||||
); |
); |
||||
}; |
}; |
||||
|
|
||||
PollGraph.defaultProps = { |
|
||||
hasUserVoted: false, |
|
||||
selectedOptionIndex: '', |
|
||||
}; |
|
||||
|
|
||||
PollGraph.propTypes = { |
PollGraph.propTypes = { |
||||
pollOptions: PropTypes.arrayOf(PropTypes.string).isRequired, |
pollOptions: PropTypes.arrayOf(PropTypes.string).isRequired, |
||||
voteCounts: PropTypes.arrayOf(PropTypes.number).isRequired, |
voteCounts: PropTypes.arrayOf(PropTypes.number).isRequired, |
||||
hasUserVoted: PropTypes.bool, |
|
||||
selectedOptionIndex: PropTypes.string, |
|
||||
}; |
}; |
||||
|
|
||||
export default PollGraph; |
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 CHART_TYPE_BAR = 'bar'; |
||||
export const CASTED_OPTION_COLOR = '#0b2540'; |
export const CHART_TYPE_DONUT = 'donut'; |
||||
|
Loading…
Reference in new issue