123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- import { getStepLine, Step, traversalSteps } from "./tree-helper";
- import {
- getStepsTreeCtx as getStepsTreeCtxRaw,
- StepsCtx as StepsCtxRaw,
- } from "./tree-helper";
- type DataStep = {
- serviceTypeParallel?: boolean | "True" | "Flase";
- subStepsParallel?: boolean | "True" | "Flase";
- };
- export type DataStepTree<T extends DataStep = DataStep> = T & {
- steps: DataStepTree<T>[];
- };
- export type NStep<T extends DataStepTree> = Step<T>;
- const _flatSteps = <T extends DataStep>(
- steps: DataStepTree<T>[],
- nsteps: NStep<DataStepTree<T>>[] = [],
- parents: NStep<DataStepTree<T>>[] = [],
- parallel = false
- ) => {
- const lonelySteps: NStep<DataStepTree<T>>[] = [];
- let tempParents = parents;
- for (const step of steps) {
- const stepParallel = parallel;
- if (!stepParallel && lonelySteps.length) {
- tempParents = [...lonelySteps];
- lonelySteps.length = 0;
- }
- const nstep = {
- raw: step,
- children: [],
- parents: tempParents,
- } as NStep<DataStepTree<T>>;
- nsteps.push(nstep);
- tempParents.forEach((parent) => parent.children.push(nstep));
- if (step.steps && step.steps.length) {
- step.serviceTypeParallel;
- lonelySteps.push(
- ..._flatSteps(
- step.steps,
- nsteps,
- [nstep],
- step.subStepsParallel === "True" ||
- step.serviceTypeParallel === "True" ||
- !!step.subStepsParallel ||
- !!step.serviceTypeParallel
- )
- );
- } else {
- lonelySteps.push(nstep);
- }
- }
- return lonelySteps;
- };
- export const flatSteps = <T extends DataStep>(steps: DataStepTree<T>[]) => {
- const nsteps: NStep<DataStepTree<T>>[] = [];
- _flatSteps(steps, nsteps);
- return nsteps;
- };
- // 获取step所有子级
- const getStepFlatSteps = <T extends DataStep>(step: DataStepTree<T>) => {
- if (!step.steps || step.steps.length === 0) return [];
- const children: DataStepTree<T>[] = [];
- for (const child of step.steps) {
- children.push(child);
- children.push(...getStepFlatSteps(child));
- }
- return children;
- };
- // 获取steps组成的bound
- const getStepsBound = <T>(nsteps: NStep<DataStepTree<T>>[]) => {
- const bounds = nsteps.map((nstep) => {
- return { ...nstep.box.offset, ...nstep.box.size };
- });
- let maxX = -Number.MAX_VALUE,
- maxY = -Number.MAX_VALUE,
- minX = Number.MAX_VALUE,
- minY = Number.MAX_VALUE;
- for (const bound of bounds) {
- minX = Math.min(bound.x, minX);
- minY = Math.min(bound.y, minY);
- maxX = Math.max(bound.x + bound.w, maxX);
- maxY = Math.max(bound.y + bound.h, maxY);
- }
- return {
- x: minX,
- y: minY,
- w: maxX - minX,
- h: maxY - minY,
- };
- };
- export type StepsCtx<T> = StepsCtxRaw<T> & {
- groupBoxs: {
- step: Step<T>;
- bound: { w: number; h: number; x: number; y: number };
- line: number[][];
- }[];
- };
- const setGroupBack = <T>(
- steps: NStep<DataStepTree<T>>[],
- ctx: StepsCtx<DataStepTree<T>>,
- groups: NStep<DataStepTree<T>>[]
- ) => {
- const maxWidth = Math.max(...groups.map(({ box }) => box.size.w));
- for (const groupStep of groups) {
- const children = getStepFlatSteps(groupStep.raw);
- const childSteps = children.map((raw) =>
- steps.find((step) => raw === step.raw)
- );
- ctx.groupBoxs.push({
- step: groupStep,
- line: [],
- bound: getStepsBound(childSteps),
- });
- groupStep.box.offset.x = -maxWidth + (maxWidth - groupStep.box.size.w) / 2;
- }
- ctx.offset.x = -maxWidth;
- ctx.size.w += maxWidth;
- };
- const setGroupOffset = <T>(
- steps: NStep<DataStepTree<T>>[],
- ctx: StepsCtx<DataStepTree<T>>,
- groupSteps: NStep<DataStepTree<T>>[],
- margin: number
- ) => {
- // margin = 0;
- const offsetYs: number[] = [];
- const offsetLYs: number[] = [];
- for (let i = 0; i < groupSteps.length; i++) {
- const groupStep = groupSteps[i];
- if (i > 0) {
- offsetYs[i] = -groupStep.box.size.h + offsetYs[i - 1] + margin;
- offsetLYs[i] = offsetLYs[i - 1] - groupStep.box.size.h + margin;
- } else {
- offsetYs[i] = -groupStep.box.size.h + margin;
- offsetLYs[i] = -groupStep.box.size.h + margin;
- }
- groupStep.box.offset.y += margin;
- }
- let offsetNdx = offsetYs.length - 1;
- let offsetLNdx = offsetYs.length - 1;
- traversalSteps({
- steps,
- ctx,
- oper: ({ currents }) => {
- const isBorder = currents.some((current) => groupSteps.includes(current));
- if (isBorder) {
- offsetNdx -= 1;
- }
- for (const current of currents) {
- if (offsetNdx === -1) {
- current.box.lines = [];
- break;
- }
- current.box.offset.y += offsetYs[offsetNdx];
- for (const points of current.box.lines) {
- for (const point of points) {
- point[1] = point[1] + offsetLYs[offsetLNdx];
- }
- }
- }
- if (isBorder) {
- offsetLNdx -= 1;
- }
- },
- reverse: true,
- });
- ctx.size.h += offsetYs[offsetYs.length - 1];
- };
- export const setGroupLine = <T>(
- ctx: StepsCtx<DataStepTree<T>>,
- groupSteps: NStep<DataStepTree<T>>[],
- margin: number[]
- ) => {
- for (let i = 0; i < groupSteps.length - 1; i++) {
- ctx.groupBoxs[i].line = getStepLine(
- ctx,
- groupSteps[i],
- groupSteps[i + 1],
- margin
- );
- }
- };
- export const getStepsTreeCtx = <T extends DataStep>(
- steps: NStep<DataStepTree<T>>[],
- margin: number[],
- getStepSize: (step: T) => { w: number; h: number },
- groups: DataStepTree<T>[]
- ) => {
- const ctx = getStepsTreeCtxRaw(steps, margin, getStepSize) as StepsCtx<
- DataStepTree<T>
- >;
- const groupSteps = groups.map((group) =>
- steps.find((step) => group === step.raw)
- );
- setGroupOffset(steps, ctx, groupSteps, margin[0]);
- ctx.groupBoxs = [];
- setGroupBack(steps, ctx, groupSteps);
- setGroupLine(ctx, groupSteps, margin);
- return ctx;
- };
|