修改树组件配置

master
suixy 2 days ago
parent ef9d89936f
commit 3db6ef7094

@ -190,7 +190,7 @@
<!-- </template>-->
<!-- <div class="moduleText">设备数据</div>-->
<!-- </el-card>-->
<template v-for="i in customData.slice(17,customData.length)">
<template v-for="i in customData">
<el-card class="moduleCard" shadow="never" :draggable="true"
@dragstart="onDragStart($event, 'customData',i)"
:style="{display:'inline-block',margin:'0 4px 4px 0'}"
@ -714,6 +714,10 @@
@click="selectTabs(1)">
样式设置
</div>
<div v-if="Object.keys(nodeDataForm).length>0" class="tab" :class="{active : tabs === 2}"
@click="selectTabs(2)">
数据
</div>
</div>
<div class="tabItems">
<div class="tabItem" v-if=" tabs === 0">
@ -1224,6 +1228,9 @@
<el-form-item label="提示框" v-if="Object.keys(nodeAttrForm).includes('tooltip')">
<el-switch v-model="nodeAttrForm.tooltip" active-text="" inactive-text="" />
</el-form-item>
<el-form-item label="图表方向" v-if="Object.keys(nodeAttrForm).includes('isHorizontal')">
<el-switch v-model="nodeAttrForm.isHorizontal" active-text="" inactive-text="" />
</el-form-item>
<el-form-item label="图例" v-if="Object.keys(nodeAttrForm).includes('legend')">
<el-switch v-model="nodeAttrForm.legend" active-text="" inactive-text="" />
</el-form-item>
@ -1391,6 +1398,42 @@
</el-collapse>
</el-form>
</div>
<div class="tabItem" v-if="Object.keys(nodeDataForm).length>0 && tabs === 2">
<div v-for=" (i,k) in nodeAttrForm.request" style="margin-bottom: 12px;">
<el-form :model="i.data" label-width="auto" style="max-width: 600px" labelWidth="120px">
<el-form-item label="使用数据源">
<el-select
v-model="i.dataSource"
placeholder="请选择"
style="width: 200px"
@change="(e)=>nodeAttrForm.request[k].mapList = customData.find(v=>v.id === e).outputData.map(v=>{return{originalField:v.fieldOne}})"
>
<el-option
:label="option.name"
v-for="option in customData"
:value="option.id"
>
</el-option>
</el-select>
</el-form-item>
<div style="width: 100%;text-align: center;font-size: 14px;color: #fff;font-weight: 600;margin: 12px 0">
字段映射
</div>
<el-table :data="i.mapList" style="width: 100%" max-height="500">
<el-table-column label="原字段" prop="originalField">
</el-table-column>
<el-table-column label="映射字段">
<template #default="scope">
<el-input v-model="scope.row.field" style="width: 100%" />
</template>
</el-table-column>
</el-table>
</el-form>
</div>
<div style="width: 100%;text-align: center;margin-top: 12px">
<el-button type="primary" plain style="text-align: center" @click="addRequest"></el-button>
</div>
</div>
</div>
</div>
<el-dialog v-model="pageSettingVisible" title="页面设置" width="500">
@ -1685,8 +1728,9 @@
</el-dialog>
<el-dialog v-model="treeOptionsVisible" title="树设置" fullscreen>
<TreeOption :data="nodeAttrForm.treeOptions" :level="nodeAttrForm.level" key="1"/>
<el-dialog v-model="treeOptionsVisible" title="树设置" fullscreen :before-close="closeTreeOption">
<TreeOption v-if="treeOptionsVisible" ref="treeOptionRef" :data="nodeAttrForm.treeOptions"
:level="nodeAttrForm.level" />
</el-dialog>
</div>
</template>
@ -1788,6 +1832,7 @@ const headers = ref(globalHeaders());
const { onDragStart, onDrop, onDragOver } = tool();
const router = useRouter();
const key = ref(0);
const treeOptionRef = ref();
const isSnapToGrid = ref(false);
const toggleSnapToGrid = (e) => {
@ -1833,6 +1878,7 @@ onMounted(async () => {
.then((res) => {
customData.value = res.rows.map(e => {
return {
id: e.dataSourceId,
name: e.dataSourceName,
url: e.requestUrl,
method: e.requestMethod,
@ -1971,6 +2017,7 @@ const nodes = ref([{
data: {}
}]);
const edges = ref([]);
const requestDatas = ref([]);
const customData = ref([]);
// const customBoard = ref([]);
const cellOption = ref({});
@ -2012,23 +2059,13 @@ const logEvent = async (eventname, event) => {
key.value += 1;
} else {
nodeAttrForm.value = {};
tabs, value = 0;
tabs.value = 0;
nodeDataForm.value = {};
}
break;
case 'contextmenu':
}
};
const resize = (e, id) => {
nodes.value.forEach((item) => {
if (item.selected && item.id !== id) {
item.dimensions = {
width: e.params.width,
height: e.params.height
};
}
});
};
const getInputData = (e) => {
let outputData = {};
let nodeIds = edges.value.map(v => {
@ -2172,20 +2209,6 @@ const save = () => {
// };
// })));
};
const clear = () => {
nodes.value = [{
id: `area_${uuidv4().replaceAll('-', '_')}`,
name: 'area',
type: 'area',
position: {
x: 0,
y: 0
},
data: {}
}];
edges.value = [];
};
const pageBgUploadSuccess = (res) => {
if (res.code === 200) {
pageSettingForm.value.bg = res.data.url;
@ -2316,7 +2339,35 @@ const setText = (value, row, formula) => {
return formulaFun(row, formula);
}
};
const closeTreeOption = (done) => {
console.log(treeOptionRef.value.getNodes());
nodeAttrForm.value.treeOptions = (treeOptionRef.value.getNodes() || []).map(e => {
return {
id: e.id,
parentNode: e.parentNode || '',
position: e.position,
type: e.type,
data: e.data,
dimensions: e.dimensions,
extent: e.extent || '',
draggable: e.draggable
};
});
done();
};
const addRequest = (e) => {
if (nodeAttrForm.value.request) {
nodeAttrForm.value.request.push({
dataSource: '',
mapList: []
});
} else {
nodeAttrForm.value.request = [{
dataSource: '',
mapList: []
}];
}
};
</script>
<style scoped lang="less">

@ -11,7 +11,7 @@
</div>
</div>
<Handle :id="`${props.id}.-l`" type="target" :position="Position.Left" />
<Handle :id="`${props.id}.-r`" type="target" :position="Position.Right" />
<Handle :id="`${props.id}.-r`" type="source" :position="Position.Right" />
</div>
</template>
<script setup>

@ -1,34 +1,34 @@
<template>
<div style="height: calc(90vh - 111px - 30px);position: relative;">
<div style="width:100px;height: calc(90vh - 111px - 30px);overflow-y: auto">
<el-card class="moduleCard" shadow="never" :draggable="true"
@dragstart="onDragStart($event, 'itemNode',checkNodeId)" :style="{display:'inline-block',margin:'0 4px 4px 0'}"
@dragstart="onDragStart($event, 'text',checkNodeId)"
:style="{display:'inline-block',margin:'0 4px 4px 0'}"
:body-style="{padding:'4px 0'}">
<template #header>
<div style="width: 100%;height: 100%;text-align: center">
<svg t="1768964556223" class="icon" viewBox="0 0 1024 1024" version="1.1"
xmlns="http://www.w3.org/2000/svg" p-id="4878" width="30" height="30">
<path
d="M554.666667 682.666667h85.333333v128h-213.333333v-128h85.333333v-128H256v128h85.333333v128H128v-128h85.333333v-170.666667h298.666667V384h-85.333333V256h213.333333v128h-85.333333v128h298.666666v170.666667h85.333334v128h-213.333334v-128h85.333334v-128h-256v128z m42.666666-384h-128v42.666666h128V298.666667zM298.666667 725.333333H170.666667v42.666667h128v-42.666667z m597.333333 0h-128v42.666667h128v-42.666667z m-298.666667 0h-128v42.666667h128v-42.666667z"
fill="#444444" p-id="4879"></path>
</svg>
</div>
</template>
<div class="moduleText">文字</div>
</el-card>
<div class="content" @drop="onDrop">
<el-card class="moduleCard" shadow="never" :draggable="true"
@dragstart="onDragStart($event, 'text',checkNodeId)"
:style="{display:'inline-block',margin:'0 4px 4px 0'}"
:body-style="{padding:'4px 0'}">
<div class="moduleText">图片</div>
</el-card>
</div>
<div class="content" @drop="onDrop" ref="contentRef">
<VueFlow
id="flowB"
:min-zoom="0.01"
:zoomOnScroll="false"
:panOnDrag="false"
ref="flowRef1"
v-model:nodes="nodes"
v-model:edges="edges"
:zoom-on-double-click="false"
fit-view-on-init
@dragover="onDragOver"
default-marker-color="#409EFF"
@connect="logEvent('connect', $event)"
@node-click="logEvent('click', $event)"
@node-double-click="logEvent('dbclick', $event)"
@pane-click="logEvent('paneClick', $event)"
@node-drag-start="logEvent('nodeDrag', $event)"
@node-contextMenu="logEvent('contextmenu', $event)"
@ -43,7 +43,7 @@
</div>
</template>
<script setup>
import { defineEmits, defineProps, ref } from 'vue';
import { defineEmits, defineProps, ref, defineExpose } from 'vue';
import { MarkerType, useVueFlow, VueFlow } from '@vue-flow/core';
import tool from './tool.js';
import { Background } from '@vue-flow/background';
@ -59,6 +59,7 @@ const {
addNodes
} = useVueFlow({ id: 'flowB' });
const flowRef1 = ref();
const contentRef = ref();
const props = defineProps({
data: {
@ -72,7 +73,7 @@ const props = defineProps({
});
const nodes = ref([]);
const edges = ref([]);
const checkNodeId = ref('')
const checkNodeId = ref('');
const logEvent = async (eventname, event) => {
switch (eventname) {
case 'connect':
@ -92,13 +93,16 @@ const logEvent = async (eventname, event) => {
case 'paneClick':
break;
case 'click':
console.log(event.node)
if(event.node.id.startsWith("root")){
checkNodeId.value = event.node.id
}else{
checkNodeId.value = ''
if (event.node.id.startsWith('root')) {
checkNodeId.value = event.node.id;
} else {
checkNodeId.value = '';
}
break;
case 'dbclick':
console.log(event.node);
break;
case 'nodeDrag':
break;
case 'contextmenu':
@ -127,18 +131,31 @@ onMounted(async () => {
await nextTick();
nodes.value = [];
await nextTick();
console.log(props.level);
Array(props.level).fill(0).forEach((e, index) => {
let x = 50;
for (let i = 0; i < index; i++) {
x += (props.data.find(e => e.id === `root_${i}`)?.dimensions.width || 300);
x += 50;
}
addNodes({
id: `root_${index}`,
type: 'itemNode',
draggable: false,
position: {
x: index * ((300) + (50)),
y: 200
x: x,
y: (contentRef.value.offsetHeight / 2) - (props.data.find(e => e.id === `root_${index}`)?.dimensions.height || 200) / 2
},
dimensions: { width: 300, height: 200 },
data: {}
dimensions: {
width: props.data.find(e => e.id === `root_${index}`)?.dimensions.width || 300,
height: props.data.find(e => e.id === `root_${index}`)?.dimensions.height || 200
},
data: props.data.find(e => e.id === `root_${index}`)?.data || {}
});
props.data.forEach(e => {
if (e.parentNode === `root_${index}`) {
addNodes(e);
}
});
if (index > 0) {
addEdges({
@ -154,6 +171,14 @@ onMounted(async () => {
}
});
});
function getNodes() {
return nodes.value;
}
defineExpose({
getNodes
});
</script>
<style lang="less" scoped>
.levelItem {

@ -13,7 +13,9 @@ const getNodeSize = (e) => {
const tool = () => {
const nodeType = ref('');
const checkNodeId = ref('');
const { addNodes, screenToFlowCoordinate, onNodesInitialized, updateNode, getNodes,nodes } = useVueFlow({ id: 'flowB' });
const {
addNodes, screenToFlowCoordinate, onNodesInitialized, updateNode, getNodes, nodes
} = useVueFlow({ id: 'flowB' });
const onDragStart = (event, type, data) => {
if (event.dataTransfer) {
event.dataTransfer.setData('application/vueflow', type);
@ -29,48 +31,38 @@ const tool = () => {
document.removeEventListener('drop', onDragEnd);
};
const onDrop = (event) => {
const dimensions = getNodeSize();
const position = screenToFlowCoordinate({
x: event.clientX, y: event.clientY
});
const nodeId = getId();
const newNode = {
id: nodeId,
draggable: true,
type: nodeType.value,
dimensions,
position,
data: { options: {} }
};
if (checkNodeId.value) {
const parentNode = nodes.value.find(n => n.id === checkNodeId.value);
console.log(parentNode);
const parentPos = parentNode.position;
const parentSize = parentNode.dimensions;
const dimensions = getNodeSize();
const position = screenToFlowCoordinate({
x: event.clientX, y: event.clientY
});
const nodeId = getId();
const newNode = {
id: nodeId, draggable: true, type: nodeType.value, dimensions, position, data: { options: {} }
};
const parentNode = nodes.value.find(n => n.id === checkNodeId.value);
const parentPos = parentNode.position;
// 转成父节点坐标
const relPosition = {
x: position.x - parentPos.x,
y: position.y - parentPos.y
x: Math.max(position.x - parentPos.x, 0), y: Math.max(position.y - parentPos.y, 0)
};
newNode.parentNode = checkNodeId.value;
newNode.extent = 'parent';
newNode.position = relPosition;
const { off } = onNodesInitialized(() => {
updateNode(nodeId, (node) => ({
position: { x: node.position.x - node.dimensions.width / 2, y: node.position.y - node.dimensions.height / 2 }
}));
off();
});
addNodes(newNode);
}
console.log(newNode);
const { off } = onNodesInitialized(() => {
updateNode(nodeId, (node) => ({
position: { x: node.position.x - node.dimensions.width / 2, y: node.position.y - node.dimensions.height / 2 }
}));
off();
});
addNodes(newNode);
};
const onDragOver = (event) => {

@ -1,7 +1,8 @@
<template>
<div
:style="{width:props.dimensions.width*props.ratioWidth+'px',height:props.dimensions.height*props.ratioHeight+'px'}">
<NodeResizer @resizeEnd="(e) => $emit('resize', e)" color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
<NodeResizer @resizeEnd="(e) => $emit('resize', e)" color="#fff"
v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
<div class="custom-node"
:style="{width:props.dimensions.width*props.ratioWidth+'px',height:props.dimensions.height*props.ratioHeight+'px',pointerEvents:props.isView?'auto': 'none'}">
@ -208,12 +209,12 @@ const getOption = () => {
title: {
text: props.data.options.title || ''
},
legend: {
show: props.data?.options?.legend || false
},
tooltip: {
show: props.data?.options?.tooltip || false
},
legend: {
show: props.data?.options?.legend || false
},
tooltip: {
show: props.data?.options?.tooltip || false
},
grid: {
top: props.data?.options?.gridTop + '%' || '20%',
left: props.data?.options?.gridLeft + '%' || '20%',
@ -223,8 +224,9 @@ const getOption = () => {
xAxis: [
{
name: props.data?.options?.xName || '',
type: props.data?.options?.isHorizontal ? 'value' : 'category',
nameLocation: props.data?.options?.xNameLocation || 'end',
boundaryGap: props.data?.options?.boundaryGap || false,
boundaryGap: true,
axisLine: {
show: props.data?.options?.xAxisLineShow || false,
lineStyle: {
@ -260,6 +262,7 @@ const getOption = () => {
yAxis: [
{
name: props.data?.options?.yName || '',
type: props.data?.options?.isHorizontal ? 'category' : 'value',
nameLocation: props.data?.options?.yNameLocation || 'end',
axisLine: {
show: props.data?.options?.yAxisLineShow || false,
@ -293,11 +296,14 @@ const getOption = () => {
}
}
],
series: [
{
lineStyle: {
color: props.data?.options?.seriesColor || colorList[0]
}
series: [
{
lineStyle: {
color: props.data?.options?.seriesColor || colorList[0]
},
label: {
position: props.data?.options?.isHorizontal ? 'right' : 'top'
}
}
]
}

@ -1,7 +1,8 @@
<template>
<div
:style="{width:props.dimensions.width*props.ratioWidth+'px',height:props.dimensions.height*props.ratioHeight+'px'}">
<NodeResizer @resizeEnd="(e) => $emit('resize', e)" color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
<NodeResizer @resizeEnd="(e) => $emit('resize', e)" color="#fff"
v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
<div class="custom-node"
:style="{width:props.dimensions.width*props.ratioWidth+'px',height:props.dimensions.height*props.ratioHeight+'px',pointerEvents:props.isView?'auto': 'none'}">
@ -71,7 +72,7 @@ const defaultOption = {
top: '5%'
},
legend: {
show:props.data?.options?.legend||false,
show: props.data?.options?.legend || false,
icon: 'circle',
top: '5%',
right: '5%',
@ -82,7 +83,7 @@ const defaultOption = {
}
},
tooltip: {
show:props.data?.options?.tooltip||false,
show: props.data?.options?.tooltip || false,
trigger: 'axis',
axisPointer: {
label: {
@ -114,7 +115,7 @@ const defaultOption = {
{
name: props.data?.options?.xName || '',
nameLocation: props.data?.options?.xNameLocation || 'end',
type: 'category',
type: props.data?.options?.isHorizontal ?'value':'category',
boundaryGap: props.data?.options?.boundaryGap || false,
axisLine: {
show: props.data?.options?.xAxisLineShow || false,
@ -152,7 +153,7 @@ const defaultOption = {
{
name: props.data?.options?.yName || '',
nameLocation: props.data?.options?.yNameLocation || 'end',
type: 'value',
type: props.data?.options?.isHorizontal ? 'category' : 'value',
axisLine: {
show: props.data?.options?.yAxisLineShow || false,
lineStyle: {
@ -182,7 +183,7 @@ const defaultOption = {
color: props.data?.options?.yAxisSplitLineColor || '#DCE2E8',
type: props.data?.options?.yAxisSplitLineType || 'solid'
}
},
}
}
],
series: [
@ -216,10 +217,10 @@ const getOption = () => {
text: props.data.options.title || ''
},
legend: {
show: props.data?.options?.legend || false,
show: props.data?.options?.legend || false
},
tooltip: {
show:props.data?.options?.tooltip||false,
show: props.data?.options?.tooltip || false
},
grid: {
top: props.data?.options?.gridTop + '%' || '20%',
@ -306,8 +307,8 @@ const getOption = () => {
symbolSize: props.data?.options?.lineSymbolSize || 5,
symbol: props.data?.options?.lineSymbolType || 'circle',
lineStyle: {
color: props.data?.options?.seriesColor || colorList.value[0],
},
color: props.data?.options?.seriesColor || colorList.value[0]
}
}
]
};

@ -60,7 +60,7 @@ const getOption = (e) => {
lineSymbolType: 'circle',
seriesColor: '#9E87FF',
tooltip: true,
legend: true
legend: true,
};
} else if (e === 'bar' || e === 'multiBars') {
return {
@ -108,7 +108,8 @@ const getOption = (e) => {
yAxisSplitLineType: 'solid',
seriesColor: '#9E87FF',
tooltip: true,
legend: true
legend: true,
isHorizontal:false,
};
} else if (e === 'backgroundBar') {
return {
@ -157,7 +158,8 @@ const getOption = (e) => {
tooltip: true,
legend: true,
seriesColor: '#9E87FF',
backgroundColor: 'rgba(180, 180, 180, 0.2)'
backgroundColor: 'rgba(180, 180, 180, 0.2)',
isHorizontal:false,
};
} else if (e === 'curve' || e === 'multiCurves') {
return {

Loading…
Cancel
Save