refactor(chart): enforce 400-line source limit
Some checks failed
Package component / package (push) Failing after 4m19s
Some checks failed
Package component / package (push) Failing after 4m19s
This commit is contained in:
55
src/demo/DemoChartHost.vue
Normal file
55
src/demo/DemoChartHost.vue
Normal file
@@ -0,0 +1,55 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
|
||||
import { WaveformChart } from '../components'
|
||||
import type { DemoChartModel } from './types'
|
||||
|
||||
const model = defineModel<DemoChartModel>('model', { required: true })
|
||||
|
||||
const waveformChartRef = ref<{ resetViewport: (trackIndex?: number) => void }>()
|
||||
|
||||
function resetViewport() {
|
||||
waveformChartRef.value?.resetViewport()
|
||||
}
|
||||
|
||||
defineExpose({ resetViewport })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="chart-panel">
|
||||
<WaveformChart
|
||||
ref="waveformChartRef"
|
||||
v-model:annotations="model.annotations"
|
||||
v-model:hidden-series-ids="model.hiddenSeriesIds"
|
||||
:data="model.data"
|
||||
:min-zoom-span="model.minZoomSpan"
|
||||
:min-visible-points="5"
|
||||
:initial-x-domain="model.initialXDomain"
|
||||
:display-mode="model.displayMode"
|
||||
:overlay-mode="model.overlayMode"
|
||||
:grid="{
|
||||
rowCount: model.rowCount,
|
||||
columnCount: model.columnCount,
|
||||
showPagination: true,
|
||||
trackLines: model.gridTrackLines,
|
||||
}"
|
||||
:title="model.title"
|
||||
:legend="{
|
||||
position: model.legendPosition,
|
||||
orientation: model.legendOrientation,
|
||||
backgroundColor: model.legendBackgroundColor,
|
||||
interactive: true,
|
||||
}"
|
||||
:frame-style="model.frameStyle"
|
||||
:axes="model.axes"
|
||||
:clean-view="model.cleanView"
|
||||
:show-tooltip="model.showTooltip"
|
||||
:zero-line="model.zeroLine"
|
||||
:frame-number="model.frameWatermarkVisible ? 1 : undefined"
|
||||
:annotations-visible="model.annotationsVisible"
|
||||
:interaction-mode="model.interactionMode"
|
||||
@zoom-end="model.handleZoomEnd"
|
||||
@zoom-reset="model.resetWaveformViewport"
|
||||
/>
|
||||
</section>
|
||||
</template>
|
||||
44
src/demo/DemoControlPanel.vue
Normal file
44
src/demo/DemoControlPanel.vue
Normal file
@@ -0,0 +1,44 @@
|
||||
<script setup lang="ts">
|
||||
import { Button } from 'ant-design-vue'
|
||||
|
||||
import DemoGridFrameControls from './DemoGridFrameControls.vue'
|
||||
import DemoTitleLegendControls from './DemoTitleLegendControls.vue'
|
||||
import DemoViewControls from './DemoViewControls.vue'
|
||||
import type { DemoControlPanelModel } from './types'
|
||||
|
||||
const model = defineModel<DemoControlPanelModel>('model', { required: true })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Button
|
||||
class="mobile-control-toggle"
|
||||
size="small"
|
||||
:aria-expanded="model.controlsOpen"
|
||||
aria-controls="waveform-control-panel"
|
||||
@click="model.controlsOpen = true"
|
||||
>
|
||||
控制面板
|
||||
</Button>
|
||||
<button
|
||||
v-if="model.controlsOpen"
|
||||
type="button"
|
||||
class="control-backdrop"
|
||||
aria-label="关闭控制面板"
|
||||
@click="model.closeControls"
|
||||
/>
|
||||
<aside
|
||||
id="waveform-control-panel"
|
||||
class="control-panel"
|
||||
:class="{ 'is-open': model.controlsOpen }"
|
||||
aria-label="波形图控制"
|
||||
>
|
||||
<div class="control-panel__scroll">
|
||||
<Button class="control-panel__close" type="text" size="small" @click="model.closeControls">
|
||||
关闭
|
||||
</Button>
|
||||
<DemoViewControls :model="model" />
|
||||
<DemoGridFrameControls :model="model" />
|
||||
<DemoTitleLegendControls :model="model" />
|
||||
</div>
|
||||
</aside>
|
||||
</template>
|
||||
157
src/demo/DemoGridFrameControls.vue
Normal file
157
src/demo/DemoGridFrameControls.vue
Normal file
@@ -0,0 +1,157 @@
|
||||
<script setup lang="ts">
|
||||
import { InputNumber, Select, Switch } from 'ant-design-vue'
|
||||
import { ColorPicker } from 'vue3-colorpicker'
|
||||
|
||||
import type { DemoControlPanelModel } from './types'
|
||||
|
||||
const model = defineModel<DemoControlPanelModel>('model', { required: true })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="control-section">
|
||||
<div class="control-section__header">
|
||||
<h2>零值参考线</h2>
|
||||
<Switch v-model:checked="model.zeroLineVisible" size="small" aria-label="显示零值参考线" />
|
||||
</div>
|
||||
<div class="auxiliary-style-controls zero-line-controls" style="margin-top: 10px">
|
||||
<label class="frame-style-control">
|
||||
<span>颜色</span>
|
||||
<ColorPicker
|
||||
v-model:pure-color="model.zeroLineColor"
|
||||
aria-label="零值参考线颜色"
|
||||
use-type="pure"
|
||||
picker-type="chrome"
|
||||
format="hex"
|
||||
:disable-alpha="true"
|
||||
:blur-close="true"
|
||||
/>
|
||||
</label>
|
||||
<label class="frame-style-control">
|
||||
<span>线宽</span>
|
||||
<InputNumber
|
||||
v-model:value="model.zeroLineWidth"
|
||||
:min="0.5"
|
||||
:max="10"
|
||||
:step="0.5"
|
||||
size="small"
|
||||
aria-label="零值参考线线宽"
|
||||
/>
|
||||
</label>
|
||||
<label class="frame-style-control">
|
||||
<span>线型</span>
|
||||
<Select
|
||||
v-model:value="model.zeroLineDash"
|
||||
:options="model.zeroLineDashOptions"
|
||||
size="small"
|
||||
aria-label="零值参考线线型"
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
</section>
|
||||
<section class="control-section">
|
||||
<h2>网格与轴线</h2>
|
||||
<div class="grid-line-controls">
|
||||
<div class="grid-line-control">
|
||||
<span>水平网格</span>
|
||||
<Switch
|
||||
v-model:checked="model.horizontalGridVisible"
|
||||
size="small"
|
||||
aria-label="显示水平网格线"
|
||||
/>
|
||||
<span class="grid-line-color-picker" role="group" aria-label="水平网格线颜色">
|
||||
<ColorPicker
|
||||
v-model:pure-color="model.horizontalGridColor"
|
||||
use-type="pure"
|
||||
picker-type="chrome"
|
||||
format="hex"
|
||||
:disable-alpha="true"
|
||||
:blur-close="true"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
<div class="grid-line-control">
|
||||
<span>垂直网格</span>
|
||||
<Switch
|
||||
v-model:checked="model.verticalGridVisible"
|
||||
size="small"
|
||||
aria-label="显示垂直网格线"
|
||||
/>
|
||||
<span class="grid-line-color-picker" role="group" aria-label="垂直网格线颜色">
|
||||
<ColorPicker
|
||||
v-model:pure-color="model.verticalGridColor"
|
||||
use-type="pure"
|
||||
picker-type="chrome"
|
||||
format="hex"
|
||||
:disable-alpha="true"
|
||||
:blur-close="true"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
<div class="grid-line-control grid-line-control--switch-only">
|
||||
<span>横轴线</span>
|
||||
<Switch v-model:checked="model.xAxisLineVisible" size="small" aria-label="显示横轴线" />
|
||||
</div>
|
||||
<div class="grid-line-control grid-line-control--switch-only">
|
||||
<span>纵轴线</span>
|
||||
<Switch v-model:checked="model.yAxisLineVisible" size="small" aria-label="显示纵轴线" />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="control-section">
|
||||
<h2>图框样式</h2>
|
||||
<div class="frame-style-controls">
|
||||
<label class="frame-style-control">
|
||||
<span>边框颜色</span>
|
||||
<ColorPicker
|
||||
v-model:pure-color="model.frameBorderColor"
|
||||
aria-label="图框边框颜色"
|
||||
use-type="pure"
|
||||
picker-type="chrome"
|
||||
format="rgb"
|
||||
:disable-alpha="false"
|
||||
:blur-close="true"
|
||||
/>
|
||||
</label>
|
||||
<label class="frame-style-control">
|
||||
<span>背景颜色</span>
|
||||
<ColorPicker
|
||||
v-model:pure-color="model.frameBackgroundColor"
|
||||
aria-label="图框背景颜色"
|
||||
use-type="pure"
|
||||
picker-type="chrome"
|
||||
format="rgb"
|
||||
:disable-alpha="false"
|
||||
:blur-close="true"
|
||||
/>
|
||||
</label>
|
||||
<label class="frame-style-control">
|
||||
<span>线宽</span>
|
||||
<InputNumber
|
||||
v-model:value="model.frameBorderWidth"
|
||||
:min="0"
|
||||
:max="10"
|
||||
:step="0.5"
|
||||
size="small"
|
||||
aria-label="图框线宽"
|
||||
/>
|
||||
</label>
|
||||
<label class="frame-style-control">
|
||||
<span>线型</span>
|
||||
<Select
|
||||
v-model:value="model.frameBorderStyle"
|
||||
:options="model.frameBorderStyleOptions"
|
||||
size="small"
|
||||
aria-label="图框线型"
|
||||
/>
|
||||
</label>
|
||||
<label class="frame-style-control frame-style-control--switch">
|
||||
<span>水印</span>
|
||||
<Switch
|
||||
v-model:checked="model.frameWatermarkVisible"
|
||||
size="small"
|
||||
aria-label="显示图框水印"
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
152
src/demo/DemoTitleLegendControls.vue
Normal file
152
src/demo/DemoTitleLegendControls.vue
Normal file
@@ -0,0 +1,152 @@
|
||||
<script setup lang="ts">
|
||||
import { Input, InputNumber, Select, Switch } from 'ant-design-vue'
|
||||
import { ColorPicker } from 'vue3-colorpicker'
|
||||
|
||||
import type { DemoControlPanelModel } from './types'
|
||||
|
||||
const model = defineModel<DemoControlPanelModel>('model', { required: true })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="control-section title-control-section">
|
||||
<div class="control-section__header">
|
||||
<h2>标题</h2>
|
||||
<Switch v-model:checked="model.titleVisible" size="small" aria-label="显示标题" />
|
||||
</div>
|
||||
<div class="title-controls">
|
||||
<label class="title-control title-control--wide">
|
||||
<span>标题名称</span>
|
||||
<Input v-model:value="model.titleText" size="small" aria-label="标题名称" />
|
||||
</label>
|
||||
<label class="title-control title-control--wide">
|
||||
<span>对齐方式</span>
|
||||
<Select
|
||||
v-model:value="model.titleAlign"
|
||||
:options="model.titleAlignOptions"
|
||||
size="small"
|
||||
aria-label="标题对齐方式"
|
||||
/>
|
||||
</label>
|
||||
<label class="title-control">
|
||||
<span>字体</span>
|
||||
<Select
|
||||
v-model:value="model.titleFontFamily"
|
||||
:options="model.titleFontFamilyOptions"
|
||||
size="small"
|
||||
aria-label="标题字体"
|
||||
/>
|
||||
</label>
|
||||
<label class="title-control">
|
||||
<span>字号</span>
|
||||
<InputNumber
|
||||
v-model:value="model.titleFontSize"
|
||||
:min="8"
|
||||
:max="72"
|
||||
:step="1"
|
||||
size="small"
|
||||
aria-label="标题字号"
|
||||
/>
|
||||
</label>
|
||||
<div class="title-control">
|
||||
<span>字体样式</span>
|
||||
<div class="title-style-controls" role="group" aria-label="标题字体样式">
|
||||
<button
|
||||
type="button"
|
||||
aria-label="恢复标题常规样式"
|
||||
title="恢复常规样式"
|
||||
@click="model.resetTitleTextStyle"
|
||||
>
|
||||
A
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
:class="{ 'is-active': model.titleBold }"
|
||||
:aria-pressed="model.titleBold"
|
||||
aria-label="标题粗体"
|
||||
title="粗体"
|
||||
@click="model.titleBold = !model.titleBold"
|
||||
>
|
||||
<b>B</b>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
:class="{ 'is-active': model.titleItalic }"
|
||||
:aria-pressed="model.titleItalic"
|
||||
aria-label="标题斜体"
|
||||
title="斜体"
|
||||
@click="model.titleItalic = !model.titleItalic"
|
||||
>
|
||||
<i>I</i>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
:class="{ 'is-active': model.titleUnderline }"
|
||||
:aria-pressed="model.titleUnderline"
|
||||
aria-label="标题下划线"
|
||||
title="下划线"
|
||||
@click="model.titleUnderline = !model.titleUnderline"
|
||||
>
|
||||
<u>U</u>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<label class="title-control">
|
||||
<span>旋转</span>
|
||||
<InputNumber
|
||||
v-model:value="model.titleRotation"
|
||||
:min="-180"
|
||||
:max="180"
|
||||
:step="1"
|
||||
addon-after="°"
|
||||
size="small"
|
||||
aria-label="标题旋转角度"
|
||||
/>
|
||||
</label>
|
||||
<div class="title-control title-control--color">
|
||||
<span>颜色</span>
|
||||
<ColorPicker
|
||||
v-model:pure-color="model.titleColor"
|
||||
aria-label="标题颜色"
|
||||
use-type="pure"
|
||||
picker-type="chrome"
|
||||
format="hex"
|
||||
:disable-alpha="true"
|
||||
:blur-close="true"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="control-section">
|
||||
<h2>图例</h2>
|
||||
<label class="select-control">
|
||||
<span>位置</span>
|
||||
<Select
|
||||
v-model:value="model.legendPosition"
|
||||
:options="model.legendPositionOptions"
|
||||
size="small"
|
||||
aria-label="图例位置"
|
||||
/>
|
||||
</label>
|
||||
<label class="select-control">
|
||||
<span>排列</span>
|
||||
<Select
|
||||
v-model:value="model.legendOrientation"
|
||||
:options="model.legendOrientationOptions"
|
||||
size="small"
|
||||
aria-label="图例排列"
|
||||
/>
|
||||
</label>
|
||||
<label class="legend-color-control">
|
||||
<span>背景</span>
|
||||
<ColorPicker
|
||||
v-model:pure-color="model.legendBackgroundColor"
|
||||
aria-label="图例背景颜色"
|
||||
use-type="pure"
|
||||
picker-type="chrome"
|
||||
format="rgb"
|
||||
:disable-alpha="false"
|
||||
:blur-close="true"
|
||||
/>
|
||||
</label>
|
||||
</section>
|
||||
</template>
|
||||
82
src/demo/DemoViewControls.vue
Normal file
82
src/demo/DemoViewControls.vue
Normal file
@@ -0,0 +1,82 @@
|
||||
<script setup lang="ts">
|
||||
import { Button, InputNumber, Radio, Select, Switch } from 'ant-design-vue'
|
||||
|
||||
import type { DemoControlPanelModel } from './types'
|
||||
|
||||
const model = defineModel<DemoControlPanelModel>('model', { required: true })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="control-section">
|
||||
<h2>显示方式</h2>
|
||||
<Radio.Group
|
||||
v-model:value="model.displayMode"
|
||||
class="display-mode-control"
|
||||
button-style="solid"
|
||||
size="small"
|
||||
aria-label="波形展示方式"
|
||||
>
|
||||
<Radio.Button value="independent">单独坐标</Radio.Button>
|
||||
<Radio.Button value="separated">多道分离</Radio.Button>
|
||||
<Radio.Button value="compact">多道紧凑</Radio.Button>
|
||||
</Radio.Group>
|
||||
</section>
|
||||
<section class="control-section">
|
||||
<h2>叠加方式</h2>
|
||||
<Radio.Group
|
||||
v-model:value="model.overlayMode"
|
||||
class="display-mode-control"
|
||||
button-style="solid"
|
||||
size="small"
|
||||
aria-label="波形叠加方式"
|
||||
>
|
||||
<Radio.Button value="single-axis">单值轴</Radio.Button>
|
||||
<Radio.Button value="multi-axis">多值轴</Radio.Button>
|
||||
</Radio.Group>
|
||||
</section>
|
||||
<section class="control-section">
|
||||
<h2>视图</h2>
|
||||
<Button block aria-label="重置波形视图" @click="model.resetWaveformViewport"> 重置视图 </Button>
|
||||
<div class="auxiliary-style-controls" style="margin-top: 10px">
|
||||
<label class="frame-style-control frame-style-control--switch">
|
||||
<span>数值 Tooltip</span>
|
||||
<Switch v-model:checked="model.showTooltip" size="small" aria-label="显示数值 Tooltip" />
|
||||
</label>
|
||||
<label class="frame-style-control frame-style-control--switch">
|
||||
<span>净图</span>
|
||||
<Switch v-model:checked="model.cleanView" size="small" aria-label="净图模式" />
|
||||
</label>
|
||||
</div>
|
||||
</section>
|
||||
<section class="control-section">
|
||||
<h2>波形线型</h2>
|
||||
<label class="select-control">
|
||||
<span>波形</span>
|
||||
<Select
|
||||
v-model:value="model.selectedSeriesId"
|
||||
:options="model.seriesStyleOptions"
|
||||
size="small"
|
||||
aria-label="选择波形线型"
|
||||
/>
|
||||
</label>
|
||||
<label class="select-control">
|
||||
<span>线型</span>
|
||||
<Select
|
||||
v-model:value="model.selectedLineStyle"
|
||||
:options="model.lineStyleOptions"
|
||||
size="small"
|
||||
aria-label="设置波形线型"
|
||||
/>
|
||||
</label>
|
||||
</section>
|
||||
<section class="control-section">
|
||||
<h2>图框布局</h2>
|
||||
<div class="grid-size-control" aria-label="波形网格尺寸">
|
||||
<InputNumber v-model:value="model.rowCount" :min="1" :max="10" size="small" />
|
||||
<span>行</span>
|
||||
<span class="control-separator">×</span>
|
||||
<InputNumber v-model:value="model.columnCount" :min="1" :max="10" size="small" />
|
||||
<span>列</span>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
99
src/demo/types.ts
Normal file
99
src/demo/types.ts
Normal file
@@ -0,0 +1,99 @@
|
||||
import type {
|
||||
WaveformAnnotation,
|
||||
WaveformAxesOptions,
|
||||
WaveformData,
|
||||
WaveformDisplayMode,
|
||||
WaveformFrameStyle,
|
||||
WaveformGridTrackLines,
|
||||
WaveformInteractionMode,
|
||||
WaveformLegendOrientation,
|
||||
WaveformLegendPosition,
|
||||
WaveformLineStyle,
|
||||
WaveformOverlayMode,
|
||||
WaveformTitleOptions,
|
||||
WaveformZeroLineOptions,
|
||||
WaveformZoomEndPayload,
|
||||
} from '../components'
|
||||
|
||||
interface SelectOption<T> {
|
||||
label: string
|
||||
value: T
|
||||
}
|
||||
|
||||
export interface DemoControlPanelModel {
|
||||
controlsOpen: boolean
|
||||
displayMode: WaveformDisplayMode
|
||||
overlayMode: WaveformOverlayMode
|
||||
showTooltip: boolean
|
||||
cleanView: boolean
|
||||
selectedSeriesId: string
|
||||
selectedLineStyle: WaveformLineStyle
|
||||
lineStyleOptions: Array<SelectOption<WaveformLineStyle>>
|
||||
seriesStyleOptions: Array<SelectOption<string>>
|
||||
zeroLineVisible: boolean
|
||||
zeroLineColor: string
|
||||
zeroLineWidth: number
|
||||
zeroLineDash: string
|
||||
zeroLineDashOptions: Array<SelectOption<string>>
|
||||
rowCount: number
|
||||
columnCount: number
|
||||
horizontalGridVisible: boolean
|
||||
horizontalGridColor: string
|
||||
verticalGridVisible: boolean
|
||||
verticalGridColor: string
|
||||
xAxisLineVisible: boolean
|
||||
yAxisLineVisible: boolean
|
||||
frameBorderColor: string
|
||||
frameBackgroundColor: string
|
||||
frameBorderWidth: number
|
||||
frameBorderStyle: NonNullable<WaveformFrameStyle['borderStyle']>
|
||||
frameBorderStyleOptions: Array<SelectOption<string>>
|
||||
frameWatermarkVisible: boolean
|
||||
titleVisible: boolean
|
||||
titleText: string
|
||||
titleAlign: NonNullable<WaveformTitleOptions['align']>
|
||||
titleAlignOptions: Array<SelectOption<NonNullable<WaveformTitleOptions['align']>>>
|
||||
titleFontFamily: string
|
||||
titleFontFamilyOptions: Array<SelectOption<string>>
|
||||
titleFontSize: number
|
||||
titleBold: boolean
|
||||
titleItalic: boolean
|
||||
titleUnderline: boolean
|
||||
titleRotation: number
|
||||
titleColor: string
|
||||
legendPosition: WaveformLegendPosition
|
||||
legendPositionOptions: Array<SelectOption<WaveformLegendPosition>>
|
||||
legendOrientation: WaveformLegendOrientation
|
||||
legendOrientationOptions: Array<SelectOption<WaveformLegendOrientation>>
|
||||
legendBackgroundColor: string
|
||||
closeControls: () => void
|
||||
resetTitleTextStyle: () => void
|
||||
resetWaveformViewport: () => void
|
||||
}
|
||||
|
||||
export interface DemoChartModel {
|
||||
data: WaveformData
|
||||
minZoomSpan?: number
|
||||
initialXDomain?: [number, number]
|
||||
displayMode: WaveformDisplayMode
|
||||
overlayMode: WaveformOverlayMode
|
||||
rowCount: number
|
||||
columnCount: number
|
||||
gridTrackLines: WaveformGridTrackLines
|
||||
title: WaveformTitleOptions
|
||||
legendPosition: WaveformLegendPosition
|
||||
legendOrientation: WaveformLegendOrientation
|
||||
legendBackgroundColor: string
|
||||
frameStyle: WaveformFrameStyle
|
||||
axes: WaveformAxesOptions
|
||||
cleanView: boolean
|
||||
showTooltip: boolean
|
||||
zeroLine: WaveformZeroLineOptions
|
||||
frameWatermarkVisible: boolean
|
||||
annotations: WaveformAnnotation[]
|
||||
annotationsVisible: boolean
|
||||
interactionMode: WaveformInteractionMode
|
||||
hiddenSeriesIds: string[]
|
||||
handleZoomEnd: (payload: WaveformZoomEndPayload) => void | Promise<void>
|
||||
resetWaveformViewport: () => void
|
||||
}
|
||||
Reference in New Issue
Block a user