perf: improve flowChart logic
@@ -32,5 +32,6 @@ export function generateModifyVars(dark = false) {
|
||||
'font-size-base': '14px', // Main font size
|
||||
'border-radius-base': '2px', // Component/float fillet
|
||||
'link-color': primary, // Link color
|
||||
'content-background': '#fafafa', // Link color
|
||||
};
|
||||
}
|
||||
|
@@ -53,6 +53,7 @@ export function configThemePlugin(isBuild: boolean): Plugin[] {
|
||||
'border-color-base': '#303030',
|
||||
// 'border-color-split': '#30363d',
|
||||
'item-active-bg': '#111b26',
|
||||
'content-background': '#ffffff0a', // Link color
|
||||
},
|
||||
}),
|
||||
];
|
||||
|
@@ -101,7 +101,7 @@
|
||||
"prettier": "^2.2.1",
|
||||
"pretty-quick": "^3.1.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"rollup-plugin-visualizer": "5.3.6",
|
||||
"rollup-plugin-visualizer": "5.3.4",
|
||||
"stylelint": "^13.12.0",
|
||||
"stylelint-config-prettier": "^8.0.2",
|
||||
"stylelint-config-standard": "^21.0.0",
|
||||
|
@@ -1,17 +1,10 @@
|
||||
import { App } from 'vue';
|
||||
import control from './src/Control.vue';
|
||||
import nodePanel from './src/NodePanel.vue';
|
||||
import dataDialog from './src/DataDialog.vue';
|
||||
import flowChart from './src/index.vue';
|
||||
|
||||
export const Control = Object.assign(control, {
|
||||
export const FlowChart = Object.assign(flowChart, {
|
||||
install(app: App) {
|
||||
app.component(control.name, control);
|
||||
},
|
||||
});
|
||||
|
||||
export const NodePanel = Object.assign(nodePanel, {
|
||||
install(app: App) {
|
||||
app.component(nodePanel.name, nodePanel);
|
||||
app.component(flowChart.name, flowChart);
|
||||
},
|
||||
});
|
||||
|
||||
|
@@ -1,150 +0,0 @@
|
||||
<template>
|
||||
<div class="control-container">
|
||||
<!-- 功能按钮 -->
|
||||
<ul>
|
||||
<li
|
||||
v-for="(item, key) in titleLists"
|
||||
:key="key"
|
||||
:title="item.text"
|
||||
@mouseenter.prevent="onEnter(key)"
|
||||
@mouseleave.prevent="focusIndex = -1"
|
||||
>
|
||||
<a-button
|
||||
:disabled="item.disabled"
|
||||
:style="{ cursor: item.disabled === false ? 'pointer' : 'not-allowed' }"
|
||||
@click="onControl(item, key)"
|
||||
>
|
||||
<span :class="'iconfont ' + item.icon"></span>
|
||||
<p>{{ item.text }}</p>
|
||||
</a-button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, unref, onMounted } from 'vue';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'Control',
|
||||
props: {
|
||||
lf: Object || String,
|
||||
catTurboData: Boolean,
|
||||
},
|
||||
emits: ['catData'],
|
||||
setup(props, { emit }) {
|
||||
let focusIndex = ref(-1);
|
||||
let titleLists = ref([
|
||||
{
|
||||
icon: 'icon-zoom-out-hs',
|
||||
text: '缩小',
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
icon: 'icon-enlarge-hs',
|
||||
text: '放大',
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
icon: 'icon-full-screen-hs',
|
||||
text: '适应',
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
icon: 'icon-previous-hs',
|
||||
text: '上一步',
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
icon: 'icon-next-step-hs',
|
||||
text: '下一步',
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
icon: 'icon-download-hs',
|
||||
text: '下载图片',
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
icon: 'icon-watch-hs',
|
||||
text: '查看数据',
|
||||
disabled: false,
|
||||
},
|
||||
]);
|
||||
|
||||
const onControl = (item, key) => {
|
||||
['zoom', 'zoom', 'resetZoom', 'undo', 'redo', 'getSnapshot'].forEach((v, i) => {
|
||||
let domControl = props.lf;
|
||||
if (key === 1) {
|
||||
domControl.zoom(true);
|
||||
}
|
||||
if (key === 6) {
|
||||
emit('catData');
|
||||
}
|
||||
if (key === i) {
|
||||
domControl[v]();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const onEnter = (key) => {
|
||||
focusIndex.value = key;
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
props.lf.on('history:change', ({ data: { undoAble, redoAble } }) => {
|
||||
unref(titleLists)[3].disabled = !undoAble;
|
||||
unref(titleLists)[4].disabled = !redoAble;
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
focusIndex,
|
||||
titleLists,
|
||||
onControl,
|
||||
onEnter,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@import './assets/iconfont/iconfont.css';
|
||||
|
||||
.control-container {
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
background: hsla(0, 0%, 100%, 0.8);
|
||||
box-shadow: 0 1px 4px rgb(0 0 0 / 30%);
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
font-size: 25px;
|
||||
}
|
||||
|
||||
.control-container p {
|
||||
margin: 0;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.control-container ul {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
.control-container ul li {
|
||||
width: 60px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.control-container ul li button {
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
padding: 0;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
outline: none;
|
||||
}
|
||||
</style>
|
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<vue-json-pretty :path="'res'" :deep="3" :showLength="true" :data="graphData" />
|
||||
<vue-json-pretty :path="'res'" :deep="3" :showLength="true" :data="data" />
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
@@ -12,7 +12,7 @@
|
||||
VueJsonPretty,
|
||||
},
|
||||
props: {
|
||||
graphData: Object,
|
||||
data: Object,
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
156
src/components/FlowChart/src/FlowChartToolbar.vue
Normal file
@@ -0,0 +1,156 @@
|
||||
<template>
|
||||
<div :class="`${prefixCls}-toolbar`" class="flex items-center px-2 py-1">
|
||||
<template v-for="(item, index) in toolbarItemList" :key="item.type || index">
|
||||
<Tooltip placement="bottom" v-bind="item.disabled ? { visible: false } : {}">
|
||||
<template #title>{{ item.tooltip }}</template>
|
||||
<span :class="`${prefixCls}-toolbar__icon`" v-if="item.icon" @click="onControl(item)">
|
||||
<Icon
|
||||
:icon="item.icon"
|
||||
:class="item.disabled ? 'cursor-not-allowed disabeld' : 'cursor-pointer'"
|
||||
/>
|
||||
</span>
|
||||
</Tooltip>
|
||||
<Divider v-if="item.separate" type="vertical" />
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import type { ToolbarConfig } from './types';
|
||||
|
||||
import { defineComponent, ref, onUnmounted, unref, nextTick, watchEffect } from 'vue';
|
||||
import { Divider, Tooltip } from 'ant-design-vue';
|
||||
import { Icon } from '/@/components/Icon';
|
||||
|
||||
import { useFlowChartContext } from './useFlowContext';
|
||||
import { ToolbarTypeEnum } from './enum';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'FlowChartToolbar',
|
||||
components: { Icon, Divider, Tooltip },
|
||||
props: {
|
||||
prefixCls: String,
|
||||
},
|
||||
setup(_, { emit }) {
|
||||
const toolbarItemList = ref<ToolbarConfig[]>([
|
||||
{
|
||||
type: ToolbarTypeEnum.ZOOM_IN,
|
||||
icon: 'codicon:zoom-out',
|
||||
tooltip: '缩小',
|
||||
},
|
||||
{
|
||||
type: ToolbarTypeEnum.ZOOM_OUT,
|
||||
icon: 'codicon:zoom-in',
|
||||
tooltip: '放大',
|
||||
},
|
||||
{
|
||||
type: ToolbarTypeEnum.RESET_ZOOM,
|
||||
icon: 'codicon:screen-normal',
|
||||
tooltip: '重置比例',
|
||||
},
|
||||
{ separate: true },
|
||||
{
|
||||
type: ToolbarTypeEnum.UNDO,
|
||||
icon: 'ion:arrow-undo-outline',
|
||||
tooltip: '后退',
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
type: ToolbarTypeEnum.REDO,
|
||||
icon: 'ion:arrow-redo-outline',
|
||||
tooltip: '前进',
|
||||
disabled: true,
|
||||
},
|
||||
{ separate: true },
|
||||
{
|
||||
type: ToolbarTypeEnum.SNAPSHOT,
|
||||
icon: 'ion:download-outline',
|
||||
tooltip: '下载',
|
||||
},
|
||||
{
|
||||
type: ToolbarTypeEnum.VIEW_DATA,
|
||||
icon: 'carbon:document-view',
|
||||
tooltip: '查看数据',
|
||||
},
|
||||
]);
|
||||
|
||||
const { logicFlow } = useFlowChartContext();
|
||||
|
||||
function onHistoryChange({ data: { undoAble, redoAble } }) {
|
||||
const itemsList = unref(toolbarItemList);
|
||||
const undoIndex = itemsList.findIndex((item) => item.type === ToolbarTypeEnum.UNDO);
|
||||
const redoIndex = itemsList.findIndex((item) => item.type === ToolbarTypeEnum.REDO);
|
||||
if (undoIndex !== -1) {
|
||||
unref(toolbarItemList)[undoIndex].disabled = !undoAble;
|
||||
}
|
||||
if (redoIndex !== -1) {
|
||||
unref(toolbarItemList)[redoIndex].disabled = !redoAble;
|
||||
}
|
||||
}
|
||||
|
||||
const onControl = (item) => {
|
||||
const lf = unref(logicFlow);
|
||||
if (!lf) {
|
||||
return;
|
||||
}
|
||||
switch (item.type) {
|
||||
case ToolbarTypeEnum.ZOOM_IN:
|
||||
lf.zoom();
|
||||
break;
|
||||
case ToolbarTypeEnum.ZOOM_OUT:
|
||||
lf.zoom(true);
|
||||
break;
|
||||
case ToolbarTypeEnum.RESET_ZOOM:
|
||||
lf.resetZoom();
|
||||
break;
|
||||
case ToolbarTypeEnum.UNDO:
|
||||
lf.undo();
|
||||
break;
|
||||
case ToolbarTypeEnum.REDO:
|
||||
lf.redo();
|
||||
break;
|
||||
case ToolbarTypeEnum.SNAPSHOT:
|
||||
lf.getSnapshot();
|
||||
break;
|
||||
case ToolbarTypeEnum.VIEW_DATA:
|
||||
emit('catData');
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
watchEffect(async () => {
|
||||
if (unref(logicFlow)) {
|
||||
await nextTick();
|
||||
unref(logicFlow)?.on('history:change', onHistoryChange);
|
||||
}
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
unref(logicFlow)?.off('history:change', onHistoryChange);
|
||||
});
|
||||
return { toolbarItemList, onControl };
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
@prefix-cls: ~'@{namespace}-flow-chart-toolbar';
|
||||
|
||||
.@{prefix-cls} {
|
||||
height: 36px;
|
||||
background: @content-background;
|
||||
border-bottom: 1px solid @border-color-base;
|
||||
|
||||
.disabeld {
|
||||
color: @disabled-color;
|
||||
}
|
||||
|
||||
&__icon {
|
||||
display: inline-block;
|
||||
padding: 2px 4px;
|
||||
margin-right: 10px;
|
||||
|
||||
&:hover {
|
||||
color: @primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@@ -1,145 +0,0 @@
|
||||
<template>
|
||||
<!-- 左侧bpmn元素选择器 -->
|
||||
<div class="node-panel">
|
||||
<div
|
||||
class="node-item"
|
||||
v-for="item in nodeList"
|
||||
:key="item.text"
|
||||
@mousedown="nodeDragNode(item)"
|
||||
>
|
||||
<div class="node-item-icon" :class="item.class">
|
||||
<div v-if="item.type === 'user' || item.type === 'time'" class="shape"></div>
|
||||
</div>
|
||||
<span class="node-label">{{ item.text }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, unref } from 'vue';
|
||||
export default defineComponent({
|
||||
name: 'NodePanel',
|
||||
props: {
|
||||
lf: Object,
|
||||
nodeList: Array,
|
||||
},
|
||||
setup(props) {
|
||||
let node = ref({
|
||||
type: 'rect',
|
||||
property: {
|
||||
a: 'efrwe',
|
||||
b: 'wewe',
|
||||
},
|
||||
});
|
||||
let properties = ref({
|
||||
a: 'efrwe',
|
||||
b: 'wewe',
|
||||
});
|
||||
|
||||
const nodeDragNode = (item) => {
|
||||
props.lf.dnd.startDrag({
|
||||
type: item.type,
|
||||
properties: unref(properties),
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
node,
|
||||
properties,
|
||||
nodeDragNode,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.node-panel {
|
||||
position: absolute;
|
||||
top: 100px;
|
||||
left: 50px;
|
||||
z-index: 101;
|
||||
width: 70px;
|
||||
padding: 20px 10px;
|
||||
text-align: center;
|
||||
background-color: white;
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 0 10px 1px rgb(228, 224, 219);
|
||||
}
|
||||
|
||||
.node-item {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.node-item-icon {
|
||||
display: flex;
|
||||
height: 30px;
|
||||
background-size: cover;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.node-label {
|
||||
margin-top: 5px;
|
||||
font-size: 12px;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.node-start {
|
||||
background: url('./background/start.png') no-repeat;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.node-rect {
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
.node-user {
|
||||
background: url('./background/user.png') no-repeat;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.node-time {
|
||||
background: url('./background/time.png') no-repeat;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.node-push {
|
||||
background: url('./background/push.png') no-repeat;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.node-download {
|
||||
background: url('./background/download.png') no-repeat;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.node-click {
|
||||
background: url('./background/click.png') no-repeat;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.node-end {
|
||||
background: url('./background/end.png') no-repeat;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.bpmn-start {
|
||||
cursor: grab;
|
||||
background: url('./assets/background/bpmn-start.png') center center no-repeat;
|
||||
}
|
||||
|
||||
.bpmn-end {
|
||||
cursor: grab;
|
||||
background: url('./assets/background/bpmn-end.png') center center no-repeat;
|
||||
}
|
||||
|
||||
.bpmn-user {
|
||||
cursor: grab;
|
||||
background: url('./assets/background/bpmn-user.png') center center no-repeat;
|
||||
}
|
||||
|
||||
.bpmn-exclusiveGateway {
|
||||
cursor: grab;
|
||||
background: url('./assets/background/bpmn-exclusiveGateway.png') center center no-repeat;
|
||||
}
|
||||
</style>
|
@@ -7,95 +7,6 @@ const TurboType = {
|
||||
EXCLUSIVE_GATEWAY: 6,
|
||||
};
|
||||
|
||||
function getTurboType(type) {
|
||||
switch (type) {
|
||||
case 'bpmn:sequenceFlow':
|
||||
return TurboType.SEQUENCE_FLOW;
|
||||
case 'bpmn:startEvent':
|
||||
return TurboType.START_EVENT;
|
||||
case 'bpmn:endEvent':
|
||||
return TurboType.END_EVENT;
|
||||
case 'bpmn:userTask':
|
||||
return TurboType.USER_TASK;
|
||||
case 'bpmn:serviceTask':
|
||||
return TurboType.SERVICE_TASK;
|
||||
case 'bpmn:exclusiveGateway':
|
||||
return TurboType.EXCLUSIVE_GATEWAY;
|
||||
default:
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
function convertNodeToTurboElement(node) {
|
||||
const { id, type, x, y, text = '', properties } = node;
|
||||
return {
|
||||
incoming: [],
|
||||
outgoing: [],
|
||||
dockers: [],
|
||||
type: getTurboType(node.type),
|
||||
properties: {
|
||||
...properties,
|
||||
name: (text && text.value) || '',
|
||||
x: x,
|
||||
y: y,
|
||||
text,
|
||||
logicFlowType: type,
|
||||
},
|
||||
key: id,
|
||||
};
|
||||
}
|
||||
|
||||
function convertEdgeToTurboElement(edge) {
|
||||
const {
|
||||
id,
|
||||
type,
|
||||
sourceNodeId,
|
||||
targetNodeId,
|
||||
startPoint,
|
||||
endPoint,
|
||||
pointsList,
|
||||
text = '',
|
||||
properties,
|
||||
} = edge;
|
||||
return {
|
||||
incoming: [sourceNodeId],
|
||||
outgoing: [targetNodeId],
|
||||
type: getTurboType(type),
|
||||
dockers: [],
|
||||
properties: {
|
||||
...properties,
|
||||
name: (text && text.value) || '',
|
||||
text,
|
||||
startPoint,
|
||||
endPoint,
|
||||
pointsList,
|
||||
logicFlowType: type,
|
||||
},
|
||||
key: id,
|
||||
};
|
||||
}
|
||||
|
||||
export function toTurboData(data) {
|
||||
const nodeMap = new Map();
|
||||
const turboData = {
|
||||
flowElementList: [],
|
||||
};
|
||||
data.nodes.forEach((node) => {
|
||||
const flowElement = convertNodeToTurboElement(node);
|
||||
turboData.flowElementList.push(flowElement);
|
||||
nodeMap.set(node.id, flowElement);
|
||||
});
|
||||
data.edges.forEach((edge) => {
|
||||
const flowElement = convertEdgeToTurboElement(edge);
|
||||
const sourceElement = nodeMap.get(edge.sourceNodeId);
|
||||
sourceElement.outgoing.push(flowElement.key);
|
||||
const targetElement = nodeMap.get(edge.targetNodeId);
|
||||
targetElement.incoming.push(flowElement.key);
|
||||
turboData.flowElementList.push(flowElement);
|
||||
});
|
||||
return turboData;
|
||||
}
|
||||
|
||||
function convertFlowElementToEdge(element) {
|
||||
const { incoming, outgoing, properties, key } = element;
|
||||
const { text, startPoint, endPoint, pointsList, logicFlowType } = properties;
|
||||
@@ -139,8 +50,12 @@ function convertFlowElementToNode(element) {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function toLogicflowData(data) {
|
||||
const lfData = {
|
||||
export function toLogicFlowData(data) {
|
||||
const lfData: {
|
||||
// TODO type
|
||||
nodes: any[];
|
||||
edges: any[];
|
||||
} = {
|
||||
nodes: [],
|
||||
edges: [],
|
||||
};
|
||||
|
Before Width: | Height: | Size: 921 B |
Before Width: | Height: | Size: 830 B |
Before Width: | Height: | Size: 697 B |
Before Width: | Height: | Size: 754 B |
Before Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 40 KiB |
@@ -1,48 +0,0 @@
|
||||
@font-face {
|
||||
font-family: 'iconfont';
|
||||
src: url('iconfont.eot?t=1618544337340'); /* IE9 */
|
||||
src: url('iconfont.eot?t=1618544337340#iefix') format('embedded-opentype'),
|
||||
/* IE6-IE8 */
|
||||
url('data:application/x-font-woff2;charset=utf-8;base64,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')
|
||||
format('woff2'),
|
||||
url('iconfont.woff?t=1618544337340') format('woff'),
|
||||
url('iconfont.ttf?t=1618544337340') format('truetype'),
|
||||
/* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
|
||||
url('iconfont.svg?t=1618544337340#iconfont') format('svg'); /* iOS 4.1- */
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
font-family: 'iconfont' !important;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-full-screen-hs:before {
|
||||
content: '\e656';
|
||||
}
|
||||
|
||||
.icon-watch-hs:before {
|
||||
content: '\e766';
|
||||
}
|
||||
|
||||
.icon-download-hs:before {
|
||||
content: '\e6af';
|
||||
}
|
||||
|
||||
.icon-enlarge-hs:before {
|
||||
content: '\e765';
|
||||
}
|
||||
|
||||
.icon-previous-hs:before {
|
||||
content: '\e84c';
|
||||
}
|
||||
|
||||
.icon-zoom-out-hs:before {
|
||||
content: '\e744';
|
||||
}
|
||||
|
||||
.icon-next-step-hs:before {
|
||||
content: '\e84b';
|
||||
}
|
@@ -1,58 +0,0 @@
|
||||
{
|
||||
"id": "2491438",
|
||||
"name": "liu'c'tu",
|
||||
"font_family": "iconfont",
|
||||
"css_prefix_text": "icon-",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "755619",
|
||||
"name": "自适应图标",
|
||||
"font_class": "full-screen-hs",
|
||||
"unicode": "e656",
|
||||
"unicode_decimal": 58966
|
||||
},
|
||||
{
|
||||
"icon_id": "14445801",
|
||||
"name": "查看",
|
||||
"font_class": "watch-hs",
|
||||
"unicode": "e766",
|
||||
"unicode_decimal": 59238
|
||||
},
|
||||
{
|
||||
"icon_id": "9712640",
|
||||
"name": "下载",
|
||||
"font_class": "download-hs",
|
||||
"unicode": "e6af",
|
||||
"unicode_decimal": 59055
|
||||
},
|
||||
{
|
||||
"icon_id": "1029099",
|
||||
"name": "放大",
|
||||
"font_class": "enlarge-hs",
|
||||
"unicode": "e765",
|
||||
"unicode_decimal": 59237
|
||||
},
|
||||
{
|
||||
"icon_id": "20017362",
|
||||
"name": "上一步",
|
||||
"font_class": "previous-hs",
|
||||
"unicode": "e84c",
|
||||
"unicode_decimal": 59468
|
||||
},
|
||||
{
|
||||
"icon_id": "1010015",
|
||||
"name": "缩小",
|
||||
"font_class": "zoom-out-hs",
|
||||
"unicode": "e744",
|
||||
"unicode_decimal": 59204
|
||||
},
|
||||
{
|
||||
"icon_id": "20017363",
|
||||
"name": "下一步",
|
||||
"font_class": "next-step-hs",
|
||||
"unicode": "e84b",
|
||||
"unicode_decimal": 59467
|
||||
}
|
||||
]
|
||||
}
|
@@ -1,47 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
|
||||
<!--
|
||||
2013-9-30: Created.
|
||||
-->
|
||||
<svg>
|
||||
<metadata>
|
||||
Created by iconfont
|
||||
</metadata>
|
||||
<defs>
|
||||
|
||||
<font id="iconfont" horiz-adv-x="1024" >
|
||||
<font-face
|
||||
font-family="iconfont"
|
||||
font-weight="500"
|
||||
font-stretch="normal"
|
||||
units-per-em="1024"
|
||||
ascent="896"
|
||||
descent="-128"
|
||||
/>
|
||||
<missing-glyph />
|
||||
|
||||
<glyph glyph-name="full-screen-hs" unicode="" d="M960.605-36.34500000000003v240.231c0.045 7.2-2.723 14.445-8.213 19.98-11.115 11.047-29.002 11.047-40.071 0-5.535-5.535-8.303-12.757-8.303-19.98v-171.923l-351.99 352.035 351.99 352.013v-171.855c0-7.245 2.767-14.49 8.303-20.002 11.07-11.07 28.957-11.07 40.071 0 5.49 5.511 8.257 12.78 8.213 20.002v240.187c0.045 7.223-2.723 14.468-8.213 20.003-5.58 5.511-12.803 8.279-20.025 8.302h-240.233c-7.222 0-14.467-2.79-19.98-8.302-11.115-11.049-11.115-28.957 0-40.05 5.511-5.535 12.735-8.302 19.98-8.279h171.9l-352.013-352.013-352.012 352.035h171.855c7.268-0.022 14.49 2.745 20.025 8.279 11.07 11.047 11.07 29.002 0 40.05-5.49 5.511-12.758 8.279-20.025 8.303h-240.187c-7.268 0-14.513-2.79-20.025-8.303-5.513-5.558-8.279-12.803-8.279-20.048v-240.165c0-7.245 2.79-14.512 8.279-20.002 11.07-11.07 28.98-11.07 40.028 0 5.513 5.511 8.279 12.713 8.279 20.002v171.855l352.058-352.012-352.035-352.035v171.922c0 7.2-2.745 14.445-8.279 19.98-11.07 11.047-29.002 11.047-40.028 0-5.558-5.535-8.279-12.757-8.279-19.98v-240.231c0-7.223 2.79-14.468 8.279-20.048 5.535-5.468 12.757-8.279 20.025-8.279h240.188c7.268 0 14.49 2.745 20.025 8.279 11.07 11.047 11.07 29.002 0 40.05-5.535 5.535-12.78 8.257-20.025 8.257h-171.877l352.012 352.035 352.013-352.035h-171.9c-7.222 0-14.467-2.768-19.98-8.257-11.115-11.049-11.115-29.002 0-40.05 5.511-5.468 12.735-8.279 19.98-8.279h240.255c7.2 0 14.445 2.813 20.025 8.279 5.467 5.602 8.19 12.825 8.19 20.048z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="watch-hs" unicode="" d="M511.08 265.58000000000004c0.39 0.09 0.8 0.14 1.2 0.2h-0.52zM651 405.5c0-0.2-0.09-0.4-0.13-0.59s0-0.14 0-0.2c0.03 0.29 0.07 0.53 0.13 0.79zM471.17 265.58000000000004l-0.84 0.18h-0.31c0.38-0.03 0.77-0.1 1.15-0.18zM331.49 447v-0.36c0.08 0.51 0.16 1 0.23 1.52-0.12-0.37-0.19-0.78-0.23-1.16zM468.88 265.9l1.14-0.11c-0.83 0.13-1.67 0.23-2.5 0.36a10 10 0 0 1 1.36-0.25zM331.57 403.22a11.92 11.92 0 0 1 0.24-1.36c-0.13 0.87-0.24 1.76-0.38 2.64 0.05-0.43 0.09-0.86 0.14-1.28zM331.25 405.5c0.07-0.33 0.13-0.66 0.18-1v0.23zM331.25 445.42c0.05 0.26 0.1 0.5 0.15 0.73s0 0.34 0.05 0.51c-0.06-0.42-0.12-0.84-0.2-1.24zM650.84 404.59v0.12c-0.07-0.41-0.13-0.83-0.19-1.24 0.09 0.4 0.15 0.8 0.19 1.12zM512 831C264.66 831 65 631.3399999999999 65 384s199.66-447 447-447 447 199.66 447 447S759.34 831 512 831z m213.38-684.87c-8.76-9.55-25-8.88-33.91 0l-12.3 12.3q-42.64 42.63-85.28 85.28a200 200 0 0 0-59.3-22.52 214 214 0 0 0-131.48 14.95c-37.52 16.92-69.56 46.36-90.86 81.46-22 36.33-32.73 80.15-29.4 122.54a213.12 213.12 0 0 0 48.3 119.42c54.37 66.3 150.16 92.22 230.58 62.43a214.42 214.42 0 0 0 100.68-77.16c24.62-34.5 37.4-77.11 37.56-119.37a235.67 235.67 0 0 0-2.92-34.06c-6.88-45.84-30.52-87.73-64.1-118.92l5.81-5.81L725.38 180c9.48-9.43 8.79-24.3 0-33.87zM635.31 353.9c1.2 2.36 2.34 4.74 3.44 7.15 0.28 0.61 0.54 1.22 0.81 1.83 1.5 3.86 3 7.72 4.25 11.67a183.83 183.83 0 0 1 6.56 26.9c0.11 0.66 0.2 1.34 0.29 2-0.35-1.85-0.91-3.8 0.21 1.44 0.24 2.18 0.45 4.37 0.61 6.56 0.35 4.66 0.51 9.32 0.52 14s-0.17 9.33-0.52 14q-0.26 3.45-0.64 6.88v0.08c-1 6-0.2 1.67 0 0 0-0.31 0.11-0.63 0.17-1-0.16 0.89-0.27 1.8-0.41 2.7a182.65 182.65 0 0 1-6.6 27.62c-1.38 4.27-3 8.41-4.59 12.61-0.32 0.71-0.63 1.42-1 2.13-0.92 2-1.87 4-2.87 6a184.55 184.55 0 0 1-13.85 23.12c-1.11 1.58-7 8.66-1.71 2.52-1.42 1.65-2.72 3.42-4.12 5.09q-4.2 5-8.75 9.73c-6.1 6.32-12.78 11.79-19.44 17.49 6.14-5.26-0.94 0.6-2.52 1.71-1.79 1.26-3.6 2.48-5.43 3.68q-5.52 3.59-11.27 6.78-6.07 3.36-12.38 6.26c-0.75 0.35-1.51 0.68-2.26 1-1.64 0.62-3.25 1.3-4.9 1.9a181.3 181.3 0 0 1-27.13 7.74c-2.67 0.55-5.36 1-8.05 1.46-0.9 0.14-1.81 0.25-2.71 0.41l1-0.17c1.67-0.2 6-1 0 0H512q-6.56 0.75-13.15 1a188.34 188.34 0 0 1-28.4-1c-1.1-0.2-2.25-0.31-3.34-0.49-2.24-0.37-4.48-0.78-6.7-1.24q-6.63-1.35-13.14-3.18c-4.29-1.21-8.55-2.58-12.75-4.1-2-0.72-4-1.51-6-2.28l-1.84-0.82a185.92 185.92 0 0 1-24.25-13.32q-3.3-2.16-6.51-4.44c-0.74-0.53-3.82-2.89-3.93-2.93-0.71-0.57-1.41-1.14-2.1-1.72q-2.52-2.1-5-4.27a186.27 186.27 0 0 1-18.65-19.25c-1.32-1.58-6.2-9-2-2.31-1.16-1.83-2.62-3.53-3.86-5.3q-3.78-5.37-7.17-11T346.94 497q-1.5-3-2.89-5.95c-0.86-1.86-3.23-8.91-0.78-1.56-3-8.94-6.46-17.52-8.69-26.72q-1.68-6.94-2.82-14c0-0.21-0.05-0.42-0.08-0.62 0.29 1.51 0.67 2.55-0.28-2-0.2-1.77-0.38-3.54-0.53-5.32a188.09 188.09 0 0 1-0.11-29.36c0.17-2.25 0.41-4.49 0.65-6.74 0.8-3.86 0.63-3.81 0.4-2.87l0.06-0.41q1.06-6.38 2.56-12.66a200.32 200.32 0 0 1 8.27-26c0.46-1 0.89-2 1.35-3q1.4-3 2.89-6 3-5.86 6.39-11.53 3.56-5.89 7.54-11.54c1.13-1.59 2.44-3.11 3.49-4.76-4.09 6.45-0.21 0.31 1.12-1.3a185.34 185.34 0 0 1 19-19.82q2.92-2.63 5.95-5.13c1.62-1.33 7.76-5.22 1.31-1.12 3.49-2.22 6.72-4.91 10.18-7.19a184.79 184.79 0 0 1 23.59-13.12c1-0.48 2.06-0.93 3.09-1.4 2-0.76 3.94-1.54 5.92-2.26 4.2-1.52 8.46-2.89 12.75-4.1s8.72-2.29 13.14-3.18c2.22-0.46 4.46-0.87 6.7-1.24l0.41-0.06c-0.93 0.22-1 0.39 2.81-0.39a200.31 200.31 0 0 1 27.82-1q6.83 0.25 13.61 1c4.64 1 3.6 0.58 2.08 0.28l0.62 0.09c2 0.33 4 0.69 6 1.08a183.29 183.29 0 0 1 27.22 7.55c2.26 0.81 4.49 1.87 6.76 2.64 0.75 0.34 1.51 0.67 2.25 1q5.7 2.64 11.2 5.66c7.94 4.37 15 9.82 22.58 14.65-6.69-4.25 0.74 0.64 2.31 2s3.32 2.83 4.95 4.29q4.86 4.38 9.4 9.08 4.79 5 9.17 10.23c1.26 1.51 2.43 3.1 3.7 4.59-5.06-5.91-0.2-0.17 1 1.45a185.86 185.86 0 0 1 14.31 23.66zM512.68 265.82000000000005l1.16 0.19-1.56-0.23z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="download-hs" unicode="" d="M200 62h632v-88a8 8 0 0 0-8-8H192v88a8 8 0 0 0 8 8z m239 262.037V711c0 13.255 10.745 24 24 24h104v-401.473l141.997 137.148c9.534 9.209 24.728 8.945 33.936-0.59l0.004-0.003 72.205-74.799-304.959-294.546c-9.534-9.208-24.728-8.944-33.936 0.59l-0.003 0.004-71.859 74.44-0.063-0.062-205.587 212.927c-9.206 9.534-8.941 24.724 0.59 33.932l74.782 72.246L439 324.03700000000003z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="enlarge-hs" unicode="" d="M945.159 28.389999999999986l-206.543 206.538c49.578 63.772 79.108 143.903 79.108 230.953 0 207.97-168.58 376.547-376.639 376.547-207.97 0-376.547-168.577-376.547-376.547 0-208.038 168.577-376.614 376.547-376.614 87.059 0 167.197 29.532 230.973 79.108l206.543-206.544c9.171-9.17 21.227-13.802 33.278-13.802s24.106 4.629 33.28 13.802c18.431 18.43 18.431 48.215 0 66.559v0zM158.701 465.881c0 155.737 126.65 282.39 282.39 282.39 155.826 0 282.477-126.65 282.477-282.39 0-155.805-126.65-282.458-282.477-282.458-155.739 0-282.39 126.65-282.39 282.458v0zM579.708 506.147h-98.352v98.352c0 22.272-17.991 40.268-40.268 40.352-22.185-0.086-40.267-18.078-40.267-40.352v-98.352h-98.352c-22.272 0-40.268-17.991-40.268-40.179 0-22.272 17.991-40.352 40.268-40.352h98.352v-98.352c0-22.252 18.08-40.246 40.267-40.333 22.274 0.086 40.268 18.08 40.268 40.333v98.352h98.352c22.272 0 40.355 18.079 40.267 40.352 0 22.187-17.991 40.179-40.267 40.179v0z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="previous-hs" unicode="" d="M814.933333 413.866667C716.8 512 597.333333 567.4666669999999 460.8 580.266667V768c0 17.066667-8.533333 34.133333-25.6 38.4-17.066667 8.533333-34.133333 4.266667-46.933333-8.533333L29.866667 422.4c-17.066667-17.066667-17.066667-42.666667 0-59.733333l358.4-392.533334c8.533333-8.533333 21.333333-12.8 34.133333-12.8 4.266667 0 8.533333 0 17.066667 4.266667 17.066667 4.266667 25.6 21.333333 25.6 38.4v204.8c68.266667 8.533333 128 4.266667 192-12.8 76.8-21.333333 170.666667-93.866667 273.066666-213.333333 12.8-12.8 29.866667-21.333333 51.2-12.8 17.066667 8.533333 29.866667 25.6 25.6 42.666666-21.333333 162.133333-85.333333 298.666667-192 405.333334z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="zoom-out-hs" unicode="" d="M951.643 18.452999999999975l-210.337 210.335c50.487 64.946 80.56 146.547 80.56 235.199 0 211.793-171.681 383.472-383.563 383.472-211.792 0-383.471-171.679-383.471-383.472 0-211.862 171.679-383.538 383.471-383.538 88.661 0 170.271 30.075 235.218 80.56l210.337-210.339c9.34-9.339 21.614-14.055 33.89-14.055s24.551 4.716 33.892 14.055c18.77 18.77 18.77 49.101 0 67.781v0zM150.725 463.989c0 158.601 128.978 287.58 287.58 287.58 158.691 0 287.671-128.978 287.671-287.58 0-158.668-128.978-287.651-287.671-287.651-158.601 0-287.58 128.978-287.58 287.651v0zM397.297 504.996h-100.16c-22.683 0-41.008-18.324-41.008-40.919 0-22.683 18.324-41.094 41.008-41.094h282.333c22.683 0 41.095 18.412 41.007 41.094 0 22.595-18.324 40.919-41.007 40.919v0h-182.173z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="next-step-hs" unicode="" d="M209.066667 413.866667c98.133333 98.133333 213.333333 153.6 349.866666 166.4V768c0 17.066667 8.533333 34.133333 25.6 38.4 17.066667 8.533333 34.133333 4.266667 46.933334-8.533333l358.4-375.466667c17.066667-17.066667 17.066667-42.666667 0-59.733333l-358.4-392.533334c-8.533333-8.533333-21.333333-12.8-29.866667-12.8-4.266667 0-8.533333 0-17.066667 4.266667-17.066667 4.266667-25.6 21.333333-25.6 38.4v204.8c-68.266667 8.533333-128 4.266667-192-12.8-76.8-21.333333-170.666667-93.866667-273.066666-213.333333-8.533333-17.066667-29.866667-21.333333-46.933334-12.8-17.066667 8.533333-29.866667 25.6-25.6 42.666666 17.066667 162.133333 81.066667 298.666667 187.733334 405.333334z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
|
||||
|
||||
</font>
|
||||
</defs></svg>
|
Before Width: | Height: | Size: 9.4 KiB |
11
src/components/FlowChart/src/enum.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
export enum ToolbarTypeEnum {
|
||||
ZOOM_IN = 'zoomIn',
|
||||
ZOOM_OUT = 'zoomOut',
|
||||
RESET_ZOOM = 'resetZoom',
|
||||
|
||||
UNDO = 'undo',
|
||||
REDO = 'redo',
|
||||
|
||||
SNAPSHOT = 'snapshot',
|
||||
VIEW_DATA = 'viewData',
|
||||
}
|
124
src/components/FlowChart/src/index.vue
Normal file
@@ -0,0 +1,124 @@
|
||||
<template>
|
||||
<div class="h-full" :class="prefixCls">
|
||||
<FlowChartToolbar :prefixCls="prefixCls" v-if="toolbar" />
|
||||
<div ref="lfElRef" class="h-full"></div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import type { Definition } from '@logicflow/core';
|
||||
|
||||
import { defineComponent, ref, onMounted, unref, nextTick, computed, watch } from 'vue';
|
||||
|
||||
import FlowChartToolbar from './FlowChartToolbar.vue';
|
||||
import LogicFlow from '@logicflow/core';
|
||||
import { Snapshot, BpmnElement, Menu, DndPanel } from '@logicflow/extension';
|
||||
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
import { createFlowChartContext } from './useFlowContext';
|
||||
|
||||
import { toLogicFlowData } from './adpterForTurbo';
|
||||
|
||||
import '@logicflow/core/dist/style/index.css';
|
||||
import '@logicflow/extension/lib/style/index.css';
|
||||
export default defineComponent({
|
||||
name: 'FlowChart',
|
||||
components: { FlowChartToolbar },
|
||||
props: {
|
||||
flowOptions: {
|
||||
type: Object as PropType<Definition>,
|
||||
default: () => {},
|
||||
},
|
||||
|
||||
data: {
|
||||
type: Object as PropType<any>,
|
||||
default: () => {},
|
||||
},
|
||||
|
||||
toolbar: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const lfElRef = ref<ElRef>(null);
|
||||
|
||||
const lfInstance = ref<Nullable<LogicFlow>>(null);
|
||||
|
||||
const { prefixCls } = useDesign('flow-chart');
|
||||
createFlowChartContext({
|
||||
logicFlow: (lfInstance as unknown) as LogicFlow,
|
||||
});
|
||||
|
||||
const getFlowOptions = computed(() => {
|
||||
const { flowOptions } = props;
|
||||
|
||||
const defaultOptions: Partial<Definition> = {
|
||||
grid: true,
|
||||
background: {
|
||||
color: '#f7f9ff',
|
||||
},
|
||||
keyboard: {
|
||||
enabled: true,
|
||||
},
|
||||
...flowOptions,
|
||||
};
|
||||
return defaultOptions as Definition;
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.data,
|
||||
() => {
|
||||
onRender();
|
||||
}
|
||||
);
|
||||
|
||||
watch(
|
||||
() => props.flowOptions,
|
||||
(options) => {
|
||||
unref(lfInstance)?.updateEditConfig(options);
|
||||
}
|
||||
);
|
||||
|
||||
// init logicFlow
|
||||
async function init() {
|
||||
await nextTick();
|
||||
|
||||
const lfEl = unref(lfElRef);
|
||||
if (!lfEl) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Canvas configuration
|
||||
LogicFlow.use(Snapshot);
|
||||
// Use the bpmn plug-in to introduce bpmn elements, which can be used after conversion in turbo
|
||||
LogicFlow.use(BpmnElement);
|
||||
// Start the right-click menu
|
||||
LogicFlow.use(Menu);
|
||||
LogicFlow.use(DndPanel);
|
||||
lfInstance.value = new LogicFlow({
|
||||
...unref(getFlowOptions),
|
||||
container: lfEl,
|
||||
});
|
||||
unref(lfInstance)?.setDefaultEdgeType('line');
|
||||
onRender();
|
||||
}
|
||||
|
||||
async function onRender() {
|
||||
await nextTick();
|
||||
const lf = unref(lfInstance);
|
||||
if (!lf) {
|
||||
return;
|
||||
}
|
||||
const lFData = toLogicFlowData(props.data);
|
||||
lf.render(lFData);
|
||||
}
|
||||
|
||||
onMounted(init);
|
||||
|
||||
return {
|
||||
prefixCls,
|
||||
lfElRef,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
14
src/components/FlowChart/src/types.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { NodeConfig } from '@logicflow/core';
|
||||
import { ToolbarTypeEnum } from './enum';
|
||||
|
||||
export interface NodeItem extends NodeConfig {
|
||||
icon: string;
|
||||
}
|
||||
|
||||
export interface ToolbarConfig {
|
||||
type?: string | ToolbarTypeEnum;
|
||||
tooltip?: string | boolean;
|
||||
icon?: string;
|
||||
disabled?: boolean;
|
||||
separate?: boolean;
|
||||
}
|
17
src/components/FlowChart/src/useFlowContext.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import type LogicFlow from '@logicflow/core';
|
||||
|
||||
import { provide, inject } from 'vue';
|
||||
|
||||
const key = Symbol('flow-chart');
|
||||
|
||||
type Instance = {
|
||||
logicFlow: LogicFlow;
|
||||
};
|
||||
|
||||
export function createFlowChartContext(instance: Instance) {
|
||||
provide(key, instance);
|
||||
}
|
||||
|
||||
export function useFlowChartContext(): Instance {
|
||||
return inject(key) as Instance;
|
||||
}
|
@@ -298,27 +298,13 @@
|
||||
|
||||
@prefix-cls: ~'@{namespace}-basic-table';
|
||||
|
||||
html[data-theme='light'] {
|
||||
.@{prefix-cls} {
|
||||
&-row__striped {
|
||||
td {
|
||||
background-color: #fafafa;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
html[data-theme='dark'] {
|
||||
.@{prefix-cls} {
|
||||
&-row__striped {
|
||||
td {
|
||||
background-color: rgb(255 255 255 / 4%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.@{prefix-cls} {
|
||||
&-row__striped {
|
||||
td {
|
||||
background-color: content-background;
|
||||
}
|
||||
}
|
||||
|
||||
&-form-container {
|
||||
padding: 16px;
|
||||
|
||||
|
@@ -25,7 +25,7 @@ import 'tinymce/plugins/save';
|
||||
import 'tinymce/plugins/searchreplace';
|
||||
import 'tinymce/plugins/spellchecker';
|
||||
import 'tinymce/plugins/tabfocus';
|
||||
import 'tinymce/plugins/table';
|
||||
// import 'tinymce/plugins/table';
|
||||
import 'tinymce/plugins/template';
|
||||
import 'tinymce/plugins/textpattern';
|
||||
import 'tinymce/plugins/visualblocks';
|
||||
@@ -38,12 +38,12 @@ import 'tinymce/plugins/wordcount';
|
||||
// colorpicker/contextmenu/textcolor plugin is now built in to the core editor, please remove it from your editor configuration
|
||||
|
||||
export const plugins = [
|
||||
'advlist anchor autolink autosave code codesample directionality fullscreen hr insertdatetime link lists media nonbreaking noneditable pagebreak paste preview print save searchreplace spellchecker tabfocus table template textpattern visualblocks visualchars wordcount',
|
||||
'advlist anchor autolink autosave code codesample directionality fullscreen hr insertdatetime link lists media nonbreaking noneditable pagebreak paste preview print save searchreplace spellchecker tabfocus template textpattern visualblocks visualchars wordcount',
|
||||
];
|
||||
|
||||
export const toolbar = [
|
||||
'fontsizeselect lineheight searchreplace bold italic underline strikethrough alignleft aligncenter alignright outdent indent blockquote undo redo removeformat subscript superscript code codesample',
|
||||
'hr bullist numlist link preview anchor pagebreak insertdatetime media table forecolor backcolor fullscreen',
|
||||
'hr bullist numlist link preview anchor pagebreak insertdatetime media forecolor backcolor fullscreen',
|
||||
];
|
||||
|
||||
export { tinymce };
|
||||
|
@@ -35,5 +35,4 @@ export default {
|
||||
|
||||
time: 'Relative Time',
|
||||
cropperImage: 'Cropper Image',
|
||||
flowChart: 'Flow Chart',
|
||||
};
|
||||
|
4
src/locales/lang/en/routes/demo/flow.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export default {
|
||||
name: 'Graphics editor',
|
||||
flowChart: 'FlowChart',
|
||||
};
|
@@ -34,5 +34,4 @@ export default {
|
||||
|
||||
time: '相对时间',
|
||||
cropperImage: '图片裁剪',
|
||||
flowChart: '流程图',
|
||||
};
|
||||
|
4
src/locales/lang/zh_CN/routes/demo/flow.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export default {
|
||||
name: '图形编辑器',
|
||||
flowChart: '流程图',
|
||||
};
|
@@ -123,13 +123,6 @@ const menu: MenuModule = {
|
||||
content: 'new',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'flowChart',
|
||||
name: t('routes.demo.comp.flowChart'),
|
||||
tag: {
|
||||
content: 'new',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'countTo',
|
||||
name: t('routes.demo.comp.countTo'),
|
||||
|
18
src/router/menus/modules/demo/flow.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import type { MenuModule } from '/@/router/types';
|
||||
import { t } from '/@/hooks/web/useI18n';
|
||||
|
||||
const menu: MenuModule = {
|
||||
orderNo: 5000,
|
||||
menu: {
|
||||
name: t('routes.demo.flow.name'),
|
||||
path: '/flow',
|
||||
|
||||
children: [
|
||||
{
|
||||
path: 'flowChart',
|
||||
name: t('routes.demo.flow.flowChart'),
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
export default menu;
|
@@ -240,14 +240,7 @@ const comp: AppRouteModule = {
|
||||
title: t('routes.demo.comp.cropperImage'),
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'flowChart',
|
||||
name: 'flowChartDemo',
|
||||
component: () => import('/@/views/demo/comp/flow-chart/index.vue'),
|
||||
meta: {
|
||||
title: t('routes.demo.comp.flowChart'),
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
path: 'timestamp',
|
||||
name: 'TimeDemo',
|
||||
|
27
src/router/routes/modules/demo/flow.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import type { AppRouteModule } from '/@/router/types';
|
||||
|
||||
import { LAYOUT } from '/@/router/constant';
|
||||
import { t } from '/@/hooks/web/useI18n';
|
||||
|
||||
const charts: AppRouteModule = {
|
||||
path: '/flow',
|
||||
name: 'FlowDemo',
|
||||
component: LAYOUT,
|
||||
redirect: '/flow/flowChart',
|
||||
meta: {
|
||||
icon: 'tabler:chart-dots',
|
||||
title: t('routes.demo.flow.name'),
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: 'flowChart',
|
||||
name: 'flowChartDemo',
|
||||
component: () => import('/@/views/demo/comp/flow-chart/index.vue'),
|
||||
meta: {
|
||||
title: t('routes.demo.flow.flowChart'),
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default charts;
|
@@ -1,133 +1,23 @@
|
||||
<template>
|
||||
<div class="logic-flow-view">
|
||||
<!-- 辅助工具栏 -->
|
||||
<Control class="demo-control" v-if="lf" :lf="lf" :catTurboData="false" @catData="catData" />
|
||||
<!-- 节点面板 -->
|
||||
<NodePanel :lf="lf" :nodeList="nodeList" />
|
||||
<!-- 画布 -->
|
||||
<div id="LF-Turbo"></div>
|
||||
<!-- 数据查看面板 -->
|
||||
<BasicModal @register="register" title="数据">
|
||||
<DataDialog :graphData="graphData" />
|
||||
</BasicModal>
|
||||
</div>
|
||||
<PageWrapper
|
||||
title="流程图"
|
||||
content="简单流程图示例,具体功能需要自己完善"
|
||||
contentFullHeight
|
||||
fixedHeight
|
||||
>
|
||||
<FlowChart :data="demoData" />
|
||||
</PageWrapper>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { ref, unref, onMounted } from 'vue';
|
||||
import LogicFlow from '@logicflow/core';
|
||||
import { Snapshot, BpmnElement, Menu } from '@logicflow/extension';
|
||||
import '@logicflow/core/dist/style/index.css';
|
||||
import '@logicflow/extension/lib/style/index.css';
|
||||
import { Control, NodePanel, DataDialog } from '/@/components/FlowChart';
|
||||
import { FlowChart } from '/@/components/FlowChart';
|
||||
import { PageWrapper } from '/@/components/Page';
|
||||
|
||||
import { toLogicflowData } from '/@/components/FlowChart/src/adpterForTurbo';
|
||||
import { BpmnNode } from '/@/components/FlowChart/src/config';
|
||||
import demoData from './dataTurbo.json';
|
||||
|
||||
import { BasicModal, useModal } from '/@/components/Modal';
|
||||
export default {
|
||||
components: { NodePanel, Control, DataDialog, BasicModal },
|
||||
components: { FlowChart, PageWrapper },
|
||||
setup() {
|
||||
let lf = ref(null);
|
||||
let graphData = ref(null);
|
||||
let config = ref({
|
||||
grid: true,
|
||||
background: {
|
||||
color: '#f7f9ff',
|
||||
},
|
||||
keyboard: {
|
||||
enabled: true,
|
||||
},
|
||||
});
|
||||
let nodeList = BpmnNode;
|
||||
|
||||
const [register, { openModal }] = useModal();
|
||||
|
||||
function initLf() {
|
||||
// 画布配置
|
||||
LogicFlow.use(Snapshot);
|
||||
// 使用bpmn插件,引入bpmn元素,这些元素可以在turbo中转换后使用
|
||||
LogicFlow.use(BpmnElement);
|
||||
// 启动右键菜单
|
||||
LogicFlow.use(Menu);
|
||||
const domLf = new LogicFlow({
|
||||
...unref(config),
|
||||
container: document.querySelector('#LF-Turbo'),
|
||||
});
|
||||
lf.value = domLf;
|
||||
// 设置边类型bpmn:sequenceFlow为默认类型
|
||||
unref(lf).setDefaultEdgeType('bpmn:sequenceFlow');
|
||||
onRender();
|
||||
}
|
||||
|
||||
function onRender() {
|
||||
// Turbo数据转换为LogicFlow内部识别的数据结构
|
||||
const lFData = toLogicflowData(demoData);
|
||||
lf.value.render(lFData);
|
||||
}
|
||||
|
||||
function catData() {
|
||||
graphData.value = unref(lf).getGraphData();
|
||||
openModal();
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
initLf();
|
||||
});
|
||||
|
||||
return {
|
||||
lf,
|
||||
graphData,
|
||||
config,
|
||||
nodeList,
|
||||
catData,
|
||||
register,
|
||||
openModal,
|
||||
};
|
||||
return { demoData };
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
#LF-Turbo {
|
||||
width: 100vw;
|
||||
height: 85%;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.logic-flow-view {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.demo-title {
|
||||
margin: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.demo-control {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 20px;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.time-plus {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.add-panel {
|
||||
position: absolute;
|
||||
z-index: 11;
|
||||
padding: 10px 5px;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.el-drawer__body {
|
||||
z-index: 3;
|
||||
height: 80%;
|
||||
margin-top: -30px;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
|
10
yarn.lock
@@ -7719,17 +7719,17 @@ rollup-plugin-terser@^7.0.0:
|
||||
serialize-javascript "^4.0.0"
|
||||
terser "^5.0.0"
|
||||
|
||||
rollup-plugin-visualizer@5.3.6:
|
||||
version "5.3.6"
|
||||
resolved "https://registry.npmjs.org/rollup-plugin-visualizer/-/rollup-plugin-visualizer-5.3.6.tgz#df6317b242f4aa58b6a03261335dbc64ea6fe0df"
|
||||
integrity sha512-USIyYkzRuvIJZyUoFWSvejy/c8F9jm9mHbyB+01oE7m0Vc0Ll67HlZgRsY59IqU/j/qF1adPsXKSDkEXS6tzfg==
|
||||
rollup-plugin-visualizer@5.3.4:
|
||||
version "5.3.4"
|
||||
resolved "https://registry.npmjs.org/rollup-plugin-visualizer/-/rollup-plugin-visualizer-5.3.4.tgz#216300acca6e31b139be92eed98280c5662a5818"
|
||||
integrity sha512-n3wYwKrZ3nhYJj8apzFuxmiu4y+ygDNJYLqQCOxludg3Pnhkql9WYc8iupgsMI+jGREA0dFsfDlzDAKcmXZIMQ==
|
||||
dependencies:
|
||||
nanoid "^3.1.22"
|
||||
open "^7.4.2"
|
||||
source-map "^0.7.3"
|
||||
yargs "^16.2.0"
|
||||
|
||||
rollup@^2.25.0, rollup@^2.38.5, rollup@^2.44.0, rollup@^2.45.2:
|
||||
rollup@^2.25.0, rollup@^2.38.5, rollup@^2.44.0:
|
||||
version "2.45.2"
|
||||
resolved "https://registry.npmjs.org/rollup/-/rollup-2.45.2.tgz#8fb85917c9f35605720e92328f3ccbfba6f78b48"
|
||||
integrity sha512-kRRU7wXzFHUzBIv0GfoFFIN3m9oteY4uAsKllIpQDId5cfnkWF2J130l+27dzDju0E6MScKiV0ZM5Bw8m4blYQ==
|
||||
|