50 lines
1.2 KiB
Vue
50 lines
1.2 KiB
Vue
<script setup lang="ts">
|
|
import type {
|
|
CustomerAnalysisSegmentCode,
|
|
CustomerAnalysisTrendPointDto,
|
|
} from '#/api/customer';
|
|
|
|
import { computed } from 'vue';
|
|
|
|
interface Props {
|
|
points: CustomerAnalysisTrendPointDto[];
|
|
}
|
|
|
|
const props = defineProps<Props>();
|
|
|
|
const emit = defineEmits<{
|
|
(event: 'segment', segmentCode: CustomerAnalysisSegmentCode): void;
|
|
}>();
|
|
|
|
const maxValue = computed(() =>
|
|
Math.max(1, ...(props.points.map((item) => item.value) ?? [1])),
|
|
);
|
|
|
|
function resolveHeight(value: number) {
|
|
const ratio = value / maxValue.value;
|
|
return `${Math.max(14, Math.round(ratio * 96))}px`;
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="ca-card ca-card-full">
|
|
<div class="ca-card-title">客户增长趋势</div>
|
|
<div class="ca-bars">
|
|
<button
|
|
v-for="point in props.points"
|
|
:key="point.label"
|
|
class="ca-bar-col"
|
|
type="button"
|
|
@click="emit('segment', 'active_new')"
|
|
>
|
|
<div class="ca-bar-val">{{ point.value }}</div>
|
|
<div
|
|
class="ca-bar"
|
|
:style="{ height: resolveHeight(point.value) }"
|
|
></div>
|
|
<span class="ca-bar-lbl">{{ point.label }}</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</template>
|