102 lines
2.2 KiB
Vue
102 lines
2.2 KiB
Vue
<template>
|
|
<section class="date-range-chart-card">
|
|
<div class="title">
|
|
<h2 v-text="title" />
|
|
<span v-if="caption" class="caption" v-text="caption" />
|
|
</div>
|
|
<div ref="chartElement" class="chart" :style="{ height }" />
|
|
<div v-if="loading" class="center-tips">
|
|
<t-loading size="1.5rem" text="加载中" />
|
|
</div>
|
|
<chart-range-slider
|
|
v-if="chartShowSlider"
|
|
:model-value="sliderValue"
|
|
:max="maxSliderValue"
|
|
:min-range="5"
|
|
:label="rangeText"
|
|
@change="handleSliderChange"
|
|
/>
|
|
</section>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import type { EChartsOption } from "echarts";
|
|
import ChartRangeSlider from "@/components/ChartRangeSlider.vue";
|
|
import { useStoreChart, useStoreChartWindow } from "@/pages/store/component/useStoreChart";
|
|
|
|
type ChartOptionBuilder = (visibleDateTextList: string[]) => EChartsOption;
|
|
|
|
const props = withDefaults(defineProps<{
|
|
caption?: string;
|
|
dateTextList?: string[];
|
|
height?: string;
|
|
hasData?: boolean;
|
|
loading?: boolean;
|
|
option: EChartsOption | ChartOptionBuilder;
|
|
title: string;
|
|
}>(), {
|
|
caption: "",
|
|
dateTextList: () => [],
|
|
height: "16rem",
|
|
loading: false
|
|
});
|
|
|
|
const dateTextList = computed(() => props.dateTextList);
|
|
const {
|
|
rangeText,
|
|
showSlider: chartShowSlider,
|
|
sliderValue,
|
|
maxSliderValue,
|
|
visibleDateTextList,
|
|
handleSliderChange
|
|
} = useStoreChartWindow(dateTextList);
|
|
const option = computed<EChartsOption>(() => typeof props.option === "function"
|
|
? props.option(visibleDateTextList.value)
|
|
: props.option);
|
|
const { chartElement } = useStoreChart(option);
|
|
</script>
|
|
|
|
<style scoped lang="less">
|
|
.date-range-chart-card {
|
|
padding: 1rem;
|
|
position: relative;
|
|
background: rgba(255, 255, 255, .92);
|
|
box-shadow: var(--td-shadow-1);
|
|
border-radius: 1.25rem;
|
|
|
|
.title {
|
|
gap: .5rem;
|
|
display: flex;
|
|
align-items: baseline;
|
|
justify-content: space-between;
|
|
|
|
h2 {
|
|
color: #0f172a;
|
|
margin: 0 0 .875rem 0;
|
|
font-size: 1rem;
|
|
font-weight: 700;
|
|
}
|
|
|
|
.caption {
|
|
color: #94a3b8;
|
|
font-size: .6875rem;
|
|
}
|
|
}
|
|
|
|
.chart {
|
|
width: 100%;
|
|
}
|
|
}
|
|
|
|
:global(html.theme-dark) {
|
|
.chart-section {
|
|
background: rgba(15, 23, 42, .88);
|
|
box-shadow: 0 .75rem 2rem rgba(2, 6, 23, .32);
|
|
|
|
h2 {
|
|
color: #e2e8f0;
|
|
}
|
|
}
|
|
}
|
|
</style>
|