diff --git a/package.json b/package.json index 8ce5c97..6ee89b5 100644 --- a/package.json +++ b/package.json @@ -25,11 +25,11 @@ "pinia": "^2.0.11", "qrcode.vue": "^3.2.2", "tdesign-icons-vue-next": "^0.0.6", - "tdesign-vue-next": "~0.11.2", + "tdesign-vue-next": "^0.13.0", "tvision-color": "^1.3.1", "vue": "^3.2.31", - "vue-router": "^4.0.11", - "vue-clipboard3": "^2.0.0" + "vue-clipboard3": "^2.0.0", + "vue-router": "^4.0.11" }, "devDependencies": { "@commitlint/cli": "^16.2.1", diff --git a/src/pages/dashboard/base/index.ts b/src/pages/dashboard/base/index.ts index 80938c5..a386bce 100644 --- a/src/pages/dashboard/base/index.ts +++ b/src/pages/dashboard/base/index.ts @@ -1,89 +1,7 @@ import dayjs from 'dayjs'; -import * as echarts from 'echarts/core'; -import { Color } from 'tvision-color'; -import { getBrandColor, defaultLightColor, defaultDarkColor, TChartColor } from '@/config/color'; -import { getSettingStore } from '@/store'; - -/** - * 依据主题类型获取颜色 - * - * @export - * @param {string} theme - * @returns {} - */ -export function getColorFromTheme(theme: string) { - const settingStore = getSettingStore(); - const { colorList, mode } = settingStore; - const isDarkMode = mode === 'dark'; - let themeColorList = []; - const themeColor = getBrandColor(theme, colorList); - - if (!/^#[A-F\d]{6}$/i.test(theme)) { - theme = themeColor?.['@brand-color'] || '#0052D9'; - const themIdx = defaultLightColor.indexOf(theme.toLocaleLowerCase()); - const defaultGradients = !isDarkMode ? defaultLightColor : defaultDarkColor; - - const spliceThemeList = defaultGradients.slice(0, themIdx); - themeColorList = defaultGradients.slice(themIdx, defaultGradients.length).concat(spliceThemeList); - } else { - theme = themeColor?.['@brand-color']; - themeColorList = Color.getRandomPalette({ - color: theme, - colorGamut: 'bright', - number: 8, - }); - } - - return themeColorList; -} - -/** 图表颜色 */ -function chartListColor(): Array { - const settingStore = getSettingStore(); - const { brandTheme } = settingStore; - const res = getColorFromTheme(brandTheme); - - return res; -} - -/** - * 获取表头数据 - * - * @export - * @param {string[]} dateTime - * @param {number} divideNum - * @returns {string[]} - */ -export function getDateArray(dateTime: string[] = [], divideNum = 10): string[] { - const timeArray: string[] = []; - if (dateTime.length > 0) { - for (let i = 0; i < divideNum; i++) { - const dateAbsTime: number = (new Date(dateTime[1]).getTime() - new Date(dateTime[0]).getTime()) / divideNum; - const enhandTime: number = new Date(dateTime[0]).getTime() + dateAbsTime * i; - timeArray.push(dayjs(enhandTime).format('YYYY-MM-DD')); - } - } - - return timeArray; -} - -/** - * 获取随机数 - * - * @param {number} [num=100] - * @returns - * - * @memberOf DashboardBase - */ -export function getRandomArray(num = 100) { - let resultNum = Number((Math.random() * num).toFixed(0)); - - if (resultNum <= 1) { - resultNum = 1; - } - - return resultNum; -} +import { TChartColor } from '@/config/color'; +import { getChartListColor } from '@/utils/color'; +import { getRandomArray } from '@/utils/charts'; /** 首页 dashboard 折线图 */ export function constructInitDashboardDataset(type: string) { @@ -137,7 +55,7 @@ export function constructInitDashboardDataset(type: string) { } const barDataset = { ...datasetAxis, - color: chartListColor(), + color: getChartListColor(), series: [ { data: [ @@ -205,7 +123,7 @@ export function constructInitDataset({ // console.log('timeArray..', timeArray); const dataset = { - color: chartListColor(), + color: getChartListColor(), tooltip: { trigger: 'item', }, @@ -217,7 +135,7 @@ export function constructInitDataset({ }, axisLine: { lineStyle: { - color: chartListColor()[1], + color: getChartListColor()[1], width: 1, }, }, @@ -270,267 +188,6 @@ export function constructInitDataset({ return dataset; } -/** 平滑图数据 */ -export function getSmoothLineDataSet({ - dateTime = [], - placeholderColor, - borderColor, -}: { dateTime?: Array } & TChartColor) { - let dateArray: Array = ['00:00', '02:00', '04:00', '06:00']; - if (dateTime.length > 0) { - const divideNum = 7; - dateArray = getDateArray(dateTime, divideNum); - } - - return { - color: chartListColor(), - tooltip: { - trigger: 'item', - }, - grid: { - top: '10px', - left: '0', - right: '20px', - bottom: '36px', - containLabel: true, - }, - xAxis: { - type: 'category', - data: dateArray, - boundaryGap: false, - axisLabel: { - color: placeholderColor, - }, - axisLine: { - lineStyle: { - color: borderColor, - width: 1, - }, - }, - }, - yAxis: { - type: 'value', - axisLabel: { - color: placeholderColor, - }, - splitLine: { - lineStyle: { - color: borderColor, - }, - }, - }, - legend: { - data: ['本月', '上月'], - icon: 'circle', - bottom: '0', - itemGap: 48, - itemHeight: 8, - itemWidth: 8, - textStyle: { - fontSize: 12, - color: placeholderColor, - }, - }, - series: [ - { - name: '上月', - data: [ - getRandomArray(), - getRandomArray(), - getRandomArray(), - getRandomArray(), - getRandomArray(), - getRandomArray(), - getRandomArray(), - ], - type: 'line', - smooth: true, - color: chartListColor()[0], - showSymbol: true, - symbol: 'circle', - symbolSize: 8, - areaStyle: { - normal: { - opacity: 0.1, - }, - }, - }, - { - name: '本月', - data: [ - getRandomArray(), - getRandomArray(), - getRandomArray(), - getRandomArray(), - getRandomArray(), - getRandomArray(), - getRandomArray(), - ], - type: 'line', - smooth: true, - showSymbol: true, - symbol: 'circle', - symbolSize: 8, - color: chartListColor()[1], - }, - ], - }; -} - -/** 折线图数据 */ -export function getFolderLineDataSet({ - dateTime = [], - placeholderColor, - borderColor, -}: { dateTime?: Array } & TChartColor) { - let dateArray: Array = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']; - if (dateTime.length > 0) { - const divideNum = 7; - dateArray = getDateArray(dateTime, divideNum); - } - return { - color: chartListColor(), - grid: { - top: '5%', - right: '10px', - left: '30px', - bottom: '60px', - }, - legend: { - left: 'center', - bottom: '0', - orient: 'horizontal', // legend 横向布局。 - data: ['杯子', '茶叶', '蜂蜜', '面粉'], - textStyle: { - fontSize: 12, - color: placeholderColor, - }, - }, - xAxis: { - type: 'category', - data: dateArray, - boundaryGap: false, - axisLabel: { - color: placeholderColor, - }, - axisLine: { - lineStyle: { - color: borderColor, - width: 1, - }, - }, - }, - yAxis: { - type: 'value', - axisLabel: { - color: placeholderColor, - }, - splitLine: { - lineStyle: { - color: borderColor, - }, - }, - }, - tooltip: { - trigger: 'item', - }, - series: [ - { - showSymbol: true, - symbol: 'circle', - symbolSize: 8, - name: '杯子', - stack: '总量', - data: [ - getRandomArray(), - getRandomArray(), - getRandomArray(), - getRandomArray(), - getRandomArray(), - getRandomArray(), - getRandomArray(), - ], - type: 'line', - itemStyle: { - normal: { - borderColor, - borderWidth: 1, - }, - }, - }, - { - showSymbol: true, - symbol: 'circle', - symbolSize: 8, - name: '茶叶', - stack: '总量', - data: [ - getRandomArray(), - getRandomArray(), - getRandomArray(), - getRandomArray(), - getRandomArray(), - getRandomArray(), - getRandomArray(), - ], - type: 'line', - itemStyle: { - normal: { - borderColor, - borderWidth: 1, - }, - }, - }, - { - showSymbol: true, - symbol: 'circle', - symbolSize: 8, - name: '蜂蜜', - stack: '总量', - data: [ - getRandomArray(), - getRandomArray(), - getRandomArray(), - getRandomArray(), - getRandomArray(), - getRandomArray(), - getRandomArray(), - ], - type: 'line', - itemStyle: { - normal: { - borderColor, - borderWidth: 1, - }, - }, - }, - { - showSymbol: true, - symbol: 'circle', - symbolSize: 8, - name: '面粉', - stack: '总量', - data: [ - getRandomArray(), - getRandomArray(), - getRandomArray(), - getRandomArray(), - getRandomArray(), - getRandomArray(), - getRandomArray(), - ], - type: 'line', - itemStyle: { - normal: { - borderColor, - borderWidth: 1, - }, - }, - }, - ], - }; -} - /** * 线性图表数据源 * @@ -566,7 +223,7 @@ export function getLineChartDataSet({ } const dataSet = { - color: chartListColor(), + color: getChartListColor(), tooltip: { trigger: 'item', }, @@ -652,419 +309,6 @@ export function getLineChartDataSet({ return dataSet; } -/** - * 获取表行数据 - * - * @export - * @param {string} productName - * @param {number} divideNum - */ -export function getSelftItemList(productName: string, divideNum: number): string[] { - const productArray: string[] = [productName]; - for (let i = 0; i < divideNum; i++) { - productArray.push(getRandomArray(100 * i).toString()); - } - - return productArray; -} - -/** - * 散点图数据 - * - * @export - * @returns {} - */ -export function getScatterDataSet({ - dateTime = [], - placeholderColor, - borderColor, -}: { dateTime?: Array } & TChartColor): any { - const divideNum = 40; - const timeArray = []; - const inArray = []; - const outArray = []; - for (let i = 0; i < divideNum; i++) { - // const [timeArray, inArray, outArray] = dataset; - if (dateTime.length > 0) { - const dateAbsTime: number = (new Date(dateTime[1]).getTime() - new Date(dateTime[0]).getTime()) / divideNum; - const enhandTime: number = new Date(dateTime[0]).getTime() + dateAbsTime * i; - timeArray.push(dayjs(enhandTime).format('MM-DD')); - } else { - timeArray.push( - dayjs() - .subtract(divideNum - i, 'day') - .format('MM-DD'), - ); - } - - inArray.push(getRandomArray().toString()); - outArray.push(getRandomArray().toString()); - } - - return { - color: chartListColor(), - xAxis: { - data: timeArray, - axisLabel: { - color: placeholderColor, - }, - splitLine: { show: false }, - axisLine: { - lineStyle: { - color: borderColor, - width: 1, - }, - }, - }, - yAxis: { - type: 'value', - // splitLine: { show: false}, - axisLabel: { - color: placeholderColor, - }, - nameTextStyle: { - padding: [0, 0, 0, 60], - }, - axisTick: { - show: false, - axisLine: { - show: false, - }, - }, - axisLine: { - show: false, - }, - splitLine: { - lineStyle: { - color: borderColor, - }, - }, - }, - tooltip: { - trigger: 'item', - }, - grid: { - top: '5px', - left: '25px', - right: '5px', - bottom: '60px', - }, - legend: { - left: 'center', - bottom: '0', - orient: 'horizontal', // legend 横向布局。 - data: ['按摩仪', '咖啡机'], - itemHeight: 8, - itemWidth: 8, - textStyle: { - fontSize: 12, - color: placeholderColor, - }, - }, - series: [ - { - name: '按摩仪', - symbolSize: 10, - data: outArray.reverse(), - type: 'scatter', - }, - { - name: '咖啡机', - symbolSize: 10, - data: inArray.concat(inArray.reverse()), - type: 'scatter', - }, - ], - }; -} -/** - * 获域图数据结构 - * - * @export - * @returns {} - */ -export function getAreaChartDataSet(): any { - const xAxisData = []; - const data1 = []; - const data2 = []; - for (let i = 0; i < 50; i++) { - xAxisData.push(`${i}`); - data1.push((getRandomArray() * Math.sin(i / 5) * (i / 5 - 5) + i / 6) * 2); - data2.push((getRandomArray() * Math.cos(i / 5) * (i / 5 - 5) + i / 6) * 2); - } - - return { - color: chartListColor(), - // title: { - // text: '柱状图动画延迟', - // }, - legend: { - left: 'center', - bottom: '5%', - orient: 'horizontal', - data: ['测试', '上线'], - }, - tooltip: { - trigger: 'item', - }, - xAxis: { - data: xAxisData, - splitLine: { - show: false, - }, - }, - yAxis: {}, - series: [ - { - name: '测试', - type: 'bar', - data: data1, - emphasis: { - focus: 'series', - }, - animationDelay(idx: number) { - return idx * 10; - }, - }, - { - name: '上线', - type: 'bar', - data: data2, - emphasis: { - focus: 'series', - }, - animationDelay(idx: number) { - return idx * 10 + 100; - }, - }, - ], - animationEasing: 'elasticOut', - animationDelayUpdate(idx: number) { - return idx * 5; - }, - }; -} - -/** - * 柱状图数据结构 - * - * @export - * @param {boolean} [isMonth=false] - * @returns {*} - */ -export function getColumnChartDataSet(isMonth = false) { - if (isMonth) { - return { - color: chartListColor(), - legend: { - left: 'center', - top: '10%', - orient: 'horizontal', // legend 横向布局。 - data: ['直接访问'], - }, - tooltip: { - trigger: 'axis', - axisPointer: { - // 坐标轴指示器,坐标轴触发有效 - type: 'shadow', // 默认为直线,可选为:'line' | 'shadow' - }, - }, - grid: { - left: '3%', - right: '4%', - bottom: '3%', - containLabel: true, - }, - xAxis: [ - { - type: 'category', - data: ['1', '4', '8', '12', '16', '20', '24'], - axisTick: { - alignWithLabel: true, - }, - }, - ], - yAxis: [ - { - type: 'value', - }, - ], - series: [ - { - name: '直接访问', - type: 'bar', - barWidth: '60%', - data: [ - getRandomArray(Math.random() * 100), - getRandomArray(Math.random() * 200), - getRandomArray(Math.random() * 300), - getRandomArray(Math.random() * 400), - getRandomArray(Math.random() * 500), - getRandomArray(Math.random() * 600), - getRandomArray(Math.random() * 700), - ], - }, - ], - }; - } - return { - color: chartListColor(), - tooltip: { - trigger: 'axis', - axisPointer: { - // 坐标轴指示器,坐标轴触发有效 - type: 'shadow', // 默认为直线,可选为:'line' | 'shadow' - }, - }, - legend: { - left: 'center', - bottom: '0%', - orient: 'horizontal', // legend 横向布局。 - data: ['直接访问'], - }, - grid: { - left: '3%', - right: '4%', - bottom: '13%', - containLabel: true, - }, - xAxis: [ - { - type: 'category', - data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'], - axisTick: { - alignWithLabel: true, - }, - }, - ], - yAxis: [ - { - type: 'value', - }, - ], - series: [ - { - name: '直接访问', - type: 'bar', - barWidth: '20%', - data: [ - getRandomArray(Math.random() * 100), - getRandomArray(Math.random() * 200), - getRandomArray(Math.random() * 300), - getRandomArray(Math.random() * 400), - getRandomArray(Math.random() * 500), - getRandomArray(Math.random() * 600), - getRandomArray(Math.random() * 700), - ], - }, - ], - }; -} - -export const lastYearList: Array = [100, 120, 140, 160, 180, 200, 210]; - -/** - * 柱状图数据结构 - * - * @export - * @param {boolean} [isMonth=false] - * @returns {*} - */ -export function get2ColBarChartDataSet({ - isMonth = false, - placeholderColor, - borderColor, -}: { isMonth?: boolean } & TChartColor) { - let lastYearListCopy = lastYearList.concat([]); - let thisYearListCopy = lastYearList.concat([]); - - if (isMonth) { - lastYearListCopy = lastYearListCopy.reverse(); - thisYearListCopy = thisYearListCopy.reverse(); - } - - return { - color: chartListColor(), - tooltip: { - trigger: 'item', - }, - grid: { - top: '10px', - left: '0', - right: '0', - bottom: '36px', - containLabel: true, - }, - xAxis: [ - { - type: 'category', - data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'], - axisTick: { - alignWithLabel: true, - }, - axisLabel: { - color: placeholderColor, - }, - axisLine: { - lineStyle: { - color: borderColor, - width: 1, - }, - }, - }, - ], - yAxis: [ - { - type: 'value', - axisLabel: { - color: placeholderColor, - }, - splitLine: { - lineStyle: { - color: borderColor, - }, - }, - }, - ], - legend: { - data: ['去年', '今年'], - bottom: '0', - icon: 'rect', - itemGap: 48, - itemHeight: 4, - itemWidth: 12, - textStyle: { - fontSize: 12, - color: placeholderColor, - }, - }, - series: [ - { - name: '去年', - type: 'bar', - barWidth: '30%', - data: lastYearListCopy, - itemStyle: { - color: '#BCC4D0', - }, - }, - { - name: '今年', - type: 'bar', - barWidth: '30%', - data: thisYearListCopy, - itemStyle: { - color: (params: { value: number }) => { - if (params.value >= 200) { - return chartListColor()[1]; - } - return chartListColor()[0]; - }, - }, - }, - ], - }; -} /** * 获取饼图数据 * @@ -1079,7 +323,7 @@ export function getPieChartDataSet({ containerColor, }: { radius?: number } & Record) { return { - color: chartListColor(), + color: getChartListColor(), tooltip: { show: false, trigger: 'axis', @@ -1165,29 +409,3 @@ export function getPieChartDataSet({ ], }; } - -/** - * 更改图表主题颜色 - * - * @export - * @param {Array} chartsList - * @param {string} theme - */ -export function changeChartsTheme(chartsList: echarts.EChartsType[]) { - if (chartsList && chartsList.length) { - const chartChangeColor = chartListColor(); - - for (let index = 0; index < chartsList.length; index++) { - const elementChart = chartsList[index]; - - if (elementChart) { - const optionVal = elementChart.getOption(); - - // 更改主题颜色 - optionVal.color = chartChangeColor; - - elementChart.setOption(optionVal, true); - } - } - } -} diff --git a/src/pages/dashboard/base/index.vue b/src/pages/dashboard/base/index.vue index 7f87ac2..59a8848 100644 --- a/src/pages/dashboard/base/index.vue +++ b/src/pages/dashboard/base/index.vue @@ -218,17 +218,12 @@ import { PieChart, LineChart, BarChart } from 'echarts/charts'; import { CanvasRenderer } from 'echarts/renderers'; import { useSettingStore } from '@/store'; import { LAST_7_DAYS } from '@/utils/date'; +import { changeChartsTheme } from '@/utils/color'; // 导入样式 import Trend from '@/components/trend/index.vue'; import Card from '@/components/card/index.vue'; -import { - changeChartsTheme, - constructInitDataset, - getPieChartDataSet, - getLineChartDataSet, - constructInitDashboardDataset, -} from './index'; +import { constructInitDataset, getPieChartDataSet, getLineChartDataSet, constructInitDashboardDataset } from './index'; import { PANE_LIST, SALE_TEND_LIST, BUY_TEND_LIST, SALE_COLUMNS, BUY_COLUMNS } from './constants'; diff --git a/src/pages/dashboard/detail/index.ts b/src/pages/dashboard/detail/index.ts new file mode 100644 index 0000000..4a388f0 --- /dev/null +++ b/src/pages/dashboard/detail/index.ts @@ -0,0 +1,268 @@ +import dayjs from 'dayjs'; +import { TChartColor } from '@/config/color'; +import { getChartListColor } from '@/utils/color'; +import { getRandomArray, getDateArray } from '@/utils/charts'; + +/** + * 散点图数据 + * + * @export + * @returns {} + */ +export function getScatterDataSet({ + dateTime = [], + placeholderColor, + borderColor, +}: { dateTime?: Array } & TChartColor) { + const divideNum = 40; + const timeArray = []; + const inArray = []; + const outArray = []; + for (let i = 0; i < divideNum; i++) { + // const [timeArray, inArray, outArray] = dataset; + if (dateTime.length > 0) { + const dateAbsTime: number = (new Date(dateTime[1]).getTime() - new Date(dateTime[0]).getTime()) / divideNum; + const endTime: number = new Date(dateTime[0]).getTime() + dateAbsTime * i; + timeArray.push(dayjs(endTime).format('MM-DD')); + } else { + timeArray.push( + dayjs() + .subtract(divideNum - i, 'day') + .format('MM-DD'), + ); + } + + inArray.push(getRandomArray().toString()); + outArray.push(getRandomArray().toString()); + } + + return { + color: getChartListColor(), + xAxis: { + data: timeArray, + axisLabel: { + color: placeholderColor, + }, + splitLine: { show: false }, + axisLine: { + lineStyle: { + color: borderColor, + width: 1, + }, + }, + }, + yAxis: { + type: 'value', + // splitLine: { show: false}, + axisLabel: { + color: placeholderColor, + }, + nameTextStyle: { + padding: [0, 0, 0, 60], + }, + axisTick: { + show: false, + axisLine: { + show: false, + }, + }, + axisLine: { + show: false, + }, + splitLine: { + lineStyle: { + color: borderColor, + }, + }, + }, + tooltip: { + trigger: 'item', + }, + grid: { + top: '5px', + left: '25px', + right: '5px', + bottom: '60px', + }, + legend: { + left: 'center', + bottom: '0', + orient: 'horizontal', // legend 横向布局。 + data: ['按摩仪', '咖啡机'], + itemHeight: 8, + itemWidth: 8, + textStyle: { + fontSize: 12, + color: placeholderColor, + }, + }, + series: [ + { + name: '按摩仪', + symbolSize: 10, + data: outArray.reverse(), + type: 'scatter', + }, + { + name: '咖啡机', + symbolSize: 10, + data: inArray.concat(inArray.reverse()), + type: 'scatter', + }, + ], + }; +} + +/** 折线图数据 */ +export function getFolderLineDataSet({ + dateTime = [], + placeholderColor, + borderColor, +}: { dateTime?: Array } & TChartColor) { + let dateArray: Array = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']; + if (dateTime.length > 0) { + const divideNum = 7; + dateArray = getDateArray(dateTime, divideNum); + } + return { + color: getChartListColor(), + grid: { + top: '5%', + right: '10px', + left: '30px', + bottom: '60px', + }, + legend: { + left: 'center', + bottom: '0', + orient: 'horizontal', // legend 横向布局。 + data: ['杯子', '茶叶', '蜂蜜', '面粉'], + textStyle: { + fontSize: 12, + color: placeholderColor, + }, + }, + xAxis: { + type: 'category', + data: dateArray, + boundaryGap: false, + axisLabel: { + color: placeholderColor, + }, + axisLine: { + lineStyle: { + color: borderColor, + width: 1, + }, + }, + }, + yAxis: { + type: 'value', + axisLabel: { + color: placeholderColor, + }, + splitLine: { + lineStyle: { + color: borderColor, + }, + }, + }, + tooltip: { + trigger: 'item', + }, + series: [ + { + showSymbol: true, + symbol: 'circle', + symbolSize: 8, + name: '杯子', + stack: '总量', + data: [ + getRandomArray(), + getRandomArray(), + getRandomArray(), + getRandomArray(), + getRandomArray(), + getRandomArray(), + getRandomArray(), + ], + type: 'line', + itemStyle: { + normal: { + borderColor, + borderWidth: 1, + }, + }, + }, + { + showSymbol: true, + symbol: 'circle', + symbolSize: 8, + name: '茶叶', + stack: '总量', + data: [ + getRandomArray(), + getRandomArray(), + getRandomArray(), + getRandomArray(), + getRandomArray(), + getRandomArray(), + getRandomArray(), + ], + type: 'line', + itemStyle: { + normal: { + borderColor, + borderWidth: 1, + }, + }, + }, + { + showSymbol: true, + symbol: 'circle', + symbolSize: 8, + name: '蜂蜜', + stack: '总量', + data: [ + getRandomArray(), + getRandomArray(), + getRandomArray(), + getRandomArray(), + getRandomArray(), + getRandomArray(), + getRandomArray(), + ], + type: 'line', + itemStyle: { + normal: { + borderColor, + borderWidth: 1, + }, + }, + }, + { + showSymbol: true, + symbol: 'circle', + symbolSize: 8, + name: '面粉', + stack: '总量', + data: [ + getRandomArray(), + getRandomArray(), + getRandomArray(), + getRandomArray(), + getRandomArray(), + getRandomArray(), + getRandomArray(), + ], + type: 'line', + itemStyle: { + normal: { + borderColor, + borderWidth: 1, + }, + }, + }, + ], + }; +} diff --git a/src/pages/dashboard/detail/index.vue b/src/pages/dashboard/detail/index.vue index 7dd6e20..7d7e1db 100644 --- a/src/pages/dashboard/detail/index.vue +++ b/src/pages/dashboard/detail/index.vue @@ -73,10 +73,11 @@ import { LineChart, ScatterChart } from 'echarts/charts'; import { CanvasRenderer } from 'echarts/renderers'; import ProductCard from '@/components/card/Card.vue'; -import { changeChartsTheme, getFolderLineDataSet, getScatterDataSet } from '../base/index'; +import { getFolderLineDataSet, getScatterDataSet } from './index'; import { PANE_LIST_DATA, PRODUCT_LIST } from './constants'; import { LAST_7_DAYS } from '@/utils/date'; import { useSettingStore } from '@/store'; +import { changeChartsTheme } from '@/utils/color'; import Trend from '@/components/trend/index.vue'; import Card from '@/components/card/index.vue'; diff --git a/src/pages/detail/deploy/index.ts b/src/pages/detail/deploy/index.ts new file mode 100644 index 0000000..21680c9 --- /dev/null +++ b/src/pages/detail/deploy/index.ts @@ -0,0 +1,215 @@ +import { TChartColor } from '@/config/color'; +import { getChartListColor } from '@/utils/color'; +import { getRandomArray, getDateArray } from '@/utils/charts'; + +/** 平滑图数据 */ +export function getSmoothLineDataSet({ + dateTime = [], + placeholderColor, + borderColor, +}: { dateTime?: Array } & TChartColor) { + let dateArray: Array = ['00:00', '02:00', '04:00', '06:00']; + if (dateTime.length > 0) { + const divideNum = 7; + dateArray = getDateArray(dateTime, divideNum); + } + + return { + color: getChartListColor(), + tooltip: { + trigger: 'item', + }, + grid: { + top: '10px', + left: '0', + right: '20px', + bottom: '36px', + containLabel: true, + }, + xAxis: { + type: 'category', + data: dateArray, + boundaryGap: false, + axisLabel: { + color: placeholderColor, + }, + axisLine: { + lineStyle: { + color: borderColor, + width: 1, + }, + }, + }, + yAxis: { + type: 'value', + axisLabel: { + color: placeholderColor, + }, + splitLine: { + lineStyle: { + color: borderColor, + }, + }, + }, + legend: { + data: ['本月', '上月'], + icon: 'circle', + bottom: '0', + itemGap: 48, + itemHeight: 8, + itemWidth: 8, + textStyle: { + fontSize: 12, + color: placeholderColor, + }, + }, + series: [ + { + name: '上月', + data: [ + getRandomArray(), + getRandomArray(), + getRandomArray(), + getRandomArray(), + getRandomArray(), + getRandomArray(), + getRandomArray(), + ], + type: 'line', + smooth: true, + color: getChartListColor()[0], + showSymbol: true, + symbol: 'circle', + symbolSize: 8, + areaStyle: { + normal: { + opacity: 0.1, + }, + }, + }, + { + name: '本月', + data: [ + getRandomArray(), + getRandomArray(), + getRandomArray(), + getRandomArray(), + getRandomArray(), + getRandomArray(), + getRandomArray(), + ], + type: 'line', + smooth: true, + showSymbol: true, + symbol: 'circle', + symbolSize: 8, + color: getChartListColor()[1], + }, + ], + }; +} + +export const lastYearList: Array = [100, 120, 140, 160, 180, 200, 210]; + +/** + * 柱状图数据结构 + * + * @export + * @param {boolean} [isMonth=false] + * @returns {*} + */ +export function get2ColBarChartDataSet({ + isMonth = false, + placeholderColor, + borderColor, +}: { isMonth?: boolean } & TChartColor) { + let lastYearListCopy = lastYearList.concat([]); + let thisYearListCopy = lastYearList.concat([]); + + if (isMonth) { + lastYearListCopy = lastYearListCopy.reverse(); + thisYearListCopy = thisYearListCopy.reverse(); + } + + return { + color: getChartListColor(), + tooltip: { + trigger: 'item', + }, + grid: { + top: '10px', + left: '0', + right: '0', + bottom: '36px', + containLabel: true, + }, + xAxis: [ + { + type: 'category', + data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'], + axisTick: { + alignWithLabel: true, + }, + axisLabel: { + color: placeholderColor, + }, + axisLine: { + lineStyle: { + color: borderColor, + width: 1, + }, + }, + }, + ], + yAxis: [ + { + type: 'value', + axisLabel: { + color: placeholderColor, + }, + splitLine: { + lineStyle: { + color: borderColor, + }, + }, + }, + ], + legend: { + data: ['去年', '今年'], + bottom: '0', + icon: 'rect', + itemGap: 48, + itemHeight: 4, + itemWidth: 12, + textStyle: { + fontSize: 12, + color: placeholderColor, + }, + }, + series: [ + { + name: '去年', + type: 'bar', + barWidth: '30%', + data: lastYearListCopy, + itemStyle: { + color: '#BCC4D0', + }, + }, + { + name: '今年', + type: 'bar', + barWidth: '30%', + data: thisYearListCopy, + itemStyle: { + color: (params: { value: number }) => { + if (params.value >= 200) { + return getChartListColor()[1]; + } + return getChartListColor()[0]; + }, + }, + }, + ], + }; +} diff --git a/src/pages/detail/deploy/index.vue b/src/pages/detail/deploy/index.vue index 9397c43..ad71ac2 100644 --- a/src/pages/detail/deploy/index.vue +++ b/src/pages/detail/deploy/index.vue @@ -84,8 +84,9 @@ import { BarChart, LineChart } from 'echarts/charts'; import { CanvasRenderer } from 'echarts/renderers'; import { useSettingStore } from '@/store'; -import { changeChartsTheme, getSmoothLineDataSet, get2ColBarChartDataSet } from '../../dashboard/base/index'; +import { getSmoothLineDataSet, get2ColBarChartDataSet } from './index'; import { BASE_INFO_DATA, TABLE_COLUMNS as columns } from './constants'; +import { changeChartsTheme } from '@/utils/color'; import { prefix } from '@/config/global'; import Card from '@/components/card/index.vue'; diff --git a/src/pages/user/index.ts b/src/pages/user/index.ts new file mode 100644 index 0000000..73edef3 --- /dev/null +++ b/src/pages/user/index.ts @@ -0,0 +1,157 @@ +import { TChartColor } from '@/config/color'; +import { getChartListColor } from '@/utils/color'; +import { getRandomArray, getDateArray } from '@/utils/charts'; + +/** 折线图数据 */ +export function getFolderLineDataSet({ + dateTime = [], + placeholderColor, + borderColor, +}: { dateTime?: Array } & TChartColor) { + let dateArray: Array = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']; + if (dateTime.length > 0) { + const divideNum = 7; + dateArray = getDateArray(dateTime, divideNum); + } + return { + color: getChartListColor(), + grid: { + top: '5%', + right: '10px', + left: '30px', + bottom: '60px', + }, + legend: { + left: 'center', + bottom: '0', + orient: 'horizontal', // legend 横向布局。 + data: ['杯子', '茶叶', '蜂蜜', '面粉'], + textStyle: { + fontSize: 12, + color: placeholderColor, + }, + }, + xAxis: { + type: 'category', + data: dateArray, + boundaryGap: false, + axisLabel: { + color: placeholderColor, + }, + axisLine: { + lineStyle: { + color: borderColor, + width: 1, + }, + }, + }, + yAxis: { + type: 'value', + axisLabel: { + color: placeholderColor, + }, + splitLine: { + lineStyle: { + color: borderColor, + }, + }, + }, + tooltip: { + trigger: 'item', + }, + series: [ + { + showSymbol: true, + symbol: 'circle', + symbolSize: 8, + name: '杯子', + stack: '总量', + data: [ + getRandomArray(), + getRandomArray(), + getRandomArray(), + getRandomArray(), + getRandomArray(), + getRandomArray(), + getRandomArray(), + ], + type: 'line', + itemStyle: { + normal: { + borderColor, + borderWidth: 1, + }, + }, + }, + { + showSymbol: true, + symbol: 'circle', + symbolSize: 8, + name: '茶叶', + stack: '总量', + data: [ + getRandomArray(), + getRandomArray(), + getRandomArray(), + getRandomArray(), + getRandomArray(), + getRandomArray(), + getRandomArray(), + ], + type: 'line', + itemStyle: { + normal: { + borderColor, + borderWidth: 1, + }, + }, + }, + { + showSymbol: true, + symbol: 'circle', + symbolSize: 8, + name: '蜂蜜', + stack: '总量', + data: [ + getRandomArray(), + getRandomArray(), + getRandomArray(), + getRandomArray(), + getRandomArray(), + getRandomArray(), + getRandomArray(), + ], + type: 'line', + itemStyle: { + normal: { + borderColor, + borderWidth: 1, + }, + }, + }, + { + showSymbol: true, + symbol: 'circle', + symbolSize: 8, + name: '面粉', + stack: '总量', + data: [ + getRandomArray(), + getRandomArray(), + getRandomArray(), + getRandomArray(), + getRandomArray(), + getRandomArray(), + getRandomArray(), + ], + type: 'line', + itemStyle: { + normal: { + borderColor, + borderWidth: 1, + }, + }, + }, + ], + }; +} diff --git a/src/pages/user/index.vue b/src/pages/user/index.vue index 4de4b05..b70d6fe 100644 --- a/src/pages/user/index.vue +++ b/src/pages/user/index.vue @@ -104,11 +104,12 @@ import { useSettingStore } from '@/store'; import { LAST_7_DAYS } from '@/utils/date'; import { USER_INFO_LIST, TEAM_MEMBERS, PRODUCT_LIST } from './constants'; -import { changeChartsTheme, getFolderLineDataSet } from '@/pages/dashboard/base/index'; +import { getFolderLineDataSet } from './index'; import ProductAIcon from '@/assets/assets-product-1.svg'; import ProductBIcon from '@/assets/assets-product-2.svg'; import ProductCIcon from '@/assets/assets-product-3.svg'; import ProductDIcon from '@/assets/assets-product-4.svg'; +import { changeChartsTheme } from '@/utils/color'; import Card from '@/components/card/index.vue'; diff --git a/src/utils/charts.ts b/src/utils/charts.ts new file mode 100644 index 0000000..b28162d --- /dev/null +++ b/src/utils/charts.ts @@ -0,0 +1,40 @@ +import dayjs from 'dayjs'; + +/** + * 获取表头数据 + * + * @export + * @param {string[]} dateTime + * @param {number} divideNum + * @returns {string[]} + */ +export function getDateArray(dateTime: string[] = [], divideNum = 10): string[] { + const timeArray: string[] = []; + if (dateTime.length > 0) { + for (let i = 0; i < divideNum; i++) { + const dateAbsTime: number = (new Date(dateTime[1]).getTime() - new Date(dateTime[0]).getTime()) / divideNum; + const enhandTime: number = new Date(dateTime[0]).getTime() + dateAbsTime * i; + timeArray.push(dayjs(enhandTime).format('YYYY-MM-DD')); + } + } + + return timeArray; +} + +/** + * 获取随机数 + * + * @param {number} [num=100] + * @returns + * + * @memberOf DashboardBase + */ +export function getRandomArray(num = 100) { + let resultNum = Number((Math.random() * num).toFixed(0)); + + if (resultNum <= 1) { + resultNum = 1; + } + + return resultNum; +} diff --git a/src/utils/color.ts b/src/utils/color.ts new file mode 100644 index 0000000..d01625b --- /dev/null +++ b/src/utils/color.ts @@ -0,0 +1,72 @@ +import { Color } from 'tvision-color'; +import * as echarts from 'echarts/core'; +import { getBrandColor, defaultLightColor, defaultDarkColor } from '@/config/color'; +import { getSettingStore } from '@/store'; + +/** + * 依据主题类型获取颜色 + * + * @export + * @param {string} theme + * @returns {} + */ +export function getColorFromTheme(theme: string) { + const settingStore = getSettingStore(); + const { colorList, mode } = settingStore; + const isDarkMode = mode === 'dark'; + let themeColorList = []; + const themeColor = getBrandColor(theme, colorList); + + if (!/^#[A-F\d]{6}$/i.test(theme)) { + theme = themeColor?.['@brand-color'] || '#0052D9'; + const themIdx = defaultLightColor.indexOf(theme.toLocaleLowerCase()); + const defaultGradients = !isDarkMode ? defaultLightColor : defaultDarkColor; + + const spliceThemeList = defaultGradients.slice(0, themIdx); + themeColorList = defaultGradients.slice(themIdx, defaultGradients.length).concat(spliceThemeList); + } else { + theme = themeColor?.['@brand-color']; + themeColorList = Color.getRandomPalette({ + color: theme, + colorGamut: 'bright', + number: 8, + }); + } + + return themeColorList; +} + +/** 图表颜色 */ +export function getChartListColor(): Array { + const settingStore = getSettingStore(); + const { brandTheme } = settingStore; + const res = getColorFromTheme(brandTheme); + + return res; +} + +/** + * 更改图表主题颜色 + * + * @export + * @param {Array} chartsList + * @param {string} theme + */ +export function changeChartsTheme(chartsList: echarts.EChartsType[]) { + if (chartsList && chartsList.length) { + const chartChangeColor = getChartListColor(); + + for (let index = 0; index < chartsList.length; index++) { + const elementChart = chartsList[index]; + + if (elementChart) { + const optionVal = elementChart.getOption(); + + // 更改主题颜色 + optionVal.color = chartChangeColor; + + elementChart.setOption(optionVal, true); + } + } + } +}