import { reactive, watch } from 'vue' import { ECOption } from '@/components/base/echarts/core' import { ChartCycleType } from '@/constants/chart' import { useGlobalStore } from '@/stores' import { EchartsDataset, EchartsOptions, Colors } from './types' import moment from 'moment' const globalStore = useGlobalStore() const { appTheme } = globalStore.$toRefs() function getColors() { // 默认主题色配置 const defaultColors: Colors = { upColor: '#ff3333', downColor: '#0aab62', xAxisLineColor: 'rgba(128,128,128,.1)', yAxisLineColor: 'rgba(128,128,128,.1)', } const colors = { default: defaultColors, dark: defaultColors, light: { ...defaultColors, xAxisLineColor: '#dae5ec', yAxisLineColor: '#dae5ec', } } return colors[appTheme.value]; } export function useOptions(dataset: EchartsDataset) { // 图表配置项 const options = reactive({ cycleType: ChartCycleType.Minutes, colors: getColors(), candlestick: {}, macd: {}, vol: {}, kdj: {}, cci: {}, }) const getDefaultOption = (): ECOption => { const { source } = dataset.candlestick; const { xAxisLineColor, yAxisLineColor } = options.colors; return { grid: { left: '25px', right: '25px', top: '20px', bottom: '15px', containLabel: true, }, dataZoom: { type: 'inside', startValue: source.length - 60, // 起始显示K线条数(最新60条) end: 100, minValueSpan: 30, // 限制窗口缩放显示最少数据条数 maxValueSpan: 200, // 限制窗口缩放显示最大数据条数 }, axisPointer: { label: { backgroundColor: 'rgba(72,72,72,.75)' } }, xAxis: { type: 'category', axisLabel: { color: '#777', margin: 12, formatter: (val: string) => { switch (options.cycleType) { case ChartCycleType.Day: { return moment(val).format('YYYY-MM-DD') } default: { return moment(val).format('HH:mm') } } }, // interval: (index) => { // return index % 8 === 0 // } }, axisLine: { lineStyle: { color: xAxisLineColor, // 坐标轴线线的颜色 } }, axisPointer: { label: { formatter: (params) => { switch (options.cycleType) { case ChartCycleType.Day: { return moment(params.value).format('YYYY-MM-DD') } default: { return moment(params.value).format('YYYY-MM-DD HH:mm:ss') } } }, } }, axisTick: { show: false, }, // splitLine: { // show: true, // lineStyle: { // color: xAxisLineColor, // }, // }, }, yAxis: { scale: true, splitLine: { lineStyle: { // 坐标分隔线颜色 color: yAxisLineColor, }, }, }, } } // K线配置项 const setCandlestickOption = () => { const { dimensions, source } = dataset.candlestick; const { upColor, downColor } = options.colors; options.candlestick = { ...getDefaultOption(), dataset: { dimensions, source, }, series: [ { name: 'K线', type: 'candlestick', barWidth: '80%', itemStyle: { color: upColor, color0: downColor, borderColor: upColor, borderColor0: downColor, }, // 最新价标线 markLine: { symbol: 'none', // 标线标签样式 label: { show: false, color: '#fff', backgroundColor: 'rgba(72,72,72,.75)', padding: 5, borderRadius: 3, position: 'insideStartTop', }, // 标线样式 lineStyle: { type: 'dashed', color: 'rgba(102,102,102,.7)' }, data: [ { // 收盘价 yAxis: source.length ? source[source.length - 1].close : 0, }, ], }, }, { name: 'MA5', type: 'line', sampling: 'average', //折线图在数据量远大于像素点时候的降采样策略,开启后可以有效的优化图表的绘制效率 smooth: true, symbol: 'none', lineStyle: { width: 1, opacity: 0.8, }, }, { name: 'MA10', type: 'line', sampling: 'average', smooth: true, symbol: 'none', lineStyle: { width: 1, opacity: 0.8, }, }, { name: 'MA15', type: 'line', sampling: 'average', smooth: true, symbol: 'none', lineStyle: { width: 1, opacity: 0.8, }, }, ], } } // MACD配置项 const setMacdOption = () => { const { upColor, downColor, yAxisLineColor } = options.colors; const { dimensions, source } = dataset.macd; options.macd = { ...getDefaultOption(), yAxis: { scale: true, splitNumber: 2, splitLine: { lineStyle: { // 坐标分隔线颜色 color: yAxisLineColor, }, }, }, dataset: { dimensions, source, }, series: [ { name: 'MACD', type: 'bar', sampling: 'average', barWidth: '60%', itemStyle: { color: ({ data }) => { const { macd } = data as { macd: number }; if (macd > 0) { return upColor; } else { return downColor; } }, } }, { name: 'DIF', type: 'line', sampling: 'average', smooth: true, symbol: 'none', lineStyle: { width: 1, opacity: 0.8, }, }, { name: 'DEA', type: 'line', sampling: 'average', smooth: true, symbol: 'none', lineStyle: { width: 1, opacity: 0.8, }, }, ], } } // VOL配置项 const setVolOption = () => { const { yAxisLineColor } = options.colors; const { dimensions, source } = dataset.vol; options.vol = { ...getDefaultOption(), yAxis: { scale: true, splitNumber: 2, splitLine: { lineStyle: { // 坐标分隔线颜色 color: yAxisLineColor, }, }, }, dataset: { dimensions, source, }, series: [ { name: 'VOL', type: 'bar', sampling: 'average', barWidth: '60%', }, ], } } // KDJ配置项 const setKdjOption = () => { const { yAxisLineColor } = options.colors; const { dimensions, source } = dataset.kdj; options.kdj = { ...getDefaultOption(), yAxis: { scale: true, splitNumber: 2, splitLine: { lineStyle: { // 坐标分隔线颜色 color: yAxisLineColor, }, }, }, dataset: { dimensions, source, }, series: [ { name: 'K', type: 'line', sampling: 'average', smooth: true, symbol: 'none', lineStyle: { width: 1, opacity: 0.8, }, }, { name: 'D', type: 'line', sampling: 'average', smooth: true, symbol: 'none', lineStyle: { width: 1, opacity: 0.8, }, }, { name: 'J', type: 'line', sampling: 'average', smooth: true, symbol: 'none', lineStyle: { width: 1, opacity: 0.8, }, }, ], } } // CCI配置项 const setCciOption = () => { const { yAxisLineColor } = options.colors; const { dimensions, source } = dataset.cci; options.cci = { ...getDefaultOption(), yAxis: { scale: true, splitNumber: 2, splitLine: { lineStyle: { // 坐标分隔线颜色 color: yAxisLineColor, }, }, }, dataset: { dimensions, source, }, series: [ { name: 'CCI', type: 'line', sampling: 'average', smooth: true, symbol: 'none', lineStyle: { width: 1, opacity: 0.8, }, }, ], } } const initOptions = () => { setCandlestickOption(); setMacdOption(); setVolOption(); setKdjOption(); setCciOption(); } // 动态更新数据 const updateOptions = () => { const { candlestick, macd, vol, kdj, cci } = dataset; options.candlestick = { dataset: { source: candlestick.source, }, series: [ { name: 'K线', markLine: { data: [ { yAxis: candlestick.source[candlestick.source.length - 1].close, }, ], }, }, ], } options.macd = { dataset: { source: macd.source, }, } options.vol = { dataset: { source: vol.source, }, } options.kdj = { dataset: { source: kdj.source, }, } options.cci = { dataset: { source: cci.source, }, } } // 监听主题变化 watch(appTheme, () => { options.colors = getColors(); initOptions(); }) return { options, initOptions, updateOptions, } }