mirror of
https://gitee.com/dromara/go-view.git
synced 2026-04-29 17:28:12 +08:00
feat: add 新增自定义排行榜组件RankChart
This commit is contained in:
parent
7b565a5ad6
commit
13154d2c87
BIN
src/assets/images/chart/charts/rank-chart.png
Normal file
BIN
src/assets/images/chart/charts/rank-chart.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 142 KiB |
BIN
src/assets/images/chart/informations/richeng.png
Normal file
BIN
src/assets/images/chart/informations/richeng.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
196
src/packages/components/Charts/Bars/RankChart/config.ts
Normal file
196
src/packages/components/Charts/Bars/RankChart/config.ts
Normal file
@ -0,0 +1,196 @@
|
||||
import { echartOptionProfixHandle, PublicConfigClass } from '@/packages/public'
|
||||
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
import { RankChartConfig } from './index'
|
||||
// 深拷贝
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
// 默认数据
|
||||
import dataJson from './data.json'
|
||||
|
||||
export const includes = ['legend', 'xAxis', 'grid']
|
||||
|
||||
const barName = "检测任务数";
|
||||
export const seriesItem = {
|
||||
name: barName,
|
||||
type: "bar",
|
||||
barWidth: 10, // 柱子宽度
|
||||
MaxSize: 0,
|
||||
showBackground: true,
|
||||
backgroundStyle: {
|
||||
color: "#fff",
|
||||
borderRadius: 5, //设置背景的圆角
|
||||
},
|
||||
color: {
|
||||
type: "linear",
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 1,
|
||||
y2: 0,
|
||||
colorStops: [
|
||||
{
|
||||
offset: 1,
|
||||
color: "#036afaff", // 0% 处的颜色
|
||||
},
|
||||
{
|
||||
offset: 0.5,
|
||||
color: "#034299ff"
|
||||
},
|
||||
{
|
||||
offset: 0,
|
||||
color: "#01142eff", // 100% 处的颜色
|
||||
},
|
||||
],
|
||||
global: false, // 缺省为 false
|
||||
},
|
||||
label: {
|
||||
show: true,
|
||||
offset: [10, -15], // 标签偏移量
|
||||
color: "#050505f6",
|
||||
fontSize: 15,
|
||||
fontWeight: 500,
|
||||
position: "left",
|
||||
align: "left",
|
||||
formatter: function (params:any) {
|
||||
// console.log(params);
|
||||
return params.data.name;
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const rankIcons = {
|
||||
icon1: "https://goviewpro.goviewlink.com/cloudStorageStatic/13190/rank1.png",
|
||||
icon2: "https://goviewpro.goviewlink.com/cloudStorageStatic/13190/rank2.png",
|
||||
icon3: "https://goviewpro.goviewlink.com/cloudStorageStatic/13190/rank3.png",
|
||||
icon: "https://goviewpro.goviewlink.com/cloudStorageStatic/13190/rank.png",
|
||||
};
|
||||
|
||||
export const option = {
|
||||
backgroundColor: "transparent",
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
axisPointer: {
|
||||
type: "shadow",
|
||||
},
|
||||
},
|
||||
grid: {
|
||||
left: "5%",
|
||||
right: "5%",
|
||||
top: "5%",
|
||||
bottom: "5%",
|
||||
containLabel: true,
|
||||
},
|
||||
xAxis: {
|
||||
type: "value",
|
||||
show: false,
|
||||
},
|
||||
yAxis: [
|
||||
{
|
||||
type: "category",
|
||||
splitLine: {
|
||||
show: false,
|
||||
},
|
||||
axisLine: {
|
||||
show: false,
|
||||
},
|
||||
axisTick: {
|
||||
show: false,
|
||||
},
|
||||
inverse: true,
|
||||
axisLabel: {
|
||||
color: "#333",
|
||||
fontSize: 16,
|
||||
margin: 10,
|
||||
formatter: (name: any, index: number) => {
|
||||
const id = index + 1;
|
||||
if (id == 1) {
|
||||
return `{rank1|${id}}`;
|
||||
} else if (id == 2) {
|
||||
return `{rank2|${id}}`;
|
||||
} else if (id == 3) {
|
||||
return `{rank3|${id}}`;
|
||||
} else {
|
||||
return `{rank|${id}}`;
|
||||
}
|
||||
},
|
||||
rich: {
|
||||
rank1: {
|
||||
width: 25,
|
||||
height: 25,
|
||||
lineHeight: 25,
|
||||
fontSize: 16,
|
||||
align: "center",
|
||||
color: "#ffffff",
|
||||
padding: [0, 10, 0, 0],
|
||||
backgroundColor: {
|
||||
image: rankIcons.icon1,
|
||||
},
|
||||
},
|
||||
rank2: {
|
||||
width: 25,
|
||||
height: 25,
|
||||
lineHeight: 25,
|
||||
fontSize: 16,
|
||||
align: "center",
|
||||
color: "#ffffff",
|
||||
padding: [0, 10, 0, 0],
|
||||
backgroundColor: {
|
||||
image: rankIcons.icon2,
|
||||
},
|
||||
},
|
||||
rank3: {
|
||||
width: 25,
|
||||
height: 25,
|
||||
lineHeight: 25,
|
||||
fontSize: 16,
|
||||
align: "center",
|
||||
color: "#ffffff",
|
||||
padding: [0, 10, 0, 0],
|
||||
backgroundColor: {
|
||||
image: rankIcons.icon3,
|
||||
},
|
||||
},
|
||||
rank: {
|
||||
width: 25,
|
||||
height: 25,
|
||||
lineHeight: 25,
|
||||
fontSize: 16,
|
||||
align: "center",
|
||||
color: "#ffffff",
|
||||
padding: [0, 10, 0, 0],
|
||||
backgroundColor: {
|
||||
image: rankIcons.icon,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "category",
|
||||
inverse: true,
|
||||
axisTick: "none",
|
||||
axisLine: "none",
|
||||
show: true,
|
||||
axisLabel: {
|
||||
textStyle: {
|
||||
// color: "#000000fd",
|
||||
color: "#333", // 文字颜色
|
||||
fontSize: 16,
|
||||
},
|
||||
formatter: function (value: any) {
|
||||
return value + "个";
|
||||
},
|
||||
},
|
||||
data: dataJson.source.map((item) => item.value),
|
||||
},
|
||||
],
|
||||
|
||||
series: [ seriesItem ],
|
||||
dataset: { ...dataJson }, // 数据集
|
||||
}
|
||||
|
||||
export default class Config extends PublicConfigClass implements CreateComponentType {
|
||||
public key: string = RankChartConfig.key
|
||||
public chartConfig = cloneDeep(RankChartConfig)
|
||||
// 图表配置项
|
||||
public option = echartOptionProfixHandle(option, includes)
|
||||
}
|
||||
27
src/packages/components/Charts/Bars/RankChart/config.vue
Normal file
27
src/packages/components/Charts/Bars/RankChart/config.vue
Normal file
@ -0,0 +1,27 @@
|
||||
<template>
|
||||
<!-- 遍历 seriesList -->
|
||||
<global-setting :optionData="optionData" :in-chart="true"></global-setting>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType, computed } from 'vue'
|
||||
// 以下是封装的设置模块布局组件,具体效果可在官网查看
|
||||
import {
|
||||
GlobalSetting
|
||||
} from '@/components/Pages/ChartItemSetting'
|
||||
import { GlobalThemeJsonType } from '@/settings/chartThemes/index'
|
||||
|
||||
const props = defineProps({
|
||||
optionData: {
|
||||
type: Object as PropType<GlobalThemeJsonType>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
// 去除options中的yAxis配置,不允许前端控制该属性
|
||||
const optionData = computed(() => {
|
||||
const { yAxis, ...rest } = props.optionData
|
||||
return rest
|
||||
})
|
||||
|
||||
</script>
|
||||
48
src/packages/components/Charts/Bars/RankChart/data.json
Normal file
48
src/packages/components/Charts/Bars/RankChart/data.json
Normal file
@ -0,0 +1,48 @@
|
||||
{
|
||||
"dimensions": [
|
||||
"name",
|
||||
"value"
|
||||
],
|
||||
"source": [
|
||||
{
|
||||
"name": "蔡洲",
|
||||
"value": 691
|
||||
},
|
||||
{
|
||||
"name": "孙磊",
|
||||
"value": 544
|
||||
},
|
||||
{
|
||||
"name": "张伟",
|
||||
"value": 522
|
||||
},
|
||||
{
|
||||
"name": "王文峰",
|
||||
"value": 502
|
||||
},
|
||||
{
|
||||
"name": "李强",
|
||||
"value": 488
|
||||
},
|
||||
{
|
||||
"name": "刘敏涛",
|
||||
"value": 461
|
||||
},
|
||||
{
|
||||
"name": "杨其",
|
||||
"value": 395
|
||||
},
|
||||
{
|
||||
"name": "王若娥",
|
||||
"value": 389
|
||||
},
|
||||
{
|
||||
"name": "童天宇",
|
||||
"value": 335
|
||||
},
|
||||
{
|
||||
"name": "杨欧鹏",
|
||||
"value": 298
|
||||
}
|
||||
]
|
||||
}
|
||||
16
src/packages/components/Charts/Bars/RankChart/index.ts
Normal file
16
src/packages/components/Charts/Bars/RankChart/index.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
|
||||
import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
|
||||
|
||||
import image from '@/assets/images/chart/charts/rank-chart.png'
|
||||
|
||||
export const RankChartConfig: ConfigType = {
|
||||
key: 'RankChart',
|
||||
chartKey: 'VRankChart',
|
||||
conKey: 'VCRankChart',
|
||||
title: '排行榜',
|
||||
category: ChatCategoryEnum.BAR,
|
||||
categoryName: ChatCategoryEnumName.BAR,
|
||||
package: PackagesCategoryEnum.CHARTS,
|
||||
chartFrame: ChartFrameEnum.ECHARTS,
|
||||
image: image,
|
||||
}
|
||||
102
src/packages/components/Charts/Bars/RankChart/index.vue
Normal file
102
src/packages/components/Charts/Bars/RankChart/index.vue
Normal file
@ -0,0 +1,102 @@
|
||||
<template>
|
||||
<v-chart
|
||||
ref="vChartRef"
|
||||
:init-options="initOptions"
|
||||
:theme="themeColor"
|
||||
:option="option"
|
||||
:manual-update="isPreview()"
|
||||
autoresize
|
||||
></v-chart>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, nextTick, computed, watch, PropType } from 'vue'
|
||||
import VChart from 'vue-echarts'
|
||||
import { useCanvasInitOptions } from '@/hooks/useCanvasInitOptions.hook'
|
||||
import { use } from 'echarts/core'
|
||||
import { CanvasRenderer } from 'echarts/renderers'
|
||||
import { BarChart } from 'echarts/charts'
|
||||
import config, { includes, seriesItem } from './config'
|
||||
import { mergeTheme } from '@/packages/public/chart'
|
||||
import { useChartDataFetch } from '@/hooks'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
|
||||
import { isPreview } from '@/utils'
|
||||
import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent } from 'echarts/components'
|
||||
import isObject from 'lodash/isObject'
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
|
||||
// 这里的 themeSetting、themeColor的作用是监听全局样式主题并进行设置,chartConfig 为图表的配置项数据
|
||||
const props = defineProps({
|
||||
themeSetting: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
themeColor: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
chartConfig: {
|
||||
type: Object as PropType<config>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
const initOptions = useCanvasInitOptions(props.chartConfig.option, props.themeSetting)
|
||||
|
||||
// 动态注册 ECharts 图表内容
|
||||
use([DatasetComponent, CanvasRenderer, BarChart, GridComponent, TooltipComponent, LegendComponent])
|
||||
|
||||
const replaceMergeArr = ref<string[]>()
|
||||
|
||||
|
||||
|
||||
// 应用到图表的 option
|
||||
const option = computed(() => {
|
||||
return mergeTheme(props.chartConfig.option, props.themeSetting, includes)
|
||||
})
|
||||
|
||||
// dataset 无法变更条数的补丁
|
||||
|
||||
watch(
|
||||
() => props.chartConfig.option.dataset,
|
||||
(newData: { dimensions: any }, oldData) => {
|
||||
try {
|
||||
if (!isObject(newData) || !('dimensions' in newData)) return
|
||||
if (Array.isArray(newData?.dimensions)) {
|
||||
const seriesArr = []
|
||||
// 对oldData进行判断,防止传入错误数据之后对旧维度判断产生干扰
|
||||
// 此处计算的是dimensions的Y轴维度,若是dimensions.length为0或1,则默认为1,排除X轴维度干扰
|
||||
const oldDimensions = Array.isArray(oldData?.dimensions)&&oldData.dimensions.length >= 1 ? oldData.dimensions.length : 1;
|
||||
const newDimensions = newData.dimensions.length >= 1 ? newData.dimensions.length : 1;
|
||||
const dimensionsGap = newDimensions - oldDimensions;
|
||||
if (dimensionsGap < 0) {
|
||||
props.chartConfig.option.series.splice(newDimensions - 1)
|
||||
} else if (dimensionsGap > 0) {
|
||||
if(!oldData || !oldData?.dimensions || !Array.isArray(oldData?.dimensions) || !oldData?.dimensions.length ) {
|
||||
props.chartConfig.option.series=[]
|
||||
}
|
||||
for (let i = 0; i < dimensionsGap; i++) {
|
||||
seriesArr.push(cloneDeep(seriesItem))
|
||||
}
|
||||
props.chartConfig.option.series.push(...seriesArr)
|
||||
}
|
||||
replaceMergeArr.value = ['series']
|
||||
nextTick(() => {
|
||||
replaceMergeArr.value = []
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
{
|
||||
deep: false
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
|
||||
props.chartConfig.option.dataset = newData
|
||||
})
|
||||
</script>
|
||||
@ -2,5 +2,6 @@ import { BarCommonConfig } from './BarCommon/index'
|
||||
import { BarCrossrangeConfig } from './BarCrossrange/index'
|
||||
import { CapsuleChartConfig } from './CapsuleChart/index'
|
||||
import { BarLineConfig } from './BarLine/index'
|
||||
import { RankChartConfig } from './RankChart'
|
||||
|
||||
export default [BarCommonConfig, BarCrossrangeConfig, BarLineConfig, CapsuleChartConfig]
|
||||
export default [BarCommonConfig, BarCrossrangeConfig, BarLineConfig, CapsuleChartConfig, RankChartConfig]
|
||||
|
||||
@ -2,7 +2,8 @@ import { PublicConfigClass } from '@/packages/public'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
import { ImageConfig } from './index'
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
import logo from '@/assets/logo.png'
|
||||
// import logo from '@/assets/logo.png'
|
||||
import logo from '@/assets/images/chart/informations/richeng.png'
|
||||
|
||||
export const option = {
|
||||
// 图片路径
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user