2774671584
vue3-calendar-heatmap has the behaviour that the first and second colors are mapped to values null and 0, meaning the second color was not used as intended for values > 0. I think this is a behaviour change from previous vue2 version that was missed during the upgrade. This change makes first and second values the same, so the heatmap can now use one additional color for meaningful values. Before: <img width="710" alt="Screenshot 2022-12-18 at 09 17 58" src="https://user-images.githubusercontent.com/115237/208288347-df4973af-8ebd-4582-b828-bec948ffdf60.png"> After: <img width="709" alt="Screenshot 2022-12-18 at 09 18 15" src="https://user-images.githubusercontent.com/115237/208288350-e0b85aa2-6925-4a37-83d2-89e2518c91ce.png"> Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
79 lines
2.1 KiB
Vue
79 lines
2.1 KiB
Vue
<template>
|
|
<div id="user-heatmap">
|
|
<div class="total-contributions">
|
|
{{ sum }} contributions in the last 12 months
|
|
</div>
|
|
<calendar-heatmap
|
|
:locale="locale"
|
|
:no-data-text="locale.no_contributions"
|
|
:tooltip-unit="locale.contributions"
|
|
:end-date="endDate"
|
|
:values="values"
|
|
:range-color="colorRange"
|
|
@day-click="handleDayClick($event)"
|
|
/>
|
|
</div>
|
|
</template>
|
|
<script>
|
|
import {CalendarHeatmap} from 'vue3-calendar-heatmap';
|
|
|
|
export default {
|
|
name: 'ActivityHeatmap',
|
|
components: {CalendarHeatmap},
|
|
props: {
|
|
values: {
|
|
type: Array,
|
|
default: () => [],
|
|
},
|
|
locale: {
|
|
type: Object,
|
|
default: () => {},
|
|
}
|
|
},
|
|
data: () => ({
|
|
colorRange: [
|
|
'var(--color-secondary-alpha-70)',
|
|
'var(--color-secondary-alpha-70)',
|
|
'var(--color-primary-light-4)',
|
|
'var(--color-primary-light-2)',
|
|
'var(--color-primary)',
|
|
'var(--color-primary-dark-2)',
|
|
'var(--color-primary-dark-4)',
|
|
],
|
|
endDate: new Date(),
|
|
}),
|
|
computed: {
|
|
sum() {
|
|
let s = 0;
|
|
for (let i = 0; i < this.values.length; i++) {
|
|
s += this.values[i].count;
|
|
}
|
|
return s;
|
|
}
|
|
},
|
|
mounted() {
|
|
// work around issue with first legend color being rendered twice and legend cut off
|
|
const legend = document.querySelector('.vch__external-legend-wrapper');
|
|
legend.setAttribute('viewBox', '12 0 80 10');
|
|
legend.style.marginRight = '-12px';
|
|
},
|
|
methods: {
|
|
handleDayClick(e) {
|
|
// Reset filter if same date is clicked
|
|
const params = new URLSearchParams(document.location.search);
|
|
const queryDate = params.get('date');
|
|
// Timezone has to be stripped because toISOString() converts to UTC
|
|
const clickedDate = new Date(e.date - (e.date.getTimezoneOffset() * 60000)).toISOString().substring(0, 10);
|
|
|
|
if (queryDate && queryDate === clickedDate) {
|
|
params.delete('date');
|
|
} else {
|
|
params.set('date', clickedDate);
|
|
}
|
|
|
|
const newSearch = params.toString();
|
|
window.location.search = newSearch.length ? `?${newSearch}` : '';
|
|
}
|
|
},
|
|
};
|
|
</script>
|