Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add chart plugin #949

Merged
merged 41 commits into from
Nov 8, 2021
Merged
Show file tree
Hide file tree
Changes from 35 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
fef4af1
Add charts plugin
Zerquix18 Sep 2, 2021
a813e94
Merge branch 'snapshot-labs:develop' into develop
Zerquix18 Sep 2, 2021
9d95f80
Remove non-translated locales
Zerquix18 Sep 2, 2021
80214e8
use computed values
Zerquix18 Sep 2, 2021
9f2b207
Merge branch 'develop' of github.com:Zerquix18/snapshot into develop
Zerquix18 Sep 2, 2021
e7dd953
Fix plugin modal on proposal creation error and votes array mutation …
samuveth Sep 3, 2021
3ce69b6
Merge branch 'develop' into develop
samuveth Sep 6, 2021
ba16dd3
Merge branch 'develop' into develop
Zerquix18 Sep 9, 2021
e7d648c
Merge branch 'develop' into develop
bonustrack Sep 13, 2021
5b20983
Merge branch 'develop' into develop
Zerquix18 Sep 13, 2021
4bb8cdc
Lazy load Chart.js and fix charts
Zerquix18 Sep 13, 2021
a1f7997
Merge branch 'develop' into develop
samuveth Sep 17, 2021
98c7ebe
Merge branch 'develop' of github.com:Zerquix18/snapshot into samuv-fixes
samuveth Sep 17, 2021
2e1f8dc
Use defaultParams when available
samuveth Sep 17, 2021
54d0a92
Remove ES locales (should be added through crowdin)
samuveth Sep 17, 2021
e41bf2e
Merge branch 'snapshot-labs:develop' into develop
samuveth Sep 17, 2021
eedc6c4
Merge branch 'develop' of github.com:Zerquix18/snapshot into develop
samuveth Sep 17, 2021
bb65d08
Add default params to charts plugin
samuveth Sep 17, 2021
733689d
Add plugin update hash
samuveth Sep 20, 2021
dadb3b7
Merge branch 'develop' into develop
samuveth Sep 20, 2021
ba8ad05
Merge branch 'develop' of https://github.com/snapshot-labs/snapshot i…
Zerquix18 Sep 20, 2021
0af63d3
Merge branch 'snapshot-labs-develop' into develop
Zerquix18 Sep 20, 2021
723d40b
Merge branch 'develop' of github.com:Zerquix18/snapshot into develop
Zerquix18 Sep 20, 2021
4e58a92
Merge branch 'develop' into develop
Zerquix18 Sep 23, 2021
e4cd3a0
Separate charts into tabs
Zerquix18 Sep 24, 2021
cb590a8
Merge branch 'develop' into develop
samuveth Sep 24, 2021
c259d48
Merge branch 'develop' into develop
samuveth Sep 26, 2021
f2fb58f
Merge branch 'develop' into develop
Zerquix18 Sep 28, 2021
3b67b20
Merge branch 'develop' into develop
samuveth Sep 28, 2021
825b254
Merge branch 'develop' into develop
bonustrack Oct 2, 2021
2abbb78
Merge branch 'develop' into develop
bonustrack Oct 5, 2021
1f06402
Merge branch 'develop' into develop
bonustrack Oct 6, 2021
6dc663b
Merge branch 'develop' into develop
bonustrack Oct 18, 2021
c04219e
Merge branch 'snapshot-labs:develop' into develop
Zerquix18 Oct 26, 2021
a72658d
fix tabs & remove titles from charts
Zerquix18 Oct 26, 2021
2d84949
Merge branch 'develop' into develop
mktcode Nov 2, 2021
cecf536
Merge branch 'develop' into develop
bonustrack Nov 4, 2021
c898999
Merge branch 'develop' into develop
mktcode Nov 5, 2021
4ca0a08
removed unused import
mktcode Nov 5, 2021
8829f92
better styling for tabs in chart plugin
mktcode Nov 5, 2021
f16213a
Merge branch 'develop' into develop
bonustrack Nov 8, 2021
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
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"@vueuse/core": "^5.2.0",
"@walletconnect/web3-provider": "1.4.1",
"autolinker": "^3.14.3",
"chart.js": "^3.5.1",
"eslint": "^7.32.0",
"eth-ens-namehash": "^2.0.8",
"ethereum-blockies-base64": "^1.0.2",
Expand Down
10 changes: 10 additions & 0 deletions src/components/Modal/Plugins.vue
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,16 @@ watch(open, () => {
selectedPlugin.value = {};
}
});

watch(
selectedPlugin,
() =>
(input.value = JSON.stringify(
selectedPlugin.value?.defaultParams ?? {},
null,
2
))
);
</script>

