From e81d1e8426758a146ff672997d6a94ca59279947 Mon Sep 17 00:00:00 2001 From: Ezerous Date: Tue, 6 Apr 2021 20:35:03 +0300 Subject: [PATCH] feat: poll view improvements --- .../public/locales/en/translation.json | 2 +- .../PollView/PollGraph/PollChartBar/index.jsx | 56 +++++++++ .../PollGraph/PollChartDonut/index.jsx | 49 ++++++++ .../components/PollView/PollGraph/index.jsx | 117 +++++++++--------- .../components/PollView/PollGraph/styles.css | 4 + .../src/components/PollView/index.jsx | 12 +- .../src/constants/polls/PollGraph.js | 4 +- 7 files changed, 175 insertions(+), 69 deletions(-) create mode 100644 packages/concordia-app/src/components/PollView/PollGraph/PollChartBar/index.jsx create mode 100644 packages/concordia-app/src/components/PollView/PollGraph/PollChartDonut/index.jsx create mode 100644 packages/concordia-app/src/components/PollView/PollGraph/styles.css diff --git a/packages/concordia-app/public/locales/en/translation.json b/packages/concordia-app/public/locales/en/translation.json index 5c2c92d..3eb7a2d 100644 --- a/packages/concordia-app/public/locales/en/translation.json +++ b/packages/concordia-app/public/locales/en/translation.json @@ -90,7 +90,7 @@ "topic.poll.invalid.data.header": "This topic has a poll but the data are untrusted!", "topic.poll.invalid.data.sub.header": "The poll data downloaded from the poster have been tampered with.", "topic.poll.tab.graph.title": "Results", - "topic.poll.tab.results.votes.count": "{{totalVotes}} votes casted", + "topic.poll.tab.results.votes.count": "Total votes: {{totalVotes}}", "topic.poll.tab.vote.form.button.submit": "Submit", "topic.poll.tab.vote.form.radio.label": "Select one of the options:", "topic.poll.tab.vote.title": "Vote", diff --git a/packages/concordia-app/src/components/PollView/PollGraph/PollChartBar/index.jsx b/packages/concordia-app/src/components/PollView/PollGraph/PollChartBar/index.jsx new file mode 100644 index 0000000..313a3e8 --- /dev/null +++ b/packages/concordia-app/src/components/PollView/PollGraph/PollChartBar/index.jsx @@ -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 ( + + ); +}; + +PollChartBar.propTypes = { + pollOptions: PropTypes.arrayOf(PropTypes.string).isRequired, + voteCounts: PropTypes.arrayOf(PropTypes.number).isRequired, +}; + +export default PollChartBar; diff --git a/packages/concordia-app/src/components/PollView/PollGraph/PollChartDonut/index.jsx b/packages/concordia-app/src/components/PollView/PollGraph/PollChartDonut/index.jsx new file mode 100644 index 0000000..e592d74 --- /dev/null +++ b/packages/concordia-app/src/components/PollView/PollGraph/PollChartDonut/index.jsx @@ -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 ( + + ); +}; + +PollChartDonut.propTypes = { + pollOptions: PropTypes.arrayOf(PropTypes.string).isRequired, + voteCounts: PropTypes.arrayOf(PropTypes.number).isRequired, +}; + +export default PollChartDonut; diff --git a/packages/concordia-app/src/components/PollView/PollGraph/index.jsx b/packages/concordia-app/src/components/PollView/PollGraph/index.jsx index 12d77d7..770a844 100644 --- a/packages/concordia-app/src/components/PollView/PollGraph/index.jsx +++ b/packages/concordia-app/src/components/PollView/PollGraph/index.jsx @@ -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 = ( + + + + + + + + + + + +
+ {t('topic.poll.tab.results.votes.count', { + totalVotes: voteCounts.reduce((accumulator, voteCount) => accumulator + voteCount, 0), + })} +
+
+
+
+
+ ); + const chartDonutPane = ( + + + + + + + + + + + + + ); - 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 ( - - - - - - - - - - -
- {t('topic.poll.tab.results.votes.count', { - totalVotes: voteCounts.reduce((accumulator, voteCount) => accumulator + voteCount, 0), - })} -
-
-
-
+ ); }; -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; diff --git a/packages/concordia-app/src/components/PollView/PollGraph/styles.css b/packages/concordia-app/src/components/PollView/PollGraph/styles.css new file mode 100644 index 0000000..a2c3d42 --- /dev/null +++ b/packages/concordia-app/src/components/PollView/PollGraph/styles.css @@ -0,0 +1,4 @@ +#topic-poll-container .ui.segment.tab { + box-shadow: none; + border: none; +} diff --git a/packages/concordia-app/src/components/PollView/index.jsx b/packages/concordia-app/src/components/PollView/index.jsx index 801b7a2..a7c2445 100644 --- a/packages/concordia-app/src/components/PollView/index.jsx +++ b/packages/concordia-app/src/components/PollView/index.jsx @@ -1,4 +1,6 @@ -import React, { useEffect, useMemo, useState } from 'react'; +import React, { + useEffect, useMemo, useState, +} from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { VOTING_CONTRACT } from 'concordia-shared/src/constants/contracts/ContractNames'; import { @@ -145,12 +147,10 @@ const PollView = (props) => { ) : null - ), [chainDataLoading, orbitDataLoading, pollOptions, userHasVoted, userVoteIndex, voteCounts]); + ), [chainDataLoading, orbitDataLoading, pollOptions, voteCounts]); const panes = useMemo(() => { const pollVotePane = ( @@ -165,8 +165,8 @@ const PollView = (props) => { ); return ([ - { menuItem: t(VOTE_TAB.intl_display_name_id), render: () => pollVotePane }, { menuItem: t(GRAPH_TAB.intl_display_name_id), render: () => pollGraphPane }, + { menuItem: t(VOTE_TAB.intl_display_name_id), render: () => pollVotePane }, ]); }, [chainDataLoading, orbitDataLoading, pollGraphTab, pollVoteTab, t]); @@ -182,7 +182,7 @@ const PollView = (props) => { {!chainDataLoading && !orbitDataLoading ? ( <>
- + {pollQuestion}
diff --git a/packages/concordia-app/src/constants/polls/PollGraph.js b/packages/concordia-app/src/constants/polls/PollGraph.js index a19a2ee..d2a7a3b 100644 --- a/packages/concordia-app/src/constants/polls/PollGraph.js +++ b/packages/concordia-app/src/constants/polls/PollGraph.js @@ -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';