Skip to content

Commit

Permalink
feat(xo-web): add donut chart with legends component
Browse files Browse the repository at this point in the history
  • Loading branch information
P4l0m4 committed Jun 26, 2024
1 parent 3235963 commit 791e649
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 0 deletions.
5 changes: 5 additions & 0 deletions @xen-orchestra/web-core/lib/types/donut-chart.type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export type DonutColor = 'success' | 'warning' | 'error' | 'unknown'
export type DonutSegment = {
value: number
color: DonutColor
}
1 change: 1 addition & 0 deletions @xen-orchestra/web-core/lib/types/ui-legend.type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type LegendColor = 'default' | 'success' | 'warning' | 'error' | 'disabled' | 'dark-blue'
72 changes: 72 additions & 0 deletions @xen-orchestra/web/src/components/DonutWithLegends.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<template>
<div class="donut-with-legends">
<DonutChart :segments="donutSegments" :icon="icon" :max-value="maxValue" />
<ul class="legends">
<UiLegend
v-for="(segment, index) in segments"
:key="index"
:color="segment.color"
:value="segment.value"
:unit="segment.unit"
:tooltip="segment.tooltip"
>
{{ segment.label }}
</UiLegend>
</ul>
</div>
</template>

<script setup lang="ts">
import type { DonutSegment } from '@core/types/donut-chart.type'
import type { LegendColor } from '@core/types/ui-legend.type'
import DonutChart from '@core/components/DonutChart.vue'
import UiLegend from '@core/components/UiLegend.vue'
import type { IconDefinition } from '@fortawesome/fontawesome-common-types'
import { computed } from 'vue'
const props = defineProps<{
segments: {
label: string
value: number
unit?: string
color: LegendColor
tooltip?: string
}[]
icon: IconDefinition
}>()
const maxValue = computed(() => {
return props.segments.reduce((acc, segment) => {
return acc + segment.value
}, 0)
})
const donutSegments = computed(() => {
if (props?.segments.length === 0) {
return []
}
return props.segments
.filter(segment => segment.color !== 'dark-blue')
.map(segment => {
let color
if (segment.color === 'disabled' || segment.color === 'default') {
color = 'unknown'
} else {
color = segment.color
}
return {
value: segment.value,
color,
}
}) as DonutSegment[]
})
</script>

<style lang="postcss" scoped>
.donut-with-legends {
display: flex;
align-items: center;
gap: 3.2rem;
}
</style>

0 comments on commit 791e649

Please sign in to comment.