|
@@ -9,6 +9,7 @@
|
|
v-for="step in steps"
|
|
v-for="step in steps"
|
|
:key="step.id"
|
|
:key="step.id"
|
|
v-bind="getStepAttrib(step)"
|
|
v-bind="getStepAttrib(step)"
|
|
|
|
+ :treeBoxMargin="treeBoxMargin"
|
|
@click="emit('stepClick', step)"
|
|
@click="emit('stepClick', step)"
|
|
@click-host="(data) => emit('stepHostClick', data)"
|
|
@click-host="(data) => emit('stepHostClick', data)"
|
|
/>
|
|
/>
|
|
@@ -16,22 +17,29 @@
|
|
</template>
|
|
</template>
|
|
|
|
|
|
<script lang="ts" setup>
|
|
<script lang="ts" setup>
|
|
-import { computed } from 'vue'
|
|
|
|
-import { flatSteps, attachBoundAttrib, NStep, getTextBound } from './helper'
|
|
|
|
-import Step from './step.vue'
|
|
|
|
|
|
+import { computed } from "vue";
|
|
|
|
+import {
|
|
|
|
+ flatSteps,
|
|
|
|
+ attachBoundAttrib,
|
|
|
|
+ NStep,
|
|
|
|
+ getTextBound,
|
|
|
|
+ attachStepTreesBoundAttrib,
|
|
|
|
+} from "./helper";
|
|
|
|
+import Step from "./step.vue";
|
|
|
|
|
|
const props = withDefaults(
|
|
const props = withDefaults(
|
|
defineProps<{
|
|
defineProps<{
|
|
- margin?: number[]
|
|
|
|
- padding?: number[]
|
|
|
|
- fontSize?: number
|
|
|
|
- data: any
|
|
|
|
- fontFamily?: string
|
|
|
|
- hostFontSize?: number
|
|
|
|
- hostMargin?: number[]
|
|
|
|
- hostPadding?: number[]
|
|
|
|
- customStepStyle?: (step: any) => {}
|
|
|
|
- lineGap: number
|
|
|
|
|
|
+ margin?: number[];
|
|
|
|
+ padding?: number[];
|
|
|
|
+ fontSize?: number;
|
|
|
|
+ treeBoxMargin: number[];
|
|
|
|
+ data: any;
|
|
|
|
+ fontFamily?: string;
|
|
|
|
+ hostFontSize?: number;
|
|
|
|
+ hostMargin?: number[];
|
|
|
|
+ hostPadding?: number[];
|
|
|
|
+ customStepStyle?: (step: any) => {};
|
|
|
|
+ lineGap: number;
|
|
}>(),
|
|
}>(),
|
|
{
|
|
{
|
|
margin: () => [10, 10],
|
|
margin: () => [10, 10],
|
|
@@ -41,14 +49,14 @@ const props = withDefaults(
|
|
hostFontSize: 10,
|
|
hostFontSize: 10,
|
|
lineGap: 5,
|
|
lineGap: 5,
|
|
fontSize: 14,
|
|
fontSize: 14,
|
|
- fontFamily: 'sans-serif',
|
|
|
|
|
|
+ fontFamily: "sans-serif",
|
|
}
|
|
}
|
|
-)
|
|
|
|
|
|
+);
|
|
|
|
|
|
const emit = defineEmits<{
|
|
const emit = defineEmits<{
|
|
- (e: 'stepClick', data: any): void
|
|
|
|
- (e: 'stepHostClick', host: any): void
|
|
|
|
-}>()
|
|
|
|
|
|
+ (e: "stepClick", data: any): void;
|
|
|
|
+ (e: "stepHostClick", host: any): void;
|
|
|
|
+}>();
|
|
|
|
|
|
const getStepSize = (step: any) => {
|
|
const getStepSize = (step: any) => {
|
|
const size = getTextBound(
|
|
const size = getTextBound(
|
|
@@ -56,17 +64,17 @@ const getStepSize = (step: any) => {
|
|
props.padding,
|
|
props.padding,
|
|
props.margin,
|
|
props.margin,
|
|
`${props.fontSize}px normal ${props.fontFamily}`
|
|
`${props.fontSize}px normal ${props.fontFamily}`
|
|
- )
|
|
|
|
|
|
+ );
|
|
|
|
|
|
if (step.hosts?.length) {
|
|
if (step.hosts?.length) {
|
|
- const hostsGroup = []
|
|
|
|
- const numGroup = 2
|
|
|
|
|
|
+ const hostsGroup = [];
|
|
|
|
+ const numGroup = 2;
|
|
for (let i = 0; i < step.hosts.length; i += numGroup) {
|
|
for (let i = 0; i < step.hosts.length; i += numGroup) {
|
|
- hostsGroup.push(step.hosts.slice(i, i + numGroup))
|
|
|
|
|
|
+ hostsGroup.push(step.hosts.slice(i, i + numGroup));
|
|
}
|
|
}
|
|
- let top = 0
|
|
|
|
|
|
+ let top = 0;
|
|
const hostSizeGroup = hostsGroup.map((hosts) => {
|
|
const hostSizeGroup = hostsGroup.map((hosts) => {
|
|
- let left = 0
|
|
|
|
|
|
+ let left = 0;
|
|
const hostSize = hosts.reduce(
|
|
const hostSize = hosts.reduce(
|
|
(t: any, host: any) => {
|
|
(t: any, host: any) => {
|
|
const size = getTextBound(
|
|
const size = getTextBound(
|
|
@@ -74,85 +82,112 @@ const getStepSize = (step: any) => {
|
|
props.hostPadding,
|
|
props.hostPadding,
|
|
props.hostMargin,
|
|
props.hostMargin,
|
|
`${props.hostFontSize}px normal ${props.fontFamily}`
|
|
`${props.hostFontSize}px normal ${props.fontFamily}`
|
|
- )
|
|
|
|
- t.width += size.width
|
|
|
|
- t.height = Math.max(t.height, size.height)
|
|
|
|
|
|
+ );
|
|
|
|
+ t.width += size.width;
|
|
|
|
+ t.height = Math.max(t.height, size.height);
|
|
host.bound = {
|
|
host.bound = {
|
|
...size,
|
|
...size,
|
|
left,
|
|
left,
|
|
top,
|
|
top,
|
|
- }
|
|
|
|
- left += size.width
|
|
|
|
- return t
|
|
|
|
|
|
+ };
|
|
|
|
+ left += size.width;
|
|
|
|
+ return t;
|
|
},
|
|
},
|
|
{ width: 0, height: 0 }
|
|
{ width: 0, height: 0 }
|
|
- )
|
|
|
|
- top += hostSize.height
|
|
|
|
- return hostSize
|
|
|
|
- })
|
|
|
|
|
|
+ );
|
|
|
|
+ top += hostSize.height;
|
|
|
|
+ return hostSize;
|
|
|
|
+ });
|
|
|
|
|
|
const hostSize = hostSizeGroup.reduceRight(
|
|
const hostSize = hostSizeGroup.reduceRight(
|
|
(t, hostSize) => {
|
|
(t, hostSize) => {
|
|
- t.width = Math.max(hostSize.width, t.width)
|
|
|
|
- t.height += hostSize.height
|
|
|
|
- return t
|
|
|
|
|
|
+ t.width = Math.max(hostSize.width, t.width);
|
|
|
|
+ t.height += hostSize.height;
|
|
|
|
+ return t;
|
|
},
|
|
},
|
|
{ width: 0, height: 0 }
|
|
{ width: 0, height: 0 }
|
|
- )
|
|
|
|
- step.hostSize = hostSize
|
|
|
|
- size.width = Math.max(size.width, hostSize.width + (props.padding[1] + props.margin[1]) * 2)
|
|
|
|
- size.height += hostSize.height
|
|
|
|
|
|
+ );
|
|
|
|
+ step.hostSize = hostSize;
|
|
|
|
+ size.width = Math.max(
|
|
|
|
+ size.width,
|
|
|
|
+ hostSize.width + (props.padding[1] + props.margin[1]) * 2
|
|
|
|
+ );
|
|
|
|
+ size.height += hostSize.height;
|
|
}
|
|
}
|
|
|
|
|
|
- return size
|
|
|
|
-}
|
|
|
|
|
|
+ return size;
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+const steps = computed(() => {
|
|
|
|
+ const steps = flatSteps(props.data);
|
|
|
|
+ return steps;
|
|
|
|
+});
|
|
|
|
+const bound = computed(() => {
|
|
|
|
+ const pageBound = attachBoundAttrib(steps.value, getStepSize);
|
|
|
|
+ attachStepTreesBoundAttrib(steps.value, props.data);
|
|
|
|
+ console.log(steps.value);
|
|
|
|
+ return {
|
|
|
|
+ ...pageBound,
|
|
|
|
+ left: pageBound.left - 10,
|
|
|
|
+ right: pageBound.right + 10,
|
|
|
|
+ top: pageBound.top - 10,
|
|
|
|
+ bottom: pageBound.bottom + 10,
|
|
|
|
+ };
|
|
|
|
+});
|
|
|
|
|
|
-const steps = computed(() => flatSteps(props.data))
|
|
|
|
-const bound = computed(() => attachBoundAttrib(steps.value, getStepSize))
|
|
|
|
-console.log('3323', bound.value)
|
|
|
|
const svgAttrib = computed(() => {
|
|
const svgAttrib = computed(() => {
|
|
- if (!bound.value) return null
|
|
|
|
- const { left, right, top, bottom } = bound.value
|
|
|
|
|
|
+ if (!bound.value) return null;
|
|
|
|
+ const { left, right, top, bottom } = bound.value;
|
|
return {
|
|
return {
|
|
viewBox: [left, top, right - left, bottom - top],
|
|
viewBox: [left, top, right - left, bottom - top],
|
|
- }
|
|
|
|
-})
|
|
|
|
|
|
+ };
|
|
|
|
+});
|
|
|
|
|
|
-const lineGap = computed(() => Math.min(props.lineGap, props.margin[0]))
|
|
|
|
|
|
+const lineGap = computed(() => Math.min(props.lineGap, props.margin[0]));
|
|
|
|
|
|
const getStepLines = (step: NStep) => {
|
|
const getStepLines = (step: NStep) => {
|
|
- if (!step.parentIds.length) return []
|
|
|
|
- const start = [step.bound.left + step.bound.width / 2, step.bound.top + props.margin[0]]
|
|
|
|
- const points = []
|
|
|
|
|
|
+ if (!step.parentIds.length) return [];
|
|
|
|
+ const start = [
|
|
|
|
+ step.bound.left + step.bound.width / 2,
|
|
|
|
+ step.bound.top + props.margin[0],
|
|
|
|
+ ];
|
|
|
|
+ const points = [];
|
|
for (let parentId of step.parentIds) {
|
|
for (let parentId of step.parentIds) {
|
|
- const parent = steps.value.find((step) => step.id === parentId)!
|
|
|
|
|
|
+ const parent = steps.value.find((step) => step.id === parentId)!;
|
|
const end = [
|
|
const end = [
|
|
parent.bound.left + parent.bound.width / 2,
|
|
parent.bound.left + parent.bound.width / 2,
|
|
parent.bound.top + parent.bound.height - props.margin[0],
|
|
parent.bound.top + parent.bound.height - props.margin[0],
|
|
- ]
|
|
|
|
- const startLevelHeight = bound.value.levelHeights[step.level]
|
|
|
|
|
|
+ ];
|
|
|
|
+ const startLevelHeight = bound.value.levelHeights[step.level];
|
|
// const parentLevelHeight = bound.value.levelHeights[parent.level];
|
|
// const parentLevelHeight = bound.value.levelHeights[parent.level];
|
|
- const offset = lineGap.value + (startLevelHeight - step.bound.height) / 2
|
|
|
|
|
|
+ const offset = lineGap.value + (startLevelHeight - step.bound.height) / 2;
|
|
|
|
|
|
- points.push([...start, start[0], start[1] - offset, end[0], start[1] - offset, ...end])
|
|
|
|
|
|
+ points.push([
|
|
|
|
+ ...start,
|
|
|
|
+ start[0],
|
|
|
|
+ start[1] - offset,
|
|
|
|
+ end[0],
|
|
|
|
+ start[1] - offset,
|
|
|
|
+ ...end,
|
|
|
|
+ ]);
|
|
}
|
|
}
|
|
- return points
|
|
|
|
-}
|
|
|
|
|
|
+ return points;
|
|
|
|
+};
|
|
|
|
|
|
const defaultStyle = {
|
|
const defaultStyle = {
|
|
- lineColor: '#000',
|
|
|
|
|
|
+ lineColor: "#000",
|
|
lineWidth: 1,
|
|
lineWidth: 1,
|
|
- textColor: '#000',
|
|
|
|
- rectBorderColor: '#000',
|
|
|
|
- rectBgColor: '#ffff',
|
|
|
|
|
|
+ textColor: "#000",
|
|
|
|
+ rectBorderColor: "#000",
|
|
|
|
+ rectBgColor: "#ffff",
|
|
rectRadius: 2,
|
|
rectRadius: 2,
|
|
rectBorderWidth: 1,
|
|
rectBorderWidth: 1,
|
|
-}
|
|
|
|
|
|
+};
|
|
|
|
|
|
const getStepAttrib = (step: NStep) => {
|
|
const getStepAttrib = (step: NStep) => {
|
|
- let style = defaultStyle
|
|
|
|
|
|
+ let style = defaultStyle;
|
|
if (props.customStepStyle) {
|
|
if (props.customStepStyle) {
|
|
- style = { ...defaultStyle, ...props.customStepStyle(step.raw) }
|
|
|
|
|
|
+ style = { ...defaultStyle, ...props.customStepStyle(step.raw) };
|
|
}
|
|
}
|
|
return {
|
|
return {
|
|
style,
|
|
style,
|
|
@@ -165,7 +200,6 @@ const getStepAttrib = (step: NStep) => {
|
|
hostFontSize: props.hostFontSize,
|
|
hostFontSize: props.hostFontSize,
|
|
fontFamily: props.fontFamily,
|
|
fontFamily: props.fontFamily,
|
|
lines: getStepLines(step),
|
|
lines: getStepLines(step),
|
|
- }
|
|
|
|
-}
|
|
|
|
|
|
+ };
|
|
|
|
+};
|
|
</script>
|
|
</script>
|
|
-
|
|
|