init
This commit is contained in:
233
src/views/custom-query/echarts-editor/EchartsDesign.vue
Normal file
233
src/views/custom-query/echarts-editor/EchartsDesign.vue
Normal file
@@ -0,0 +1,233 @@
|
||||
<template>
|
||||
<div>
|
||||
<EchartsEditor :info="initInfo" :line-data="lineChartsItem" :bar-data="barChartsItem" :pie-data="pieChartsItem"
|
||||
:radar-data="radarChartsItem" :radar-indicator="indicator" @getFinalInfo="getFinalInfo"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import EchartsEditor from "./components/EchartsEditor.vue";
|
||||
//入参
|
||||
const lineChartsItem = ref([
|
||||
{
|
||||
id: 1,
|
||||
unit: '年份',
|
||||
type: '',
|
||||
dataType: 'key',
|
||||
color: '',
|
||||
label: '年份',
|
||||
symbol: "",
|
||||
symbolSize: 0,
|
||||
showSymbol: false,
|
||||
lineStyle: {
|
||||
shadowColor: '',//阴影颜色
|
||||
shadowBlur: 0,//图形阴影的模糊大小
|
||||
opacity: 1
|
||||
},
|
||||
data: ['2013', '2014', '2015', '2016', '2017', '2018']
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
unit: '年销量',
|
||||
type: 'line',
|
||||
dataType: 'value',
|
||||
color: '#9a60b4',//图形颜色
|
||||
label: '华北',
|
||||
symbol: "triangle",//标记的图形circle:圆形,rect:矩形,triangle:三角形,diamond:钻石形,roundRect:圆角矩形,pin:圆钉形,arrow:箭头形,none:不显示标记
|
||||
symbolSize: 8,//标记的大小
|
||||
showSymbol: true,//是否显示标记,如果 false 则只有在 tooltip hover 的时候显示。
|
||||
lineStyle: {
|
||||
shadowColor: '',//阴影颜色
|
||||
shadowBlur: 0,//图形阴影的模糊大小
|
||||
opacity: 1//图形透明度
|
||||
},
|
||||
data: [40, 80, 20, 120, 140, 50]
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
unit: '年销量',
|
||||
type: 'line',
|
||||
dataType: 'value',
|
||||
color: '#3ba272',
|
||||
label: '华东',
|
||||
symbol: "circle",
|
||||
symbolSize: 8,
|
||||
showSymbol: true,
|
||||
lineStyle: {
|
||||
shadowColor: '',//阴影颜色
|
||||
shadowBlur: 0,//图形阴影的模糊大小
|
||||
opacity: 1
|
||||
},
|
||||
data: [140, 180, 120, 40, 50, 150]
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
unit: '年销量',
|
||||
type: 'line',
|
||||
dataType: 'value',
|
||||
color: '#5470c6',
|
||||
label: '华南',
|
||||
symbol: "rect",
|
||||
symbolSize: 8,
|
||||
showSymbol: true,
|
||||
lineStyle: {
|
||||
shadowColor: '',//阴影颜色
|
||||
shadowBlur: 0,//图形阴影的模糊大小
|
||||
opacity: 1
|
||||
},
|
||||
data: [110, 143, 68, 90, 120, 130]
|
||||
}
|
||||
])
|
||||
const barChartsItem = ref([
|
||||
{
|
||||
id: 1,
|
||||
unit: '年份',
|
||||
type: '',
|
||||
dataType: 'key',
|
||||
color: '',
|
||||
label: '年份',
|
||||
showBackground: false,
|
||||
backgroundStyle: {
|
||||
color: '',
|
||||
borderWidth: 0,
|
||||
borderColor: '',
|
||||
borderType: 'solid',
|
||||
},
|
||||
data: ['2013', '2014', '2015', '2016', '2017', '2018']
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
unit: '销售金额',
|
||||
type: 'bar',
|
||||
dataType: 'value',
|
||||
color: '#9a60b4',//图形颜色
|
||||
label: '王五',
|
||||
showBackground: true,//是否显示柱条的背景色
|
||||
backgroundStyle: {
|
||||
color: '#e5e2e2',//柱条的颜色
|
||||
borderWidth: 0,//柱条的描边宽度,默认不描边。
|
||||
borderColor: '#000',//柱条的描边颜色
|
||||
borderType: 'dotted',//柱条的描边类型,默认为实线,支持 'dashed', 'dotted'
|
||||
},
|
||||
data: [40, 80, 20, 120, 140, 50]
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
unit: '销售金额',
|
||||
type: 'bar',
|
||||
dataType: 'value',
|
||||
color: '#3ba272',
|
||||
label: '李四',
|
||||
showBackground: true,
|
||||
backgroundStyle: {
|
||||
color: '#e5e2e2',
|
||||
borderWidth: 0,
|
||||
borderColor: '#000',
|
||||
borderType: 'dashed',
|
||||
},
|
||||
data: [140, 180, 120, 40, 50, 150]
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
unit: '销售金额',
|
||||
type: 'bar',
|
||||
dataType: 'value',
|
||||
color: '#2644a4',
|
||||
label: '张三',
|
||||
showBackground: true,
|
||||
backgroundStyle: {
|
||||
color: '#e5e2e2',
|
||||
borderWidth: 0,
|
||||
borderColor: '#000',
|
||||
borderType: 'solid',
|
||||
},
|
||||
data: [110, 143, 68, 90, 120, 130]
|
||||
}
|
||||
])
|
||||
const pieChartsItem = ref([
|
||||
{id: 1, label: '京东', dataType: 'value', value: 335},
|
||||
{id: 2, label: '菜鸟', dataType: 'value', value: 310},
|
||||
{id: 3, label: '总部', dataType: 'value', value: 234},
|
||||
{id: 4, label: '小电商', dataType: 'value', value: 135},
|
||||
])
|
||||
const radarChartsItem = ref([
|
||||
{label: 'Allocated Budget', dataType: 'value', data: [4200, 3000, 20000, 35000, 50000, 18000]},
|
||||
{label: 'Actual Spending', dataType: 'value', data: [5000, 14000, 28000, 26000, 42000, 21000]},
|
||||
])
|
||||
//定义好echarts的配置数据
|
||||
let initInfo = reactive({
|
||||
xValueAxis: [],
|
||||
yValueAxis: [],
|
||||
//echarts配置数据
|
||||
echartsOptions: {
|
||||
//图例
|
||||
legend: {
|
||||
data: [],
|
||||
selected: {},
|
||||
selectedMode: false
|
||||
},
|
||||
//离容器四侧的距离
|
||||
grid: {
|
||||
left: 40, // 左边距
|
||||
right: 60, // 右边距
|
||||
top: 40, // 顶边距
|
||||
bottom: 20, // 底边距
|
||||
// containLabel: true,
|
||||
},
|
||||
//提示框组件
|
||||
tooltip: {
|
||||
show: true,
|
||||
trigger: 'axis'
|
||||
},
|
||||
//工具栏
|
||||
// toolbox: {
|
||||
// feature: {
|
||||
// //重置按钮显示
|
||||
// restore: {
|
||||
// show: true,
|
||||
// title: '重置'
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
//X轴
|
||||
xAxis: {
|
||||
name: '',
|
||||
type: 'category',
|
||||
data: [],
|
||||
axisLine: {
|
||||
show: true
|
||||
}
|
||||
},
|
||||
//Y轴
|
||||
yAxis: {
|
||||
name: '',
|
||||
type: 'value',
|
||||
data: [],
|
||||
axisLine: {
|
||||
show: true
|
||||
}
|
||||
},
|
||||
radar: {
|
||||
// shape: 'circle',
|
||||
},
|
||||
//配置项
|
||||
series: []
|
||||
}
|
||||
})
|
||||
const indicator= ref([
|
||||
{ name: 'Sales', max: 6500 },
|
||||
{ name: 'Administration', max: 16000 },
|
||||
{ name: 'Information Technology', max: 30000 },
|
||||
{ name: 'Customer Support', max: 38000 },
|
||||
{ name: 'Development', max: 52000 },
|
||||
{ name: 'Marketing', max: 25000 }
|
||||
])
|
||||
//获取到拖拽后的数据
|
||||
const getFinalInfo = (val) => {
|
||||
// console.log('父组件获取最终数据', val)
|
||||
if (val !== undefined) {
|
||||
initInfo = val
|
||||
}
|
||||
}
|
||||
getFinalInfo()
|
||||
</script>
|
||||
538
src/views/custom-query/echarts-editor/components/AxisBox.vue
Normal file
538
src/views/custom-query/echarts-editor/components/AxisBox.vue
Normal file
@@ -0,0 +1,538 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-card class="box-card box-card-h">
|
||||
<el-row justify="space-between" class="x-y-axis">
|
||||
<el-text>值轴/{{ boxName }}</el-text>
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
:content="boxName+',数据类型必须一致!'"
|
||||
placement="bottom"
|
||||
>
|
||||
<el-icon>
|
||||
<Warning/>
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</el-row>
|
||||
<div class="drag-block">
|
||||
<draggable
|
||||
class="list-group"
|
||||
:list="dragList"
|
||||
itemKey="id"
|
||||
:group="group"
|
||||
@start="startDrag"
|
||||
@change="dragChartItem"
|
||||
>
|
||||
<template #item="{ element,index }">
|
||||
<div :id="element.dataType==='value'?'card_'+index:''" tabindex="1"
|
||||
@click.stop="handleClickValueCard(element,index)">
|
||||
<el-card shadow="hover" class="cards x-y-cards"
|
||||
:style="{borderWidth:1,borderColor:element.dataType==='value'?element.color:'#e4e7ed'}">
|
||||
<el-col :span="3">
|
||||
<div>{{ element.label }}</div>
|
||||
</el-col>
|
||||
<el-col :span="13">
|
||||
<div v-if="element.dataType==='value'" class="update-color">
|
||||
<div class="update-color" @click.stop>
|
||||
<span>图形:</span>
|
||||
<el-color-picker v-model="element.color" :color="element.color"
|
||||
@change="changeEchartsColor($event,index)" @active-change="handleActiveChange"/>
|
||||
</div>
|
||||
<div v-if="currentChart==='line'" class="update-color" @click.stop>
|
||||
<span>阴影:</span>
|
||||
<el-color-picker v-model="element.lineStyle.shadowColor" :color="element.lineStyle.shadowColor"
|
||||
@change="changeShadowColor($event,index)" @active-change="handleActiveChange"/>
|
||||
</div>
|
||||
<div v-if="currentChart==='bar'" class="update-color" @click.stop>
|
||||
<span>背景: </span>
|
||||
<el-color-picker v-model="element.backgroundStyle.color" :color="element.backgroundStyle.color"
|
||||
@change="changeBackgroundColor($event,index)" @active-change="handleActiveChange"/>
|
||||
</div>
|
||||
<div v-if="currentChart==='bar'" class="update-color" @click.stop>
|
||||
<span >描边: </span>
|
||||
<el-color-picker v-model="element.backgroundStyle.borderColor" :color="element.backgroundStyle.borderColor"
|
||||
@change="changeBackgroundBorderColor($event,index)" @active-change="handleActiveChange"/>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<div class="cards-right">
|
||||
<span>{{ element.dataType }}</span>
|
||||
<el-icon size="20" color="red" @click.stop="handleCancelAxis(element,index)"
|
||||
style="cursor: pointer">
|
||||
<CircleClose/>
|
||||
</el-icon>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
</draggable>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import draggable from 'vuedraggable'
|
||||
|
||||
const emit = defineEmits(["editBasicSettingList"])
|
||||
const props = defineProps({
|
||||
//box名字
|
||||
boxName: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
//可供拖动的选项列表
|
||||
dragOptions: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
//用于拖拽区域存放选项列表
|
||||
dragList: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
//用于X轴区域存放拖动的选项
|
||||
xAxisList: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
//用于Y轴区域存放拖动的选项
|
||||
yAxisList: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
//标记正在拖动选项的数据类型是否value
|
||||
flag: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
//获取正在拖动选项的数据类型
|
||||
startDataType: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
//初始化加载echarts函数
|
||||
initCharts: {
|
||||
type: Function,
|
||||
default: null
|
||||
},
|
||||
//echarts的配置属性
|
||||
chartOption: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
//当前echarts图形
|
||||
currentChart: {
|
||||
type: String,
|
||||
default: 'line'
|
||||
}
|
||||
})
|
||||
//基础设置列表
|
||||
const lineChartBasicSettingList = ref()
|
||||
const barChartBasicSettingList = ref()
|
||||
//选中类型为value的item所处的list列表
|
||||
const valueCardInList = ref([])
|
||||
//简化代码
|
||||
let xList = reactive(props.xAxisList)
|
||||
let yList = reactive(props.yAxisList)
|
||||
let option = reactive(props.chartOption)
|
||||
//路由刷新
|
||||
const reload = inject("reload")
|
||||
//自定义X/Y分组的拖入拖出事件
|
||||
const group = ref({
|
||||
name: 'people',
|
||||
pull: true,
|
||||
put: props.flag === true ? false : (props.boxName === 'X轴' ? () => handleGroupPut(xList, yList) : () => handleGroupPut(yList, xList))
|
||||
})
|
||||
//将改变的数据传到父组件
|
||||
watch(() => lineChartBasicSettingList.value, (newVal) => {
|
||||
emit("getLineChartBasicSettingList", newVal)
|
||||
})
|
||||
//将改变的数据传到父组件
|
||||
watch(() => barChartBasicSettingList.value, (newVal) => {
|
||||
emit("getBarChartBasicSettingList", newVal)
|
||||
})
|
||||
onMounted(() => {
|
||||
document.addEventListener('click', nullBlockClick)
|
||||
})
|
||||
onBeforeUnmount(() => {
|
||||
document.removeEventListener('click', nullBlockClick)
|
||||
})
|
||||
/**
|
||||
* 设置chart的lineStyle
|
||||
* @param sItem chartItem
|
||||
* @param opacity 透明度
|
||||
*/
|
||||
const handleChangeLineStyle = (sItem, opacity) => {
|
||||
sItem.lineStyle = {
|
||||
shadowColor: sItem.lineStyle.shadowColor,
|
||||
shadowBlur: sItem.lineStyle.shadowBlur,
|
||||
opacity: opacity
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 用于取消charts选中透明度
|
||||
*/
|
||||
const handleChangeOpacity = (type, item) => {
|
||||
if (props.currentChart === 'line') {
|
||||
option.series.forEach((sItem) => {
|
||||
if (type === 'more') {
|
||||
if (sItem.name === item.label) {
|
||||
handleChangeLineStyle(sItem, 1)
|
||||
} else {
|
||||
handleChangeLineStyle(sItem, 0.2)
|
||||
}
|
||||
} else if (type === 'single') {
|
||||
handleChangeLineStyle(sItem, 1)
|
||||
} else {
|
||||
if (sItem.name !== item.label) {
|
||||
handleChangeLineStyle(sItem, 1)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 点击空白处, 清除选项选中状态
|
||||
*/
|
||||
const nullBlockClick = () => {
|
||||
if (valueCardInList.value.length === 0) return;
|
||||
valueCardInList.value.forEach((aItem, aIndex) => {
|
||||
const card = document.getElementById('card_' + aIndex)
|
||||
card.classList.remove('card-active')
|
||||
})
|
||||
clearBasicSetting()
|
||||
//加载echarts
|
||||
props.initCharts()
|
||||
}
|
||||
/**
|
||||
* 封装自定义X/Y分组的拖入事件
|
||||
* @param aType 传入x/y区域数组
|
||||
* @param bType 传入x/y区域数组
|
||||
* @returns {boolean} 返回 true/false
|
||||
*/
|
||||
const handleGroupPut = (aType, bType) => {
|
||||
let flag = false
|
||||
let aLen = aType.length
|
||||
let bLen = bType.length
|
||||
if (aLen === 0 && bLen === 0) {
|
||||
flag = props.startDataType === 'key';
|
||||
} else if (aLen === 0 && bLen !== 0) {
|
||||
flag = bType[0].dataType === 'key';
|
||||
} else if (aLen !== 0 && bLen !== 0) {
|
||||
const dragType = localStorage.getItem('dragType')
|
||||
flag = props.startDataType === aType[0].dataType;
|
||||
if (dragType === 'key') {
|
||||
flag = aType[0].dataType !== 'value';
|
||||
}
|
||||
}
|
||||
return flag
|
||||
}
|
||||
/**
|
||||
* 封装切换坐标轴数据类型为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 = label
|
||||
axis.data = item.data
|
||||
}
|
||||
|
||||
/**
|
||||
* 封装清除坐标轴数据
|
||||
* @param type 标志清除x/y轴
|
||||
*/
|
||||
const clearAxisData = (type) => {
|
||||
let axis
|
||||
if (type === 'xAxis') {
|
||||
axis = option.xAxis
|
||||
} else {
|
||||
axis = option.yAxis
|
||||
}
|
||||
axis.name = ''
|
||||
axis.data = []
|
||||
}
|
||||
/**
|
||||
* 封装key拖入左侧时的重置事件
|
||||
* @param aList x/yList
|
||||
* @param type x/yAxis
|
||||
* @param item 选项item
|
||||
* @param label 选项名
|
||||
*/
|
||||
const restoreChart = (aList, type,item,label) => {
|
||||
let axis
|
||||
if (type === 'xAxis') {
|
||||
axis = option.xAxis
|
||||
} else {
|
||||
axis = option.yAxis
|
||||
}
|
||||
if (aList[0].dataType === 'value') {
|
||||
aList.map((item) => {
|
||||
props.dragOptions.unshift(item)
|
||||
option.legend.selected[item.label] = false
|
||||
})
|
||||
aList.splice(0, aList.length)
|
||||
option.legend.data.splice(0, option.legend.data.length)
|
||||
option.series.splice(0, option.series.length)
|
||||
axis.name = ''
|
||||
option.xAxis.type = 'category'
|
||||
option.yAxis.type = 'value'
|
||||
} else {
|
||||
changeTypeToCategory(item, label, type)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 拖拽类型为key的选项事件
|
||||
* @param item 选项item
|
||||
* @param label 选项名
|
||||
*/
|
||||
const dragTypeToKey = (item, label) => {
|
||||
if (xList.length !== 0 && yList.length === 0) {
|
||||
restoreChart(xList, 'xAxis',item,label)
|
||||
clearAxisData('yAxis')
|
||||
} else if (xList.length === 0 && yList.length !== 0) {
|
||||
restoreChart(yList, 'yAxis',item,label)
|
||||
clearAxisData('xAxis')
|
||||
} else if (xList.length === 0 && yList.length === 0) {
|
||||
//移入左侧待选列表
|
||||
clearAxisData('xAxis')
|
||||
clearAxisData('yAxis')
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 拖拽类型为value的选项事件
|
||||
* @param label 选项名
|
||||
*/
|
||||
const dragTypeToValue = (label) => {
|
||||
//删除选中选项的图例
|
||||
const legendIndex = option.legend.data.findIndex(object => object === label);
|
||||
option.legend.data.splice(legendIndex, 1)
|
||||
//删除echarts配置项series中符合该拖拽选项的item
|
||||
const objectIndex = option.series.findIndex(object => object.name === label);
|
||||
option.legend.selected[label] = false
|
||||
option.series.splice(objectIndex, 1)
|
||||
if (xList.length === 0) {
|
||||
option.xAxis.name = ''
|
||||
} else if (yList.length === 0) {
|
||||
option.yAxis.name = ''
|
||||
}
|
||||
clearBasicSetting()
|
||||
handleDeleteClassName(xList, yList)
|
||||
}
|
||||
/**
|
||||
* 封装清空基本设置
|
||||
*/
|
||||
const clearBasicSetting=()=>{
|
||||
if(props.currentChart==='line'){
|
||||
lineChartBasicSettingList.value = []
|
||||
handleChangeOpacity('single')
|
||||
}else if(props.currentChart==='bar'){
|
||||
barChartBasicSettingList.value=[]
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始拖拽事件
|
||||
* @param event event事件
|
||||
*/
|
||||
const startDrag = (event) => {
|
||||
localStorage.setItem('dragType', event.item._underlying_vm_.dataType)
|
||||
}
|
||||
|
||||
/**
|
||||
* 从X轴/Y轴区域移动选项到左/右侧结束事件
|
||||
* @param event event事件
|
||||
*/
|
||||
const dragChartItem = (event) => {
|
||||
if (event.removed === undefined) return;
|
||||
let item = event.removed.element
|
||||
let label = item.label
|
||||
//拖动key的选项
|
||||
if (item.dataType === "key") {
|
||||
dragTypeToKey(item, label)
|
||||
} else {
|
||||
dragTypeToValue(label)
|
||||
}
|
||||
props.initCharts()
|
||||
localStorage.removeItem('dragType')
|
||||
}
|
||||
|
||||
/**
|
||||
* 选中数据类型为value的点击事件
|
||||
* @param item 点击的选项item
|
||||
* @param index 点击选项的下标
|
||||
*/
|
||||
const handleClickValueCard = (item, index) => {
|
||||
document.addEventListener('click', nullBlockClick)
|
||||
if (item.dataType === 'value' ) {
|
||||
if(props.currentChart === 'line'){
|
||||
changeCardActive(props.dragList, item)
|
||||
lineChartBasicSettingList.value = [item]
|
||||
}else if(props.currentChart === 'bar'){
|
||||
changeCardActive(props.dragList, item)
|
||||
barChartBasicSettingList.value = [item]
|
||||
}
|
||||
}
|
||||
props.initCharts()
|
||||
}
|
||||
|
||||
/**
|
||||
* 封装选中类型为value的数据高亮
|
||||
* @param list x/y区域list
|
||||
* @param item 点击选项的item
|
||||
*/
|
||||
const changeCardActive = (list, item) => {
|
||||
valueCardInList.value = list
|
||||
emit('getCardActiveList',list)
|
||||
if (list.length !== 0 && list[0].dataType === 'value') {
|
||||
handleChangeOpacity('more', item)
|
||||
list.forEach((aItem, aIndex) => {
|
||||
const card = document.getElementById('card_' + aIndex)
|
||||
if (aItem.label === item.label) {
|
||||
card.classList.add('card-active')
|
||||
} else {
|
||||
card.classList.remove('card-active')
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 基础设置: 修改echarts数据颜色
|
||||
* @param val 修改的标记大小
|
||||
* @param index 修改的chart项下标
|
||||
*/
|
||||
const changeEchartsColor = (val, index) => {
|
||||
document.addEventListener('click', nullBlockClick)
|
||||
option.series[index].color = val
|
||||
props.initCharts()
|
||||
}
|
||||
/**
|
||||
* 当选择颜色时移除空白点击事件
|
||||
*/
|
||||
const handleActiveChange = () => {
|
||||
document.removeEventListener('click', nullBlockClick)
|
||||
}
|
||||
|
||||
/**
|
||||
* 基础设置: 修改echarts数据颜色
|
||||
* @param val 修改的标记大小
|
||||
* @param index 修改的chart项下标
|
||||
*/
|
||||
const changeShadowColor = (val, index) => {
|
||||
option.series[index].lineStyle.shadowColor = val
|
||||
props.initCharts()
|
||||
}
|
||||
/**
|
||||
* 基础设置:修改柱条背景颜色
|
||||
* @param val 柱条颜色
|
||||
* @param index 修改的chart项下标
|
||||
*/
|
||||
const changeBackgroundColor = (val, index) => {
|
||||
option.series[index].backgroundStyle.color = val
|
||||
props.initCharts()
|
||||
}
|
||||
/**
|
||||
* 基础设置:修改柱条描边颜色
|
||||
* @param val 柱条描边颜色
|
||||
* @param index 修改的chart项下标
|
||||
*/
|
||||
const changeBackgroundBorderColor = (val, index) => {
|
||||
option.series[index].backgroundStyle.borderColor = val
|
||||
props.initCharts()
|
||||
}
|
||||
/**
|
||||
* 封装从右侧区域拖出事件
|
||||
* @param element 获取点击该拖出的选项事件
|
||||
* @param index 点击该拖出选项的索引
|
||||
* @param aList x/y区域的值
|
||||
* @param bList x/y区域的值
|
||||
* @param aAxis echarts配置项的x/y轴
|
||||
* @param bAxis echarts配置项的x/y轴
|
||||
*/
|
||||
const handleCancel = (element, index, aList, bList, aAxis, bAxis) => {
|
||||
aList.splice(index, 1)
|
||||
props.dragOptions.push(element)
|
||||
if (element.dataType === "key") {
|
||||
aAxis.name = ''
|
||||
aAxis.data = []
|
||||
bAxis.name=''
|
||||
bList.map((item) => {
|
||||
props.dragOptions.unshift(item)
|
||||
option.legend.selected[item.label] = false
|
||||
})
|
||||
bList.splice(0, bList.length)
|
||||
option.legend.data.splice(0, option.legend.data.length)
|
||||
option.series.splice(0, option.series.length)
|
||||
// reload
|
||||
props.initCharts()
|
||||
} else {
|
||||
if (bList.length !== 0 && aList.length === 0) {
|
||||
if (bList[0].dataType === 'key') {
|
||||
aAxis.name = ''
|
||||
} else {
|
||||
bAxis.name = ''
|
||||
}
|
||||
}
|
||||
|
||||
option.legend.data.splice(index, 1)
|
||||
const objectIndex = option.series.findIndex(object => object.name === element.label);
|
||||
option.legend.selected[element.label] = false
|
||||
option.series.splice(objectIndex, 1)
|
||||
props.initCharts()
|
||||
}
|
||||
if(props.currentChart==='line'){
|
||||
handleChangeOpacity('not', element)
|
||||
if (lineChartBasicSettingList.value === undefined) return;
|
||||
lineChartBasicSettingList.value.splice(0, 1)
|
||||
}else if(props.currentChart==='bar'){
|
||||
if (barChartBasicSettingList.value === undefined) return;
|
||||
barChartBasicSettingList.value.splice(0, 1)
|
||||
}
|
||||
// const basicIndex = lineChartBasicSettingList.value.findIndex(object => object.label === element.label)
|
||||
// if (basicIndex !== -1) {
|
||||
// lineChartBasicSettingList.value.splice(basicIndex, 1)
|
||||
// }
|
||||
handleDeleteClassName(aList, bList)
|
||||
props.initCharts()
|
||||
}
|
||||
/**
|
||||
* 拖拽选项后,清除选中选项阴影
|
||||
* @param aList x/y list
|
||||
* @param bList x/y list
|
||||
*/
|
||||
const handleDeleteClassName = (aList, bList) => {
|
||||
let axis = []
|
||||
if (aList.length !== 0 && aList[0].dataType === 'value') {
|
||||
axis = aList
|
||||
} else if (bList.length !== 0 && bList[0].dataType === 'value') {
|
||||
axis = bList
|
||||
}
|
||||
axis.forEach((aItem, aIndex) => {
|
||||
const card = document.getElementById('card_' + aIndex)
|
||||
card.classList.remove('card-active')
|
||||
})
|
||||
}
|
||||
/**
|
||||
* 从右侧x/y轴区域取消选项
|
||||
* @param element 该取消的项
|
||||
* @param index 该取消项的下标
|
||||
*/
|
||||
const handleCancelAxis = (element, index) => {
|
||||
if (props.boxName === 'X轴') {
|
||||
handleCancel(element, index, xList, yList, option.xAxis, option.yAxis)
|
||||
} else {
|
||||
handleCancel(element, index, yList, xList, option.yAxis, option.xAxis)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,307 @@
|
||||
<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>
|
||||
@@ -0,0 +1,307 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-row :gutter="6">
|
||||
<el-col :span="6">
|
||||
<el-select v-model="echartsValue" filterable placeholder="请选择图形状" style="width: 100%" size="large"
|
||||
@change="handleChangeEcharts">
|
||||
<el-option v-for="chartItem in chartType"
|
||||
:key="chartItem.value"
|
||||
:label="chartItem.label"
|
||||
:value="chartItem.value"/>
|
||||
</el-select>
|
||||
<!--左侧选项区域-->
|
||||
<charts-options @editValueFlag="editValueFlag" @editStartDataType="editStartDataType"
|
||||
:drag-options="ChartsItem" :chart-option="option" :init-charts="initChart"
|
||||
:x-axis-list="xValueAxis" :y-axis-list="yValueAxis"
|
||||
:current-chart="echartsValue" :radar-indicator="radarIndicator"/>
|
||||
</el-col>
|
||||
<!--X轴区域-->
|
||||
<el-col :span="9" v-if="echartsValue==='bar'||echartsValue==='line'">
|
||||
<axis-box :box-name="'X轴'" :drag-list="xValueAxis" :drag-options="ChartsItem" :x-axis-list="xValueAxis"
|
||||
:y-axis-list="yValueAxis" :flag="valueFlag"
|
||||
:start-data-type="startDataType" :chart-option="option" :init-charts="initChart"
|
||||
@getLineChartBasicSettingList="getLineChartBasicSettingList"
|
||||
@getBarChartBasicSettingList="getBarChartBasicSettingList" :current-chart="echartsValue"/>
|
||||
</el-col>
|
||||
<!--Y轴区域-->
|
||||
<el-col :span="9" v-if="echartsValue==='bar'||echartsValue==='line'">
|
||||
<axis-box :box-name="'Y轴'" :drag-list="yValueAxis" :drag-options="ChartsItem" :x-axis-list="xValueAxis"
|
||||
:y-axis-list="yValueAxis" :flag="valueFlag"
|
||||
:start-data-type="startDataType" :chart-option="option" :init-charts="initChart"
|
||||
@getLineChartBasicSettingList="getLineChartBasicSettingList"
|
||||
@getBarChartBasicSettingList="getBarChartBasicSettingList" :current-chart="echartsValue"/>
|
||||
</el-col>
|
||||
<el-col :span="9" v-if="echartsValue==='pie'">
|
||||
<pie-box :drag-list="xValueAxis" :init-charts="initChart" :chart-option="option"/>
|
||||
</el-col>
|
||||
<el-col :span="9" v-if="echartsValue==='radar'">
|
||||
<radar-box :drag-list="xValueAxis" :init-charts="initChart" :chart-option="option"/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-button @click.stop="saveData">保存</el-button>
|
||||
<el-button v-if="echartsValue==='line'" @click.stop="openAdvancedSettings">高级设置</el-button>
|
||||
<el-row :gutter="6">
|
||||
<el-col :span="16">
|
||||
<div id="container" ref="chart" @click.stop></div>
|
||||
</el-col>
|
||||
<!--基础设置-->
|
||||
<el-col :span="8">
|
||||
<!-- 折线图基础设置-->
|
||||
<line-chart-basic-setting v-if="echartsValue==='line'" :basic-list="lineChartBasicSettingList"
|
||||
:init-charts="initChart"
|
||||
:chart-option="option"/>
|
||||
<!-- 柱状图基础设置-->
|
||||
<bar-chart-basic-setting v-if="echartsValue==='bar'" :basic-list="barChartBasicSettingList"
|
||||
:init-charts="initChart"
|
||||
:chart-option="option"/>
|
||||
<!-- 饼图基础设置-->
|
||||
<!-- <pie-chart-basic-setting v-if="echartsValue==='pie'"/>-->
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!--高级设置-->
|
||||
<!-- 折线图高级设置-->
|
||||
<line-chart-advanced-settings v-if="echartsValue==='line'" ref="advancedSettings" :init-charts="initChart"
|
||||
:chart-option="option"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import * as echarts from 'echarts'
|
||||
import draggable from 'vuedraggable'
|
||||
import ChartsOptions from "./ChartsOptions.vue";
|
||||
import AxisBox from "./AxisBox.vue";
|
||||
import LineChartBasicSetting from "./lineChart/BasicSetting.vue";
|
||||
import LineChartAdvancedSettings from "./lineChart/AdvancedSettings.vue";
|
||||
import BarChartBasicSetting from "./barChart/BasicSetting.vue";
|
||||
// import PieChartBasicSetting from "./pieChart/BasicSetting.vue";
|
||||
import PieBox from "./pieChart/PieBox.vue";
|
||||
import RadarBox from "./radarChart/RadarBox.vue";
|
||||
// import BarChartAdvancedSettings from "./barChart/AdvancedSettings.vue";
|
||||
|
||||
const emit = defineEmits(["getFinalInfo"])
|
||||
const props = defineProps({
|
||||
info: {
|
||||
type: Object,
|
||||
default: {}
|
||||
},
|
||||
lineData: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
barData: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
pieData: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
radarData: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
radarIndicator: {
|
||||
type: Array,
|
||||
default: []
|
||||
}
|
||||
})
|
||||
//图形: 1:折线图 2.柱状图 3.饼图
|
||||
const chartType = reactive([
|
||||
{
|
||||
value: 'line',
|
||||
label: '折线图',
|
||||
},
|
||||
{
|
||||
value: 'bar',
|
||||
label: '柱状图',
|
||||
},
|
||||
{
|
||||
value: 'pie',
|
||||
label: '饼图',
|
||||
},
|
||||
{
|
||||
value: 'radar',
|
||||
label: '雷达图',
|
||||
}
|
||||
])
|
||||
//基础设置列表
|
||||
const lineChartBasicSettingList = ref([])
|
||||
const barChartBasicSettingList = ref([])
|
||||
const advancedSettings = ref()
|
||||
//获取父组件传来的初始数据
|
||||
const initInfo = reactive(props.info)
|
||||
//从左侧获取拖动的选项的数据类型
|
||||
const startDataType = ref()
|
||||
//标记从左侧拖动选项数据类型是否是value
|
||||
const valueFlag = ref(false)
|
||||
//简化代码
|
||||
let xValueAxis = reactive(initInfo.xValueAxis)
|
||||
let yValueAxis = reactive(initInfo.yValueAxis)
|
||||
const line_data = reactive(props.lineData)
|
||||
const bar_data = reactive(props.barData)
|
||||
const pie_data = reactive(props.pieData)
|
||||
const radar_data = reactive(props.radarData)
|
||||
let option = reactive(initInfo.echartsOptions)
|
||||
|
||||
//页面左上角select选择框绑定数据
|
||||
const echartsValue = ref('line')
|
||||
//可供拖动的选项列表
|
||||
const ChartsItem = ref([])
|
||||
//获取到container容器实例
|
||||
const chart = ref(null);
|
||||
//定义echarts实例
|
||||
let myEcharts = reactive({});
|
||||
onMounted(() => {
|
||||
if (ChartsItem.value.length === 0) {
|
||||
ChartsItem.value = line_data
|
||||
}
|
||||
//初始化echarts(不显示图)
|
||||
let selectLegend = {}
|
||||
ChartsItem.value.forEach(item => {
|
||||
if (item.dataType !== 'key') {
|
||||
selectLegend[item.label] = false
|
||||
}
|
||||
})
|
||||
option.legend.selected = selectLegend
|
||||
if (echartsValue.value === 'pie'||echartsValue.value === 'radar') {
|
||||
isShowAxisLine(false)
|
||||
} else {
|
||||
isShowAxisLine(true)
|
||||
}
|
||||
//加载echarts
|
||||
initChart();
|
||||
})
|
||||
|
||||
/**
|
||||
* 修改valueFlag
|
||||
* @param val 子组件传的动态值
|
||||
*/
|
||||
const editValueFlag = (val) => {
|
||||
valueFlag.value = val
|
||||
}
|
||||
/**
|
||||
* 修改startDataType
|
||||
* @param str 子组件传的动态值
|
||||
*/
|
||||
const editStartDataType = (str) => {
|
||||
startDataType.value = str
|
||||
}
|
||||
/**
|
||||
* 用于其他组件获取基础设置列表
|
||||
* @param str 子组件传的动态值
|
||||
*/
|
||||
const getLineChartBasicSettingList = (str) => {
|
||||
lineChartBasicSettingList.value = str
|
||||
}
|
||||
/**
|
||||
* 修改option
|
||||
* @param str 子组件传的动态值
|
||||
*/
|
||||
const getBarChartBasicSettingList = (str) => {
|
||||
barChartBasicSettingList.value = str
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 切换echarts图类型事件
|
||||
* @param e event事件
|
||||
*/
|
||||
const handleChangeEcharts = (e) => {
|
||||
if (xValueAxis.length !== 0 || yValueAxis.length !== 0) {
|
||||
|
||||
xValueAxis.map((item) => {
|
||||
ChartsItem.value.unshift(item)
|
||||
option.legend.selected[item.label] = false
|
||||
})
|
||||
xValueAxis.splice(0, xValueAxis.length)
|
||||
yValueAxis.map((item) => {
|
||||
ChartsItem.value.unshift(item)
|
||||
option.legend.selected[item.label] = false
|
||||
})
|
||||
yValueAxis.splice(0, yValueAxis.length)
|
||||
option.legend.data.splice(0, option.legend.data.length)
|
||||
option.series.splice(0, option.series.length)
|
||||
option.xAxis.name = ''
|
||||
option.xAxis.data = []
|
||||
option.xAxis.type = 'category'
|
||||
option.yAxis.name = ''
|
||||
option.yAxis.data = []
|
||||
option.yAxis.type = 'value'
|
||||
initChart()
|
||||
}
|
||||
echartsValue.value = e
|
||||
if (e === 'line') {
|
||||
ChartsItem.value = line_data
|
||||
isShowAxisLine(true)
|
||||
option.radar={}
|
||||
} else if (e === 'bar') {
|
||||
ChartsItem.value = bar_data
|
||||
isShowAxisLine(true)
|
||||
option.radar={}
|
||||
} else if (e === 'pie') {
|
||||
ChartsItem.value = pie_data
|
||||
isShowAxisLine(false)
|
||||
option.radar={}
|
||||
}else if (e === 'radar') {
|
||||
ChartsItem.value = radar_data
|
||||
isShowAxisLine(false)
|
||||
option.radar.indicator = props.radarIndicator
|
||||
}
|
||||
let selectLegend = {}
|
||||
ChartsItem.value.forEach(item => {
|
||||
if (item.dataType !== 'key') {
|
||||
selectLegend[item.label] = false
|
||||
}
|
||||
})
|
||||
option.legend.selected = selectLegend
|
||||
initChart()
|
||||
}
|
||||
/**
|
||||
* 是否显示x/y轴线
|
||||
* @param type
|
||||
*/
|
||||
const isShowAxisLine = (type) => {
|
||||
option.xAxis.axisLine.show = type
|
||||
option.yAxis.axisLine.show = type
|
||||
if (type === false) {
|
||||
option.tooltip.trigger = 'item'
|
||||
} else {
|
||||
option.tooltip.trigger = 'axis'
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 初始化echarts实例方法
|
||||
*/
|
||||
const initChart = () => {
|
||||
console.log('initChartoption', option)
|
||||
//3.初始化container容器
|
||||
myEcharts = echarts.init(chart.value);
|
||||
//5.传入数据
|
||||
myEcharts.setOption(option,true);
|
||||
//图表大小自适应窗口大小变化
|
||||
window.onresize = () => {
|
||||
myEcharts.resize();
|
||||
}
|
||||
//点击事件
|
||||
// myEcharts.on('click', function (params) {
|
||||
// console.log('dddd点击事件', params);
|
||||
// });
|
||||
// myEcharts.restore();
|
||||
localStorage.removeItem('dragType')
|
||||
}
|
||||
/**
|
||||
* 保存数据
|
||||
*/
|
||||
const saveData = () => {
|
||||
console.log('最终initInfo', initInfo)
|
||||
emit("getFinalInfo", initInfo)
|
||||
}
|
||||
/**
|
||||
* 打开高级设置弹框
|
||||
*/
|
||||
const openAdvancedSettings = () => {
|
||||
advancedSettings.value.showDrawer()
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
<template>
|
||||
<el-drawer v-model="drawerVisible" direction="rtl">
|
||||
<template #header>
|
||||
<h4>高级设置</h4>
|
||||
</template>
|
||||
<template #default>
|
||||
<el-form :model="settingsForm" class="advanced-setting">
|
||||
<el-form-item label="是否点击图例改变图显示状态">
|
||||
<el-switch active-text="是" inactive-text="否" v-model="settingsForm.isClickLegendToShow"
|
||||
@change="changeIsClickLegend"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="是否显示提示框组件">
|
||||
<el-switch active-text="是" inactive-text="否" v-model="settingsForm.isShowTooltip"
|
||||
@change="changeIsShowTooltip"/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
<template #footer>
|
||||
<el-button @click="cancelSettings">取消</el-button>
|
||||
<el-button type="primary" @click="confirmSettings">确认</el-button>
|
||||
</template>
|
||||
</el-drawer>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
//初始化加载echarts函数
|
||||
initCharts: {
|
||||
type: Function,
|
||||
default: null
|
||||
},
|
||||
//echarts的配置属性
|
||||
chartOption: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
})
|
||||
let option = reactive(props.chartOption)
|
||||
//高级设置抽屉是否展开
|
||||
const drawerVisible = ref(false)
|
||||
//高级设置属性
|
||||
const settingsForm = reactive({
|
||||
isClickLegendToShow: option.legend.selectedMode,//打开点击图例改变图显示状态
|
||||
isShowTooltip: option.tooltip.show//是否显示提示框组件
|
||||
})
|
||||
/**
|
||||
* 打开高级设置弹窗
|
||||
*/
|
||||
const showDrawer = () => {
|
||||
drawerVisible.value = true
|
||||
}
|
||||
|
||||
/**
|
||||
* 高级设置: 取消按钮
|
||||
*/
|
||||
const cancelSettings = () => {
|
||||
drawerVisible.value = false
|
||||
}
|
||||
/**
|
||||
* 高级设置: 确认按钮
|
||||
*/
|
||||
const confirmSettings = () => {
|
||||
drawerVisible.value = false
|
||||
props.initCharts()
|
||||
}
|
||||
|
||||
/**
|
||||
* 高级设置:打开点击图例改变图显示状态
|
||||
* @param val
|
||||
*/
|
||||
const changeIsClickLegend = (val) => {
|
||||
option.legend.selectedMode = val
|
||||
}
|
||||
|
||||
/**
|
||||
* 高级设置:是否显示提示框组件
|
||||
* @param val
|
||||
*/
|
||||
const changeIsShowTooltip = (val) => {
|
||||
option.tooltip.show = val
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
showDrawer
|
||||
})
|
||||
</script>
|
||||
@@ -0,0 +1,140 @@
|
||||
<template>
|
||||
<el-scrollbar height="450px">
|
||||
<div class="basic-setup" @click.stop>
|
||||
柱状图基本设置
|
||||
</div>
|
||||
<div v-for="(settingItem) in basicList" class="setting" @click.stop>
|
||||
<div class="setting-title">{{ settingItem.label }}</div>
|
||||
<div class="setting-item">
|
||||
<span>显示柱条背景: </span>
|
||||
<el-switch active-text="是" inactive-text="否" v-model="settingItem.showBackground"
|
||||
@change="changeIsShowBackground($event,settingItem)"/>
|
||||
|
||||
</div>
|
||||
<div v-if="settingItem.showBackground!==false">
|
||||
<div class="setting-item">
|
||||
<span>柱条描边宽度: </span>
|
||||
<el-input-number v-model="settingItem.backgroundStyle.borderWidth" :min="0"
|
||||
@change="changeBorderWidth($event,settingItem)"/>
|
||||
</div>
|
||||
|
||||
<!-- <div class="setting-item" v-if="settingItem.backgroundStyle.borderWidth!==0">-->
|
||||
<!-- <span>柱条描边颜色: </span>-->
|
||||
<!-- <el-color-picker v-model="settingItem.backgroundStyle.borderColor"-->
|
||||
<!-- :color="settingItem.backgroundStyle.borderColor"-->
|
||||
<!-- @change="changeBorderColor($event,settingItem)"/>-->
|
||||
<!-- </div>-->
|
||||
<div class="setting-item" v-if="settingItem.backgroundStyle.borderWidth!==0">
|
||||
<span>柱条描边类型: </span>
|
||||
<el-select v-model="settingItem.backgroundStyle.borderType" @change="switchBorderType($event,settingItem)">
|
||||
<el-option
|
||||
v-for="symbolItem in borderTypeList"
|
||||
:key="symbolItem.value"
|
||||
:label="symbolItem.label"
|
||||
:value="symbolItem.value"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
//基础设置列表
|
||||
basicList: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
//初始化加载echarts函数
|
||||
initCharts: {
|
||||
type: Function,
|
||||
default: null
|
||||
},
|
||||
//echarts的配置属性
|
||||
chartOption: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
})
|
||||
let option = reactive(props.chartOption)
|
||||
//图形标记列表
|
||||
const borderTypeList = ref([
|
||||
{value: 'solid', label: '实线'},
|
||||
{value: 'dashed', label: '虚线'},
|
||||
{value: 'dotted', label: '点线'}
|
||||
])
|
||||
/**
|
||||
* 封装基本设置修改echarts属性事件
|
||||
* @param item 修改的项
|
||||
* @param type option.series中的属性名
|
||||
* @param val 获取修改的值
|
||||
*/
|
||||
const changeSingleParams = (item, type, val) => {
|
||||
option.series.forEach((sItem, sIndex) => {
|
||||
if (sItem.name === item.label) {
|
||||
getSeriesParams(type, sIndex, val)
|
||||
}
|
||||
})
|
||||
}
|
||||
/**
|
||||
* 根据changeSingleParams方法传的动态type,封装数据修改事件
|
||||
* @param type option.series中的属性名
|
||||
* @param index 修改某项属性的下标
|
||||
* @param val 获取修改的值
|
||||
*/
|
||||
const getSeriesParams = (type, index, val) => {
|
||||
let seriesItem = option.series[index]
|
||||
switch (type) {
|
||||
case 'showBackground':
|
||||
return seriesItem.showBackground = val
|
||||
case 'color':
|
||||
return seriesItem.backgroundStyle.color = val
|
||||
case 'borderWidth':
|
||||
return seriesItem.backgroundStyle.borderWidth = val
|
||||
case 'borderColor':
|
||||
return seriesItem.backgroundStyle.borderColor = val
|
||||
case 'borderType':
|
||||
return seriesItem.backgroundStyle.borderType = val
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 基础设置:修改是否显示柱条背景
|
||||
* @param val 是否显示
|
||||
* @param item 修改的chart项
|
||||
*/
|
||||
const changeIsShowBackground = (val, item) => {
|
||||
changeSingleParams(item, 'showBackground', val)
|
||||
props.initCharts()
|
||||
}
|
||||
|
||||
/**
|
||||
* 基础设置:修改柱条描边宽度
|
||||
* @param val 宽度
|
||||
* @param item 修改的chart项
|
||||
*/
|
||||
const changeBorderWidth = (val, item) => {
|
||||
changeSingleParams(item, 'borderWidth', val)
|
||||
props.initCharts()
|
||||
}
|
||||
/**
|
||||
* 基础设置:修改柱条的描边颜色
|
||||
* @param val 颜色
|
||||
* @param item 修改的chart项
|
||||
*/
|
||||
const changeBorderColor = (val, item) => {
|
||||
changeSingleParams(item, 'borderColor', val)
|
||||
props.initCharts()
|
||||
}
|
||||
/**
|
||||
* 基础设置:修改柱条的描边类型
|
||||
* @param val 类型
|
||||
* @param item 修改的chart项
|
||||
*/
|
||||
const switchBorderType = (val, item) => {
|
||||
changeSingleParams(item, 'borderType', val)
|
||||
props.initCharts()
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,86 @@
|
||||
<template>
|
||||
<el-drawer v-model="drawerVisible" direction="rtl">
|
||||
<template #header>
|
||||
<h4>高级设置</h4>
|
||||
</template>
|
||||
<template #default>
|
||||
<el-form :model="settingsForm" class="advanced-setting">
|
||||
<el-form-item label="是否点击图例改变图显示状态">
|
||||
<el-switch active-text="是" inactive-text="否" v-model="settingsForm.isClickLegendToShow"
|
||||
@change="changeIsClickLegend"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="是否显示提示框组件">
|
||||
<el-switch active-text="是" inactive-text="否" v-model="settingsForm.isShowTooltip"
|
||||
@change="changeIsShowTooltip"/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
<template #footer>
|
||||
<el-button @click="cancelSettings">取消</el-button>
|
||||
<el-button type="primary" @click="confirmSettings">确认</el-button>
|
||||
</template>
|
||||
</el-drawer>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
//初始化加载echarts函数
|
||||
initCharts: {
|
||||
type: Function,
|
||||
default: null
|
||||
},
|
||||
//echarts的配置属性
|
||||
chartOption: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
})
|
||||
let option = reactive(props.chartOption)
|
||||
//高级设置抽屉是否展开
|
||||
const drawerVisible = ref(false)
|
||||
//高级设置属性
|
||||
const settingsForm = reactive({
|
||||
isClickLegendToShow: option.legend.selectedMode,//打开点击图例改变图显示状态
|
||||
isShowTooltip: option.tooltip.show//是否显示提示框组件
|
||||
})
|
||||
/**
|
||||
* 打开高级设置弹窗
|
||||
*/
|
||||
const showDrawer = () => {
|
||||
drawerVisible.value = true
|
||||
}
|
||||
|
||||
/**
|
||||
* 高级设置: 取消按钮
|
||||
*/
|
||||
const cancelSettings = () => {
|
||||
drawerVisible.value = false
|
||||
}
|
||||
/**
|
||||
* 高级设置: 确认按钮
|
||||
*/
|
||||
const confirmSettings = () => {
|
||||
drawerVisible.value = false
|
||||
props.initCharts()
|
||||
}
|
||||
|
||||
/**
|
||||
* 高级设置:打开点击图例改变图显示状态
|
||||
* @param val
|
||||
*/
|
||||
const changeIsClickLegend = (val) => {
|
||||
option.legend.selectedMode = val
|
||||
}
|
||||
|
||||
/**
|
||||
* 高级设置:是否显示提示框组件
|
||||
* @param val
|
||||
*/
|
||||
const changeIsShowTooltip = (val) => {
|
||||
option.tooltip.show = val
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
showDrawer
|
||||
})
|
||||
</script>
|
||||
@@ -0,0 +1,160 @@
|
||||
<template>
|
||||
<el-scrollbar height="450px">
|
||||
<div class="basic-setup" @click.stop>
|
||||
折线图基本设置
|
||||
</div>
|
||||
<div v-for="(settingItem) in basicList" class="setting" @click.stop>
|
||||
<div class="setting-title">{{ settingItem.label }}</div>
|
||||
<!-- <div class="setting-item">-->
|
||||
<!-- <span>图形: </span>-->
|
||||
<!-- <el-select v-model="settingItem.type" @change="switchChart($event,settingItem)">-->
|
||||
<!-- <el-option-->
|
||||
<!-- v-for="chartItem in [{value: 'line',label: '折线图'},{value: 'bar',label: '柱状图'}]"-->
|
||||
<!-- :key="chartItem.value"-->
|
||||
<!-- :label="chartItem.label"-->
|
||||
<!-- :value="chartItem.value"-->
|
||||
<!-- />-->
|
||||
<!-- </el-select>-->
|
||||
<!-- </div>-->
|
||||
<div class="setting-item">
|
||||
<span>显示标记: </span>
|
||||
<el-switch active-text="是" inactive-text="否" v-model="settingItem.showSymbol"
|
||||
@change="changeIsShowSymbol($event,settingItem)"/>
|
||||
|
||||
</div>
|
||||
<div class="setting-item" v-if="settingItem.showSymbol===true">
|
||||
<span>标记: </span>
|
||||
<el-select v-model="settingItem.symbol" @change="switchSymbol($event,settingItem)">
|
||||
<el-option
|
||||
v-for="symbolItem in symbolList"
|
||||
:key="symbolItem.value"
|
||||
:label="symbolItem.label"
|
||||
:value="symbolItem.value"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="setting-item" v-if="settingItem.showSymbol===true">
|
||||
<span>标记大小: </span>
|
||||
<el-input-number v-model="settingItem.symbolSize" :min="1" @change="changeSymbolSize($event,settingItem)"/>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<span>阴影模糊大小: </span>
|
||||
<el-input-number v-model="settingItem.lineStyle.shadowBlur" :min="0" @change="changeShadowBlur($event,settingItem)"/>
|
||||
</div>
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
//基础设置列表
|
||||
basicList: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
//初始化加载echarts函数
|
||||
initCharts: {
|
||||
type: Function,
|
||||
default: null
|
||||
},
|
||||
//echarts的配置属性
|
||||
chartOption: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
})
|
||||
//图形标记列表
|
||||
const symbolList = ref([
|
||||
{value: 'none', label: '不显示标记'},
|
||||
{value: 'circle', label: '圆形'},
|
||||
{value: 'rect', label: '矩形'},
|
||||
{value: 'triangle', label: '三角形'},
|
||||
{value: 'diamond', label: '钻石形'},
|
||||
{value: 'roundRect', label: '圆角矩形'},
|
||||
{value: 'pin', label: '圆钉形'},
|
||||
{value: 'arrow', label: '箭头形'},
|
||||
])
|
||||
let option = reactive(props.chartOption)
|
||||
|
||||
/**
|
||||
* 封装基本设置修改echarts属性事件
|
||||
* @param item 修改的项
|
||||
* @param type option.series中的属性名
|
||||
* @param val 获取修改的值
|
||||
*/
|
||||
const changeSingleParams = (item, type, val) => {
|
||||
option.series.forEach((sItem, sIndex) => {
|
||||
if (sItem.name === item.label) {
|
||||
getSeriesParams(type, sIndex, val)
|
||||
}
|
||||
})
|
||||
}
|
||||
/**
|
||||
* 根据changeSingleParams方法传的动态type,封装数据修改事件
|
||||
* @param type option.series中的属性名
|
||||
* @param index 修改某项属性的下标
|
||||
* @param val 获取修改的值
|
||||
*/
|
||||
const getSeriesParams = (type, index, val) => {
|
||||
let seriesItem = option.series[index]
|
||||
switch (type) {
|
||||
case 'type':
|
||||
return seriesItem.type = val
|
||||
case 'showSymbol':
|
||||
return seriesItem.showSymbol = val
|
||||
case 'symbol':
|
||||
return seriesItem.symbol = val
|
||||
case 'symbolSize':
|
||||
return seriesItem.symbolSize = val
|
||||
case 'shadowBlur':
|
||||
return seriesItem.lineStyle.shadowBlur = val
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 基础设置:是否显示标记
|
||||
* @param val 修改的标记大小
|
||||
* @param item 修改的chart项
|
||||
*/
|
||||
const changeIsShowSymbol = (val, item) => {
|
||||
changeSingleParams(item, 'showSymbol', val)
|
||||
props.initCharts()
|
||||
}
|
||||
|
||||
/**
|
||||
* 基础设置:切换chart的形状
|
||||
* @param val 修改的标记大小
|
||||
* @param item 修改的chart项
|
||||
*/
|
||||
const switchChart = (val, item) => {
|
||||
changeSingleParams(item, 'type', val)
|
||||
props.initCharts()
|
||||
}
|
||||
/**
|
||||
* 基础设置:修改标记
|
||||
* @param val 修改的标记大小
|
||||
* @param item 修改的chart项
|
||||
*/
|
||||
const switchSymbol = (val, item) => {
|
||||
changeSingleParams(item, 'symbol', val)
|
||||
props.initCharts()
|
||||
}
|
||||
/**
|
||||
* 基础设置:修改标记大小
|
||||
* @param val 修改的标记大小
|
||||
* @param item 修改的chart项
|
||||
*/
|
||||
const changeSymbolSize = (val, item) => {
|
||||
changeSingleParams(item, 'symbolSize', val)
|
||||
props.initCharts()
|
||||
}
|
||||
|
||||
/**
|
||||
* 基础设置:修改图形阴影的模糊大小
|
||||
* @param val 修改的阴影的模糊大小
|
||||
* @param item 修改的chart项
|
||||
*/
|
||||
const changeShadowBlur = (val, item) => {
|
||||
changeSingleParams(item, 'shadowBlur', val)
|
||||
props.initCharts()
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,17 @@
|
||||
<template>
|
||||
<el-scrollbar height="450px">
|
||||
<div class="basic-setup" @click.stop>
|
||||
饼图基本设置
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "BasicSetting"
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,116 @@
|
||||
<template>
|
||||
<el-card class="box-card box-card-h">
|
||||
<el-row justify="space-between" class="x-y-axis">
|
||||
<el-text>饼图数据项</el-text>
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
:content="'数据类型必须是数字!'"
|
||||
placement="bottom"
|
||||
>
|
||||
<el-icon>
|
||||
<Warning/>
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</el-row>
|
||||
<div class="drag-block">
|
||||
<draggable
|
||||
class="list-group"
|
||||
:list="dragList"
|
||||
itemKey="id"
|
||||
group="people"
|
||||
@start="startDrag"
|
||||
@change="dragChartItem"
|
||||
>
|
||||
<template #item="{ element,index }">
|
||||
<div>
|
||||
<el-card shadow="hover" class="cards x-y-cards">
|
||||
<el-col :span="8">
|
||||
<div>{{ element.label }}</div>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<div class="cards-right">
|
||||
<span>{{ element.dataType }}</span>
|
||||
<!-- <el-icon size="20" color="red" @click.stop="handleCancelAxis(element,index)"-->
|
||||
<!-- style="cursor: pointer">-->
|
||||
<!-- <CircleClose/>-->
|
||||
<!-- </el-icon>-->
|
||||
</div>
|
||||
</el-col>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
</draggable>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import draggable from 'vuedraggable'
|
||||
const props = defineProps({
|
||||
//用于拖拽区域存放选项列表
|
||||
dragList: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
//初始化加载echarts函数
|
||||
initCharts: {
|
||||
type: Function,
|
||||
default: null
|
||||
},
|
||||
//echarts的配置属性
|
||||
chartOption: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
})
|
||||
let option = reactive(props.chartOption)
|
||||
/**
|
||||
* 开始拖拽事件
|
||||
* @param event event事件
|
||||
*/
|
||||
const startDrag = (event) => {
|
||||
|
||||
}
|
||||
/**
|
||||
* 从X轴/Y轴区域移动选项到左/右侧结束事件
|
||||
* @param event event事件
|
||||
*/
|
||||
const dragChartItem = (event) => {
|
||||
console.log('dragChartItem',event)
|
||||
if (event.removed === undefined) return;
|
||||
let item = event.removed.element
|
||||
let label = item.label
|
||||
dragTypeToValue(label)
|
||||
props.initCharts()
|
||||
// localStorage.removeItem('dragType')
|
||||
}
|
||||
/**
|
||||
* 拖拽类型为value的选项事件
|
||||
* @param label 选项名
|
||||
*/
|
||||
const dragTypeToValue = (label) => {
|
||||
console.log('dragTypeToValue',label,option)
|
||||
//删除选中选项的图例
|
||||
const legendIndex = option.legend.data.findIndex(object => object === label);
|
||||
option.legend.data.splice(legendIndex, 1)
|
||||
//删除echarts配置项series中符合该拖拽选项的item
|
||||
const objectIndex = option.series[0].data.findIndex(object => object.name === label);
|
||||
option.legend.selected[label] = false
|
||||
option.series[0].data.splice(objectIndex, 1)
|
||||
if(option.series[0].data.length===0){
|
||||
option.series.splice(0,1)
|
||||
}
|
||||
// clearBasicSetting()
|
||||
}
|
||||
const handleCancelAxis = (element, index) => {
|
||||
console.log('拖出xxx')
|
||||
dragTypeToValue(element.label)
|
||||
props.initCharts()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,110 @@
|
||||
<template>
|
||||
<el-card class="box-card box-card-h">
|
||||
<el-row justify="space-between" class="x-y-axis">
|
||||
<el-text>雷达图数据项</el-text>
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
:content="'数据类型必须是数字!'"
|
||||
placement="bottom"
|
||||
>
|
||||
<el-icon>
|
||||
<Warning/>
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</el-row>
|
||||
<div class="drag-block">
|
||||
<draggable
|
||||
class="list-group"
|
||||
:list="dragList"
|
||||
itemKey="id"
|
||||
group="people"
|
||||
@start="startDrag"
|
||||
@change="dragChartItem"
|
||||
>
|
||||
<template #item="{ element,index }">
|
||||
<div>
|
||||
<el-card shadow="hover" class="cards x-y-cards">
|
||||
<el-col :span="8">
|
||||
<div>{{ element.label }}</div>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<div class="cards-right">
|
||||
<span>{{ element.dataType }}</span>
|
||||
<!-- <el-icon size="20" color="red" @click.stop="handleCancelAxis(element,index)"-->
|
||||
<!-- style="cursor: pointer">-->
|
||||
<!-- <CircleClose/>-->
|
||||
<!-- </el-icon>-->
|
||||
</div>
|
||||
</el-col>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
</draggable>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import draggable from 'vuedraggable'
|
||||
const props = defineProps({
|
||||
//用于拖拽区域存放选项列表
|
||||
dragList: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
//初始化加载echarts函数
|
||||
initCharts: {
|
||||
type: Function,
|
||||
default: null
|
||||
},
|
||||
//echarts的配置属性
|
||||
chartOption: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
})
|
||||
let option = reactive(props.chartOption)
|
||||
/**
|
||||
* 开始拖拽事件
|
||||
* @param event event事件
|
||||
*/
|
||||
const startDrag = (event) => {
|
||||
|
||||
}
|
||||
/**
|
||||
* 从X轴/Y轴区域移动选项到左/右侧结束事件
|
||||
* @param event event事件
|
||||
*/
|
||||
const dragChartItem = (event) => {
|
||||
console.log('dragChartItem',event)
|
||||
if (event.removed === undefined) return;
|
||||
let item = event.removed.element
|
||||
let label = item.label
|
||||
dragTypeToValue(label)
|
||||
props.initCharts()
|
||||
// localStorage.removeItem('dragType')
|
||||
}
|
||||
/**
|
||||
* 拖拽类型为value的选项事件
|
||||
* @param label 选项名
|
||||
*/
|
||||
const dragTypeToValue = (label) => {
|
||||
//删除选中选项的图例
|
||||
const legendIndex = option.legend.data.findIndex(object => object === label);
|
||||
option.legend.data.splice(legendIndex, 1)
|
||||
//删除echarts配置项series中符合该拖拽选项的item
|
||||
const objectIndex = option.series[0].data.findIndex(object => object.name === label);
|
||||
option.legend.selected[label] = false
|
||||
option.series[0].data.splice(objectIndex, 1)
|
||||
// clearBasicSetting()
|
||||
if(option.series[0].data.length===0){
|
||||
option.series.splice(0,1)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
233
src/views/custom-query/echarts-editor/index.vue
Normal file
233
src/views/custom-query/echarts-editor/index.vue
Normal file
@@ -0,0 +1,233 @@
|
||||
<template>
|
||||
<div>
|
||||
<EchartsEditor :info="initInfo" :line-data="lineChartsItem" :bar-data="barChartsItem" :pie-data="pieChartsItem"
|
||||
:radar-data="radarChartsItem" :radar-indicator="indicator" @getFinalInfo="getFinalInfo"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import EchartsEditor from "./components/EchartsEditor.vue";
|
||||
//入参
|
||||
const lineChartsItem = ref([
|
||||
{
|
||||
id: 1,
|
||||
unit: '年份',
|
||||
type: '',
|
||||
dataType: 'key',
|
||||
color: '',
|
||||
label: '年份',
|
||||
symbol: "",
|
||||
symbolSize: 0,
|
||||
showSymbol: false,
|
||||
lineStyle: {
|
||||
shadowColor: '',//阴影颜色
|
||||
shadowBlur: 0,//图形阴影的模糊大小
|
||||
opacity: 1
|
||||
},
|
||||
data: ['2013', '2014', '2015', '2016', '2017', '2018']
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
unit: '年销量',
|
||||
type: 'line',
|
||||
dataType: 'value',
|
||||
color: '#9a60b4',//图形颜色
|
||||
label: '华北',
|
||||
symbol: "triangle",//标记的图形circle:圆形,rect:矩形,triangle:三角形,diamond:钻石形,roundRect:圆角矩形,pin:圆钉形,arrow:箭头形,none:不显示标记
|
||||
symbolSize: 8,//标记的大小
|
||||
showSymbol: true,//是否显示标记,如果 false 则只有在 tooltip hover 的时候显示。
|
||||
lineStyle: {
|
||||
shadowColor: '',//阴影颜色
|
||||
shadowBlur: 0,//图形阴影的模糊大小
|
||||
opacity: 1//图形透明度
|
||||
},
|
||||
data: [40, 80, 20, 120, 140, 50]
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
unit: '年销量',
|
||||
type: 'line',
|
||||
dataType: 'value',
|
||||
color: '#3ba272',
|
||||
label: '华东',
|
||||
symbol: "circle",
|
||||
symbolSize: 8,
|
||||
showSymbol: true,
|
||||
lineStyle: {
|
||||
shadowColor: '',//阴影颜色
|
||||
shadowBlur: 0,//图形阴影的模糊大小
|
||||
opacity: 1
|
||||
},
|
||||
data: [140, 180, 120, 40, 50, 150]
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
unit: '年销量',
|
||||
type: 'line',
|
||||
dataType: 'value',
|
||||
color: '#5470c6',
|
||||
label: '华南',
|
||||
symbol: "rect",
|
||||
symbolSize: 8,
|
||||
showSymbol: true,
|
||||
lineStyle: {
|
||||
shadowColor: '',//阴影颜色
|
||||
shadowBlur: 0,//图形阴影的模糊大小
|
||||
opacity: 1
|
||||
},
|
||||
data: [110, 143, 68, 90, 120, 130]
|
||||
}
|
||||
])
|
||||
const barChartsItem = ref([
|
||||
{
|
||||
id: 1,
|
||||
unit: '年份',
|
||||
type: '',
|
||||
dataType: 'key',
|
||||
color: '',
|
||||
label: '年份',
|
||||
showBackground: false,
|
||||
backgroundStyle: {
|
||||
color: '',
|
||||
borderWidth: 0,
|
||||
borderColor: '',
|
||||
borderType: 'solid',
|
||||
},
|
||||
data: ['2013', '2014', '2015', '2016', '2017', '2018']
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
unit: '销售金额',
|
||||
type: 'bar',
|
||||
dataType: 'value',
|
||||
color: '#9a60b4',//图形颜色
|
||||
label: '王五',
|
||||
showBackground: true,//是否显示柱条的背景色
|
||||
backgroundStyle: {
|
||||
color: '#e5e2e2',//柱条的颜色
|
||||
borderWidth: 0,//柱条的描边宽度,默认不描边。
|
||||
borderColor: '#000',//柱条的描边颜色
|
||||
borderType: 'dotted',//柱条的描边类型,默认为实线,支持 'dashed', 'dotted'
|
||||
},
|
||||
data: [40, 80, 20, 120, 140, 50]
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
unit: '销售金额',
|
||||
type: 'bar',
|
||||
dataType: 'value',
|
||||
color: '#3ba272',
|
||||
label: '李四',
|
||||
showBackground: true,
|
||||
backgroundStyle: {
|
||||
color: '#e5e2e2',
|
||||
borderWidth: 0,
|
||||
borderColor: '#000',
|
||||
borderType: 'dashed',
|
||||
},
|
||||
data: [140, 180, 120, 40, 50, 150]
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
unit: '销售金额',
|
||||
type: 'bar',
|
||||
dataType: 'value',
|
||||
color: '#2644a4',
|
||||
label: '张三',
|
||||
showBackground: true,
|
||||
backgroundStyle: {
|
||||
color: '#e5e2e2',
|
||||
borderWidth: 0,
|
||||
borderColor: '#000',
|
||||
borderType: 'solid',
|
||||
},
|
||||
data: [110, 143, 68, 90, 120, 130]
|
||||
}
|
||||
])
|
||||
const pieChartsItem = ref([
|
||||
{id: 1, label: '京东', dataType: 'value', value: 335},
|
||||
{id: 2, label: '菜鸟', dataType: 'value', value: 310},
|
||||
{id: 3, label: '总部', dataType: 'value', value: 234},
|
||||
{id: 4, label: '小电商', dataType: 'value', value: 135},
|
||||
])
|
||||
const radarChartsItem = ref([
|
||||
{label: 'Allocated Budget', dataType: 'value', data: [4200, 3000, 20000, 35000, 50000, 18000]},
|
||||
{label: 'Actual Spending', dataType: 'value', data: [5000, 14000, 28000, 26000, 42000, 21000]},
|
||||
])
|
||||
//定义好echarts的配置数据
|
||||
let initInfo = reactive({
|
||||
xValueAxis: [],
|
||||
yValueAxis: [],
|
||||
//echarts配置数据
|
||||
echartsOptions: {
|
||||
//图例
|
||||
legend: {
|
||||
data: [],
|
||||
selected: {},
|
||||
selectedMode: false
|
||||
},
|
||||
//离容器四侧的距离
|
||||
grid: {
|
||||
left: 40, // 左边距
|
||||
right: 60, // 右边距
|
||||
top: 40, // 顶边距
|
||||
bottom: 20, // 底边距
|
||||
// containLabel: true,
|
||||
},
|
||||
//提示框组件
|
||||
tooltip: {
|
||||
show: true,
|
||||
trigger: 'axis'
|
||||
},
|
||||
//工具栏
|
||||
// toolbox: {
|
||||
// feature: {
|
||||
// //重置按钮显示
|
||||
// restore: {
|
||||
// show: true,
|
||||
// title: '重置'
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
//X轴
|
||||
xAxis: {
|
||||
name: '',
|
||||
type: 'category',
|
||||
data: [],
|
||||
axisLine: {
|
||||
show: true
|
||||
}
|
||||
},
|
||||
//Y轴
|
||||
yAxis: {
|
||||
name: '',
|
||||
type: 'value',
|
||||
data: [],
|
||||
axisLine: {
|
||||
show: true
|
||||
}
|
||||
},
|
||||
radar: {
|
||||
// shape: 'circle',
|
||||
},
|
||||
//配置项
|
||||
series: []
|
||||
}
|
||||
})
|
||||
const indicator= ref([
|
||||
{ name: 'Sales', max: 6500 },
|
||||
{ name: 'Administration', max: 16000 },
|
||||
{ name: 'Information Technology', max: 30000 },
|
||||
{ name: 'Customer Support', max: 38000 },
|
||||
{ name: 'Development', max: 52000 },
|
||||
{ name: 'Marketing', max: 25000 }
|
||||
])
|
||||
//获取到拖拽后的数据
|
||||
const getFinalInfo = (val) => {
|
||||
// console.log('父组件获取最终数据', val)
|
||||
if (val !== undefined) {
|
||||
initInfo = val
|
||||
}
|
||||
}
|
||||
getFinalInfo()
|
||||
</script>
|
||||
Reference in New Issue
Block a user