<template>
Expand Down
234 changes: 234 additions & 0 deletions src/components/Plugin/Charts/CustomBlock.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
<script setup>
import { ref, computed, onMounted, watch, watchPostEffect } from 'vue';
mktcode marked this conversation as resolved.
Show resolved Hide resolved

const props = defineProps({
space: Object,
proposal: Object,
votes: Object
});

const Chart = ref(null);
const currentTab = ref('total_votes_per_day');
const totalVotesPerDayChart = ref(null);
const votingPowerPerAddress = ref(null);
const votingPowerPerDay = ref(null);

const space = computed(() => props.space);
const proposal = computed(() => props.proposal);
const votes = computed(() =>
[...props.votes].sort((a, b) => a.created - b.created)
);

function loadDailyChart(Chart) {
const canvasRef = totalVotesPerDayChart.value;
if (!canvasRef) {
return;
}

const dates = new Map();

votes.value.forEach(vote => {
const date = new Date(vote.created * 1000);
const day = `${date.getMonth() + 1}/${date.getDate() + 1}`;

const value = dates.get(day);
if (value) {
dates.set(day, value + 1);
} else {
dates.set(day, 1);
}
});

const labels = Array.from(dates.keys());
const data = {
labels: labels,
datasets: [
{
label: 'Total votes per day',
data: Array.from(dates.values()),
backgroundColor: 'rgba(75, 192, 192, 0.2)',
borderColor: 'rgb(75, 192, 192)',
borderWidth: 1
}
]
};

const config = {
type: 'bar',
data,
};

new Chart(canvasRef, config);
}

function loadShareOfVotingPowerChart(Chart) {
const canvasRef = votingPowerPerAddress.value;
if (!canvasRef) {
return;
}

const MAX_ADDRESSES = 20;

const newVotes = [...votes.value];
newVotes.sort((a, b) => b.balance - a.balance);

let labels = newVotes.map(vote => vote.voter);
let balances = newVotes.map(vote => vote.balance);

if (newVotes.length > MAX_ADDRESSES + 1) {
const extraBalances = balances
.slice(MAX_ADDRESSES)
.reduce((total, current) => total + current);
labels = labels.slice(0, MAX_ADDRESSES);
balances = balances.slice(0, MAX_ADDRESSES);
labels.push('Others');
balances.push(extraBalances);
}

const data = {
labels,
datasets: [
{
label: 'Share of voting power',
data: balances,
backgroundColor: labels.map(label =>
label === 'Others' ? '#cccccc' : '#' + label.substr(-6)
)
}
]
};

const config = {
type: 'doughnut',
data: data,
options: {
maintainAspectRatio: false,
responsive: true,
plugins: {
legend: {
display: true,
position: 'right'
},
}
}
};

new Chart(canvasRef, config);
}

function loadVotingPowerPerDayChart(Chart) {
const canvasRef = votingPowerPerDay.value;
if (!canvasRef) {
return;
}

const datasets = proposal.value.choices.map((choice, index) => {
const votesForThisChoice = votes.value.filter(
vote => vote.choice === index + 1
);
const data = votesForThisChoice.reduce((result, current, index) => {
const date = new Date(current.created * 1000).toString();
const balance = current.balance;

if (index === 0) {
return [{ x: date, y: balance }];
}

const previous = result[index - 1];
return result.concat({ x: date, y: previous.y + balance });
}, []);

return {
label: choice,
data,
fill: false,
borderColor:
votesForThisChoice.length > 0
? '#' + votesForThisChoice[0].voter.substr(-6)
: '', // as close to random as it gets
tension: 0.1
};
});

const data = { datasets };
const options = {
scales: {
x: {
ticks: {
display: false
}
}
},
};

new Chart(canvasRef, { type: 'line', data, options });
}

onMounted(() => {
import('chart.js').then(({ Chart: Chartjs, registerables }) => {
Chartjs.register(...registerables);
Chart.value = Chartjs;
});
});

watch(
[currentTab, Chart],
([currentTab, Chart]) => {
if (currentTab === 'total_votes_per_day') {
loadDailyChart(Chart);
}
if (currentTab === 'share_of_voting_power') {
loadShareOfVotingPowerChart(Chart);
}
if (currentTab === 'voting_power_per_day') {
loadVotingPowerPerDayChart(Chart);
}
},
{ flush: 'post' }
);
</script>

