308 lines
7.4 KiB
Vue
308 lines
7.4 KiB
Vue
<template>
|
|
<div>
|
|
<el-card class="box-card">
|
|
<div class="drag-block">
|
|
<draggable
|
|
class="list-group"
|
|
:list="dragOptions"
|
|
itemKey="id"
|
|
group="people"
|
|
@start="startDrag"
|
|
@change="changeChartItem"
|
|
>
|
|
<template #item="{element}">
|
|
<el-card shadow="hover" class="cards">
|
|
<el-row justify="space-between">
|
|
<span>{{ element.label }}</span>
|
|
<span>{{ element.dataType }}</span>
|
|
</el-row>
|
|
</el-card>
|
|
</template>
|
|
</draggable>
|
|
</div>
|
|
</el-card>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import draggable from 'vuedraggable'
|
|
import {ElMessage} from "element-plus";
|
|
|
|
const emit = defineEmits(["editValueFlag", "editStartDataType"])
|
|
const props = defineProps({
|
|
//可供拖动的选项列表
|
|
dragOptions: {
|
|
type: Array,
|
|
default: []
|
|
},
|
|
//echarts的配置属性
|
|
chartOption: {
|
|
type: Object,
|
|
default: {}
|
|
},
|
|
//初始化加载echarts函数
|
|
initCharts: {
|
|
type: Function,
|
|
default: null
|
|
},
|
|
//用于X轴区域存放拖动的选项
|
|
xAxisList: {
|
|
type: Array,
|
|
default: []
|
|
},
|
|
//用于Y轴区域存放拖动的选项
|
|
yAxisList: {
|
|
type: Array,
|
|
default: []
|
|
},
|
|
//当前echarts图形
|
|
currentChart: {
|
|
type: String,
|
|
default: 'line'
|
|
},
|
|
//雷达图指示器
|
|
radarIndicator: {
|
|
type: Array,
|
|
default: []
|
|
}
|
|
})
|
|
//简化代码
|
|
let xList = reactive(props.xAxisList)
|
|
let yList = reactive(props.yAxisList)
|
|
let option = reactive(props.chartOption)
|
|
let chart = reactive(props.currentChart)
|
|
//获取正在拖动选项的数据类型
|
|
const startDragType = ref()
|
|
//标记正在拖动选项的数据类型是否value
|
|
const flag = ref(false)
|
|
//将改变的数据传到父组件
|
|
watch(() => flag.value, (newVal) => {
|
|
emit("editValueFlag", newVal)
|
|
})
|
|
watch(() => props.currentChart, (newVal) => {
|
|
chart = newVal
|
|
})
|
|
watch(() => startDragType.value, (newVal) => {
|
|
emit("editStartDataType", newVal)
|
|
})
|
|
|
|
/**
|
|
* 设置修改后的echarts属性
|
|
* @param item 拖动的项
|
|
* @param label 拖拽选项的名称
|
|
* @returns Object
|
|
*/
|
|
const settingChartItem = (item, label) => {
|
|
if (chart === 'line') {
|
|
return {
|
|
id: item.id,//组件 ID
|
|
name: label,
|
|
// type: echartsValue.value ? echartsValue.value : item.type,
|
|
type: chart,
|
|
data: item.data,
|
|
smooth: true,
|
|
color: item.color,
|
|
symbol: item.symbol,
|
|
symbolSize: item.symbolSize,
|
|
showSymbol: item.showSymbol,
|
|
lineStyle: item.lineStyle,
|
|
// emphasis: item.emphasis
|
|
}
|
|
} else if (chart === 'bar') {
|
|
return {
|
|
id: item.id,
|
|
name: label,
|
|
type: chart,
|
|
data: item.data,
|
|
color: item.color,
|
|
showBackground: item.showBackground,
|
|
backgroundStyle: item.backgroundStyle
|
|
}
|
|
}
|
|
}
|
|
/**
|
|
* 封拖拽数据类型为value
|
|
* @param item 拖动的项
|
|
* @param label 拖拽选项的名称
|
|
* @param selectedObj 图例选中状态表
|
|
*/
|
|
const dragValue = (item, label, selectedObj) => {
|
|
dragChart(item, label, 2)
|
|
option.legend.data.push(label)
|
|
let chartItem = settingChartItem(item, label)
|
|
option.series.push(chartItem)
|
|
for (const propertyName in selectedObj) {
|
|
if (propertyName === label) {
|
|
selectedObj[propertyName] = true
|
|
}
|
|
}
|
|
}
|
|
/**
|
|
* 封装切换坐标轴数据类型为Category
|
|
* @param item 拖动的项
|
|
* @param label 坐标轴名称
|
|
* @param type 切换x/y轴
|
|
*/
|
|
const changeTypeToCategory = (item, label, type) => {
|
|
let axis
|
|
if (type === 'xAxis') {
|
|
axis = option.xAxis
|
|
} else {
|
|
axis = option.yAxis
|
|
}
|
|
axis.type = 'category'
|
|
axis.name = item.unit
|
|
axis.data = item.data
|
|
}
|
|
/**
|
|
* 封装切换坐标轴数据类型为Value
|
|
* @param item 拖动的项item
|
|
* @param type 切换x/y轴
|
|
*/
|
|
const changeTypeToValue = (item, type) => {
|
|
let axis
|
|
if (type === 'xAxis') {
|
|
axis = option.xAxis
|
|
} else {
|
|
axis = option.yAxis
|
|
}
|
|
axis.type = 'value'
|
|
axis.name = item.unit
|
|
}
|
|
/**
|
|
* 封装拖拽选项修改echarts属性
|
|
* @param item 拖动的项
|
|
* @param label 拖拽选项的名称
|
|
* @param index 区分拖的选项数据:1是key,2是value
|
|
*/
|
|
const dragChart = (item, label, index) => {
|
|
if (xList.length !== 0 && yList.length === 0) {
|
|
// console.log('x轴有值')
|
|
if (index === 1) {
|
|
changeTypeToCategory(item, label, 'xAxis')
|
|
} else {
|
|
changeTypeToValue(item, 'xAxis')
|
|
option.yAxis.type = 'category'
|
|
}
|
|
} else if (xList.length !== 0 && yList.length !== 0) {
|
|
// console.log('xy有值')
|
|
if (xList[0].dataType === 'value') {
|
|
if (index === 1) {
|
|
changeTypeToCategory(item, label)
|
|
}
|
|
changeTypeToValue(item, 'xAxis')
|
|
} else if (yList[0].dataType === 'value') {
|
|
if (index === 1) {
|
|
changeTypeToCategory(item, label, 'xAxis')
|
|
}
|
|
changeTypeToValue(item)
|
|
}
|
|
} else if (xList.length === 0 && yList.length !== 0) {
|
|
// console.log('y轴有值')
|
|
if (index === 1) {
|
|
changeTypeToCategory(item, label, 'yAxis')
|
|
} else {
|
|
option.xAxis.type = 'category'
|
|
changeTypeToValue(item)
|
|
}
|
|
}
|
|
}
|
|
/**
|
|
* 从左侧区域移动选项到右侧
|
|
* @param event 拖拽成功event事件
|
|
*/
|
|
const changeChartItem = (event) => {
|
|
if (event.removed === undefined) return;
|
|
let item = event.removed.element
|
|
if (chart === 'line'||chart === 'bar') {
|
|
let label = item.label
|
|
let selectedObj = option.legend.selected
|
|
if (item.dataType === "key") {
|
|
dragChart(item, label, 1)
|
|
} else {
|
|
if (flag.value) return;
|
|
dragValue(item, label, selectedObj)
|
|
}
|
|
} else if (chart === 'pie') {
|
|
let arr = []
|
|
xList.forEach(item => {
|
|
let obj = {
|
|
name: item.label,
|
|
value: item.value
|
|
}
|
|
arr.push(obj)
|
|
})
|
|
for (const propertyName in option.legend.selected) {
|
|
if (propertyName === item.label) {
|
|
option.legend.selected[propertyName] = true
|
|
}
|
|
}
|
|
if (item.dataType !== "key") {
|
|
option.legend.data.push(item.label)
|
|
}
|
|
option.series = [
|
|
{
|
|
type: 'pie',
|
|
radius: '50%',
|
|
data: arr
|
|
}
|
|
]
|
|
} else if (chart === 'radar') {
|
|
let arr = []
|
|
xList.forEach(item => {
|
|
let obj = {
|
|
name: item.label,
|
|
value: item.data
|
|
}
|
|
arr.push(obj)
|
|
})
|
|
// console.log('arr',arr)
|
|
for (const propertyName in option.legend.selected) {
|
|
if (propertyName === item.label) {
|
|
option.legend.selected[propertyName] = true
|
|
}
|
|
}
|
|
if (item.dataType !== "key") {
|
|
option.legend.data.push(item.label)
|
|
}
|
|
option.radar={
|
|
indicator:props.radarIndicator
|
|
}
|
|
option.series = [
|
|
{
|
|
type: 'radar',
|
|
data: arr
|
|
}
|
|
]
|
|
}
|
|
props.initCharts()
|
|
}
|
|
|
|
/**
|
|
* 左侧区域开始拖拽事件
|
|
* @param event 开始拖拽的event事件
|
|
*/
|
|
const startDrag = (event) => {
|
|
startDragType.value = event.item._underlying_vm_.dataType
|
|
if (xList.length === 0 && yList.length === 0) {
|
|
if (chart === 'line' || chart === 'bar') {
|
|
if (startDragType.value === "value") {
|
|
flag.value = true
|
|
ElMessage({
|
|
message: '请先拖动数据类型为key的选项到x轴/y轴.',
|
|
type: 'warning',
|
|
})
|
|
} else {
|
|
flag.value = false
|
|
}
|
|
} else if (chart === 'pie') {
|
|
// console.log('拖动饼图')
|
|
flag.value = false
|
|
}else if (chart === 'radar') {
|
|
// console.log('拖动雷达')
|
|
flag.value = false
|
|
}
|
|
}
|
|
}
|
|
</script>
|