Skip to content

Commit

Permalink
feat: add todo counting by kind
Browse files Browse the repository at this point in the history
  • Loading branch information
azat-io committed Oct 16, 2024
1 parent cfac0a7 commit 3d63ecf
Show file tree
Hide file tree
Showing 14 changed files with 295 additions and 16 deletions.
2 changes: 2 additions & 0 deletions .cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"words": [
"azat",
"browserslistrc",
"chartjs",
"chrono",
"combak",
"dicebear",
Expand All @@ -27,6 +28,7 @@
"hexdigit",
"lightningcss",
"mockall",
"registerables",
"replacen",
"ropey",
"serde",
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"@typescript-eslint/parser": "^8.9.0",
"browserslist": "^4.24.0",
"changelogen": "^0.5.7",
"chart.js": "^4.4.5",
"clean-publish": "^5.0.0",
"cspell": "^8.15.2",
"date-fns": "^4.1.0",
Expand Down Expand Up @@ -72,6 +73,7 @@
"stylelint-order": "^6.0.4",
"stylelint-plugin-logical-css": "^1.2.1",
"svelte": "5.0.0-next.264",
"svelte-chartjs": "^3.1.5",
"svelte-check": "^4.0.5",
"svelte-eslint-parser": "^0.41.1",
"svelte-preprocess": "^6.0.3",
Expand Down
30 changes: 30 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion preview/blocks/header.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@

<style>
.header {
padding-block: var(--space-m);
padding-block: var(--space-xl);
}
.wrapper {
Expand Down
97 changes: 97 additions & 0 deletions preview/blocks/info.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<script lang="ts">
import ChartDoughnut from '~/elements/chart-doughnut.svelte'
import Typography from '~/elements/typography.svelte'
import Container from '~/elements/container.svelte'
import { data } from '~/stores/data'
$: todosByKind =
$data.data?.reduce((accumulator: Record<string, number>, { kind }) => {
if (kind in accumulator) {
accumulator[kind] = accumulator[kind] + 1
} else {
accumulator[kind] = 1
}
return accumulator
}, {}) || {}
$: todosEntries = Object.entries(todosByKind).sort(([, a], [, b]) => b - a)
$: finalTodosEntries = (() => {
if (todosEntries.length > 5) {
let topFive = todosEntries.slice(0, 4)
let remainingSum = todosEntries
.slice(4)
.reduce((sum, [, value]) => sum + value, 0)
topFive.push(['TOTAL', remainingSum])
return topFive
}
return todosEntries
})()
$: values = finalTodosEntries.map(([, value]) => value)
let colors = [
'primary',
'secondary',
'tertiary',
'quaternary',
'quinary',
'senary',
]
</script>

<Container>
<div class="wrapper">
<div></div>
<div class="chart">
<Typography size="l" tag="h2" mbe="l" align="center"
>Todos by kind</Typography
>
{#if values.length}
<ChartDoughnut {values} />
{/if}
</div>
</div>
<div class="legend">
{#each finalTodosEntries as [kind], index}
<div class="legend-element">
<div
style={`--color: var(--color-additional-${colors[index]});`}
class="legend-color"
></div>
<Typography size="s" tag="span">{kind}</Typography>
</div>
{/each}
</div>
</Container>

<style>
.wrapper {
display: grid;
grid-template-columns: 1fr 420px;
gap: var(--space-l);
margin-block-end: var(--space-xl);
}
.legend {
display: flex;
gap: var(--space-xl);
justify-content: center;
max-inline-size: 800px;
margin-block-start: var(--space-xl);
margin-inline: auto;
}
.legend-element {
display: flex;
gap: var(--space-s);
align-items: center;
}
.legend-color {
inline-size: var(--space-l);
block-size: var(--space-l);
background: var(--color);
border-radius: var(--border-radius);
}
</style>
2 changes: 2 additions & 0 deletions preview/blocks/list.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import { renderComponent } from '@tanstack/svelte-table'
import TableComment from '~/elements/table-comment.svelte'
import Typography from '~/elements/typography.svelte'
import TableCode from '~/elements/table-code.svelte'
import TableUser from '~/elements/table-user.svelte'
import TablePath from '~/elements/table-path.svelte'
Expand Down Expand Up @@ -89,6 +90,7 @@

<div class="list">
<Container>
<Typography size="l" tag="h2" mbe="l">List of commits</Typography>
<Table data={preparedData} {columns} />
</Container>
</div>
Expand Down
44 changes: 44 additions & 0 deletions preview/elements/chart-doughnut.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<script lang="ts">
import type { ChartOptions, ChartData } from 'chart.js'
import Chart from '~/elements/chart.svelte'
import { theme } from '~/stores/theme'
export let values: number[]
$: computedStyles = getComputedStyle(document.body)
$: data = {
datasets: [
{
backgroundColor: [
computedStyles.getPropertyValue('--color-additional-primary'),
computedStyles.getPropertyValue('--color-additional-secondary'),
computedStyles.getPropertyValue('--color-additional-tertiary'),
computedStyles.getPropertyValue('--color-additional-quaternary'),
computedStyles.getPropertyValue('--color-additional-quinary'),
computedStyles.getPropertyValue('--color-additional-senary'),
],
borderColor: computedStyles.getPropertyValue(
'--color-border-secondary',
),
data: values,
},
],
} as ChartData<'doughnut'>
theme.subscribe(() => {
computedStyles = getComputedStyle(document.body)
})
let options: ChartOptions<'doughnut'> = {
plugins: {
legend: {
display: false,
},
},
responsive: true,
}
</script>

<Chart type="doughnut" {options} {data} />
52 changes: 52 additions & 0 deletions preview/elements/chart.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<script lang="ts" generics="T extends ChartType">
/* global T */
// eslint-disable-next-line no-unused-vars
import type { ChartOptions, ChartData, ChartType } from 'chart.js'
import { registerables, Chart } from 'chart.js'
import { onDestroy, onMount } from 'svelte'
Chart.register(...registerables)
export let type: T
export let data: ChartData<T>
export let options: ChartOptions<T>
let canvasRef: HTMLCanvasElement
export let chart: Chart<T> | null = null
onMount(() => {
chart = new Chart(canvasRef, {
options: {
...options,
animation: {
duration: 1000,
},
},
data,
type,
})
})
$: if (chart) {
chart.data = data
chart.options = {
...options,
animation: {
duration: 0,
},
}
chart.update()
}
onDestroy(() => {
if (chart) {
chart.destroy()
chart = null
}
})
</script>

<canvas bind:this={canvasRef}></canvas>
Loading

0 comments on commit 3d63ecf

Please sign in to comment.