<template>
<Block :title="$t('charts.charts')">
<div class="py-3 flex flex-row">
mktcode marked this conversation as resolved.
Show resolved Hide resolved
<button
v-if="space.plugins?.charts.total_votes_per_day.enabled"
class="block px-4 py-2 sidenav-item"
mktcode marked this conversation as resolved.
Show resolved Hide resolved
:class="currentTab === 'total_votes_per_day' && 'charts-selected-tab'"
@click="currentTab = 'total_votes_per_day'"
>
{{ $t('charts.totalVotesPerDay') }}
</button>
<button
v-if="space.plugins?.charts.voting_power_per_address.enabled"
class="block px-4 py-2 sidenav-item"
mktcode marked this conversation as resolved.
Show resolved Hide resolved
:class="currentTab === 'share_of_voting_power' && 'charts-selected-tab'"
@click="currentTab = 'share_of_voting_power'"
>
{{ $t('charts.shareOfVotingPower') }}
</button>
<button
v-if="space.plugins?.charts.voting_power_per_day.enabled"
class="block px-4 py-2 sidenav-item"
mktcode marked this conversation as resolved.
Show resolved Hide resolved
:class="currentTab === 'voting_power_per_day' && 'charts-selected-tab'"
@click="currentTab = 'voting_power_per_day'"
>
{{ $t('charts.votingPowerPerDay') }}
</button>
</div>
<div v-if="votes.length > 0">
mktcode marked this conversation as resolved.
Show resolved Hide resolved
<div v-if="space.plugins?.charts.total_votes_per_day.enabled && currentTab === 'total_votes_per_day'">
<canvas ref="totalVotesPerDayChart" />
</div>
<div v-if="space.plugins?.charts.voting_power_per_address.enabled && currentTab === 'share_of_voting_power'">
<canvas ref="votingPowerPerAddress" />
</div>
<div v-if="space.plugins?.charts.voting_power_per_day.enabled && currentTab === 'voting_power_per_day'">
<canvas ref="votingPowerPerDay" />
</div>
</div>
<div v-if="votes.length === 0">
mktcode marked this conversation as resolved.
Show resolved Hide resolved
{{ $t('charts.noVotesYet') }}
</div>
</Block>
</template>
3 changes: 3 additions & 0 deletions src/components/Plugin/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
"aragon": {
"proposalParams": true
},
"charts": {
"proposalParams": false
},
"gnosis": {
"proposalParams": true
},
Expand Down
7 changes: 7 additions & 0 deletions src/components/ProposalPluginsContent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const props = defineProps({
id: String,
space: Object,
proposal: Object,
votes: Object,
loadedResults: Boolean
});

Expand Down Expand Up @@ -71,6 +72,12 @@ const safeSnapInput = computed({
:config="space.plugins?.safeSnap"
:network="space.network"
/>
<PluginChartsCustomBlock
v-if="loadedResults && space.plugins?.charts"
:space="space"
:proposal="proposal"
:votes="votes"
/>
<PluginCommentBoxCustomBlock
v-if="space.plugins?.commentBox"
:proposalId="id"
Expand Down
7 changes: 7 additions & 0 deletions src/locales/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,13 @@
"success_claim": "Your POAP is on your address",
"error_claim": "There was a problem minting the token"
},
"charts": {
"charts": "Charts",
"noVotesYet": "There are no votes to visualize yet.",
"totalVotesPerDay": "Total votes per day",
"shareOfVotingPower": "Share of voting power",
"votingPowerPerDay": "Voting power per day"
},
"comment_box": {
"title": "Comment box",
"add": "Add your comment here",
Expand Down
6 changes: 6 additions & 0 deletions src/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,12 @@ select {
}
}

.sidenav-item {
&.charts-selected-tab {
border-bottom: 3px solid;
}
}

.truncated {
display: block;
white-space: nowrap; /* forces text to single line */
Expand Down
1 change: 1 addition & 0 deletions src/views/SpaceProposal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ onMounted(async () => {
:id="id"
:space="space"
:proposal="proposal"
:votes="votes"
:loadedResults="loadedResults"
/>
</template>
Expand Down
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1787,6 +1787,11 @@ chalk@^4.0.0, chalk@^4.1.2:
ansi-styles "^4.1.0"
supports-color "^7.1.0"

chart.js@^3.5.1:
version "3.5.1"
resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-3.5.1.tgz#73e24d23a4134a70ccdb5e79a917f156b6f3644a"
integrity sha512-m5kzt72I1WQ9LILwQC4syla/LD/N413RYv2Dx2nnTkRS9iv/ey1xLTt0DnPc/eWV4zI+BgEgDYBIzbQhZHc/PQ==

checkpoint-store@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/checkpoint-store/-/checkpoint-store-1.1.0.tgz#04e4cb516b91433893581e6d4601a78e9552ea06"
Expand Down