Files
PTL/1.0.0/ref/Map/dist/js/panel.test.js
T
2026-07-14 21:29:27 +08:00

623 lines
35 KiB
JavaScript

(() => {
// src/ui/panel.test.js
var root = window;
var panelNamespace = root.Panel;
if (!panelNamespace || typeof panelNamespace !== "object") {
throw new Error("加载 panel.test.js 前必须先准备 window.Panel 命名空间");
}
var page = panelNamespace.ui;
if (!page) throw new Error("加载 panel.test.js 前必须先加载 Panel.ui");
var noop = () => {
};
var BatchAppendOptions = Object.freeze({ insertMode: "append" });
var createCarCode = (index) => (index + 1).toString().padStart(4, "0");
var createCarName = (code) => `第[${code}]号车`;
var createCarShape = ({ type, code, name = createCarName(code), point = { x: 0, y: 0 }, rotate = 0, lock = false }) => {
const car = {
type,
code: { text: code },
name: { text: name },
base: { point: { x: point.x, y: point.y }, rotate }
};
if (lock) car.lock = { enable: true };
return car;
};
var setCarTransform = (car, x, y, rotate) => {
car.base.point.x = x;
car.base.point.y = y;
car.base.rotate = rotate;
return car;
};
var StaticCarDefs = Object.freeze([
{ type: "CarForklift", code: "2000", point: { x: 300, y: 100 }, rotate: 0, lock: true },
{ type: "CarForklift", code: "2001", point: { x: 400, y: 100 }, rotate: 45 },
{ type: "CarForklift", code: "2002", point: { x: 500, y: 100 }, rotate: 90 },
{ type: "CarForklift", code: "2003", point: { x: 600, y: 100 }, rotate: 135 },
{ type: "CarConveyor", code: "2010", point: { x: 700, y: 100 }, rotate: 180 },
{ type: "CarConveyor", code: "2011", point: { x: 800, y: 100 }, rotate: 225, lock: true },
{ type: "CarConveyor", code: "2012", point: { x: 900, y: 100 }, rotate: 270 },
{ type: "CarConveyor", code: "2013", point: { x: 1e3, y: 100 }, rotate: 315 },
{ type: "CarTugger", code: "2020", point: { x: 300, y: 300 }, rotate: 360 },
{ type: "CarTugger", code: "2021", point: { x: 400, y: 300 }, rotate: 405 },
{ type: "CarTugger", code: "2022", point: { x: 500, y: 300 }, rotate: 450, lock: true },
{ type: "CarTugger", code: "2023", point: { x: 600, y: 300 }, rotate: 495 },
{ type: "CarCarrier", code: "2030", point: { x: 700, y: 300 }, rotate: 540 },
{ type: "CarCarrier", code: "2031", point: { x: 800, y: 300 }, rotate: 585 },
{ type: "CarCarrier", code: "2032", point: { x: 900, y: 300 }, rotate: 630 },
{ type: "CarCarrier", code: "2033", point: { x: 1e3, y: 300 }, rotate: 675, lock: true }
]);
var createStaticCars = () => StaticCarDefs.map((def) => createCarShape(def));
var testConfig = {
seed: 20240214,
debug: false,
shapeCount: 4e3,
grid: { rows: 4, cols: 4, gap: 100 },
padding: 60,
car: {
types: ["CarForklift", "CarConveyor", "CarTugger", "CarCarrier"],
pointX: 0,
pointY: 0,
rotate: 0,
count: 900,
row: 30,
space: 50
}
};
var testState = {
carFrame: [],
staticCars: null,
carLoop: { frameId: 0, interval: 20, lastTick: 0, callback: noop }
};
var testUtil = {
log: (...args) => {
if (page.testConfig.debug) {
console.log(...args);
}
},
rand: () => {
page.testConfig.seed = page.testConfig.seed * 1664525 + 1013904223 >>> 0;
return page.testConfig.seed / 4294967296;
},
randInt: (min, max) => {
if (max <= min) return min;
return Math.floor(page.testUtil.rand() * (max - min + 1)) + min;
},
measure: (label, fn = noop) => {
const start = performance.now();
const result = fn();
const cost = performance.now() - start;
page.testUtil.log(`[测试] ${label}: ${cost.toFixed(2)}毫秒`);
return result;
},
scatterPoints: (count, options = {}) => {
const size = page.panel.map.base.size;
const safeCount = Math.max(1, Number.isFinite(count) ? Math.floor(count) : 1);
const padding = Number.isFinite(options.padding) ? options.padding : page.testConfig.padding;
const usableW = Math.max(1, size.w - padding * 2);
const usableH = Math.max(1, size.h - padding * 2);
const cols = Math.max(1, Math.ceil(Math.sqrt(safeCount * usableW / usableH)));
const rows = Math.max(1, Math.ceil(safeCount / cols));
const gapX = usableW / cols;
const gapY = usableH / rows;
const jitterRatio = Number.isFinite(options.jitter) ? options.jitter : 0.35;
const jitterX = Math.max(2, Math.floor(gapX * jitterRatio));
const jitterY = Math.max(2, Math.floor(gapY * jitterRatio));
const cells = [];
for (let r = 0; r < rows; r++) {
for (let c = 0; c < cols; c++) {
cells.push({ r, c });
}
}
for (let i = cells.length - 1; i > 0; i--) {
const j = page.testUtil.randInt(0, i);
const tmp = cells[i];
cells[i] = cells[j];
cells[j] = tmp;
}
const points = [];
for (let i = 0; i < safeCount; i++) {
const cell = cells[i];
const x = padding + (cell.c + 0.5) * gapX + page.testUtil.randInt(-jitterX, jitterX);
const y = padding + (cell.r + 0.5) * gapY + page.testUtil.randInt(-jitterY, jitterY);
points.push({
x: Math.min(size.w - padding, Math.max(padding, Math.round(x))),
y: Math.min(size.h - padding, Math.max(padding, Math.round(y)))
});
}
return { points, gapX, gapY };
},
shuffleInPlace: (list = []) => {
for (let i = list.length - 1; i > 0; i--) {
const j = page.testUtil.randInt(0, i);
const tmp = list[i];
list[i] = list[j];
list[j] = tmp;
}
return list;
},
polyPoints: (x, y, size = 80) => [
{ x, y },
{ x: x + size, y },
{ x: x + size * 1.5, y: y + size * 0.7 },
{ x: x + size, y: y + size * 1.4 },
{ x, y: y + size * 1.4 }
],
pathPoints: (x, y, size = 80) => [
{ x, y },
{ x: x + size, y },
{ x: x + size * 1.5, y: y + size * 0.7 },
{ x: x + size, y: y + size * 1.4 },
{ x, y: y + size * 0.7 }
],
createRotateAdder: (panel, method, prefix, options = {}) => {
const formatCode = typeof options.formatCode === "function" ? options.formatCode : (i) => `${prefix}-${i}`;
return (point, i) => {
panel[method]({
code: { text: formatCode(i) },
base: { point, rotate: page.testUtil.randInt(0, 359) }
}, BatchAppendOptions);
};
},
addEdgeByIndex: (panel, codePrefix, i, startNode, endNode, options = BatchAppendOptions) => {
if (i % 4 === 0) {
panel.addEdgeBeeline({
code: { text: `${codePrefix}-EL-${i}` },
base: { startNode, endNode }
}, options);
return;
}
if (i % 4 === 1) {
panel.addEdgeArc({
code: { text: `${codePrefix}-EA-${i}` },
base: {
startNode,
endNode,
p1: { x: startNode.base.point.x, y: endNode.base.point.y }
}
}, options);
return;
}
if (i % 4 === 2) {
panel.addEdgeQuadratic({
code: { text: `${codePrefix}-EQ-${i}` },
base: {
startNode,
endNode,
p1: { x: endNode.base.point.x, y: startNode.base.point.y }
}
}, options);
return;
}
panel.addEdgeBezier({
code: { text: `${codePrefix}-EB-${i}` },
base: {
startNode,
endNode,
p1: { x: startNode.base.point.x + 40, y: startNode.base.point.y - 40 },
p2: { x: endNode.base.point.x - 40, y: endNode.base.point.y + 40 }
}
}, options);
},
addRandomEdges: (panel, nodes, edgeCount, codePrefix, options = BatchAppendOptions) => {
if (!Array.isArray(nodes) || nodes.length < 2) return;
const max = nodes.length - 1;
for (let i = 0; i < edgeCount; i++) {
const startIndex = page.testUtil.randInt(0, max);
let endIndex = page.testUtil.randInt(0, max);
if (endIndex === startIndex) {
endIndex = (startIndex + 1) % nodes.length;
}
const startNode = nodes[startIndex];
const endNode = nodes[endIndex];
page.testUtil.addEdgeByIndex(panel, codePrefix, i, startNode, endNode, options);
}
},
withPerfBatch: (panel, action) => panel.withBatch(action),
measureBatchAdd: (panel, points, adders, label) => {
page.testUtil.measure(label, () => {
page.testUtil.withPerfBatch(panel, () => {
for (let i = 0; i < points.length; i++) {
adders[i % adders.length](points[i], i);
}
});
});
},
measureBatchEdges: (panel, edgeCount, codePrefix, label) => {
const nodes = panel.nodeShapes;
const safeEdgeCount = Math.min(nodes.length * 2, edgeCount);
if (nodes.length < 2 || safeEdgeCount <= 0) return;
page.testUtil.measure(label, () => {
page.testUtil.withPerfBatch(panel, () => {
page.testUtil.addRandomEdges(panel, nodes, safeEdgeCount, codePrefix);
});
});
},
createSizedAdder: (panel, method, prefix, sizeFactory, rotateFactory, options = BatchAppendOptions) => (point, i) => {
panel[method]({
code: { text: `${prefix}-${i}` },
base: { point, size: sizeFactory(), rotate: rotateFactory() }
}, options);
},
createPolyAdder: (panel, method, prefix, pointsBuilder, sizeFactory, rotateFactory, options = BatchAppendOptions) => (point, i) => {
const size = sizeFactory();
panel[method]({
code: { text: `${prefix}-${i}` },
base: { point, points: pointsBuilder(point.x, point.y, size), closed: true, rotate: rotateFactory() }
}, options);
},
ensureStaticCars: () => page.testState.staticCars ?? (page.testState.staticCars = createStaticCars()),
ensureCarFrame: () => {
const carConfig = page.testConfig.car;
const staticCars = page.testUtil.ensureStaticCars();
const frame = page.testState.carFrame;
frame.length = carConfig.count + staticCars.length;
for (let i = 0; i < carConfig.count; i++) {
const code = createCarCode(i);
const type = carConfig.types[i % carConfig.types.length];
let car = frame[i];
if (!car || car.code?.text !== code) {
car = createCarShape({ type, code });
frame[i] = car;
} else {
car.type = type;
}
}
for (let i = 0; i < staticCars.length; i++) {
frame[carConfig.count + i] = staticCars[i];
}
return frame;
},
buildCarFrame: (panel) => {
const size = panel.map.base.size;
const carConfig = page.testConfig.car;
const cars = page.testUtil.ensureCarFrame();
const { row, space } = carConfig;
carConfig.pointX = carConfig.pointX + 1 > size.w ? 0 : carConfig.pointX + 1;
carConfig.pointY = carConfig.pointY + 1 > size.h ? 0 : carConfig.pointY + 1;
carConfig.rotate = carConfig.rotate + 1 > 359 ? 0 : carConfig.rotate + 1;
for (let i = 0; i < carConfig.count; i++) {
const col = i % row;
const rowIndex = Math.floor(i / row);
const type = carConfig.types[i % carConfig.types.length];
const car = cars[i];
car.type = type;
setCarTransform(car, carConfig.pointX - col * space, carConfig.pointY - rowIndex * space, carConfig.rotate);
}
return cars;
},
resetSeed: (seed) => {
if (Number.isFinite(seed)) {
page.testConfig.seed = seed;
}
},
resetPanel: (options = {}) => {
page.testUtil.carStop();
if (options.clear !== false) {
page.panel.clearShapes();
}
page.panel.clearActiveShape();
page.panel.clearHoverShape();
page.panel.clearMarkerShape();
},
carStart: (callback, interval = 20) => {
page.testUtil.carStop();
const loop = page.testState.carLoop;
loop.callback = typeof callback === "function" ? callback : noop;
loop.interval = Number.isFinite(interval) && interval > 0 ? interval : 20;
loop.lastTick = 0;
const tick = (time) => {
if (!loop.frameId) return;
if (loop.lastTick === 0 || time - loop.lastTick >= loop.interval) {
loop.lastTick = time;
loop.callback();
if (!loop.frameId) return;
}
loop.frameId = window.requestAnimationFrame(tick);
};
loop.frameId = window.requestAnimationFrame(tick);
},
carStop: () => {
const loop = page.testState.carLoop;
if (loop.frameId) window.cancelAnimationFrame(loop.frameId);
loop.frameId = 0;
loop.lastTick = 0;
loop.callback = noop;
}
};
Object.assign(page, { testConfig, testState, testUtil });
var testActions = {
test1: () => {
page.testUtil.log("测试1:图形");
page.testUtil.resetPanel();
const panel = page.panel;
const startX = 200;
const startY = 200;
const gapX = 220;
const gapY = 180;
const polyPoints = (x, y) => [{ x, y }, { x: x + 120, y }, { x: x + 180, y: y + 90 }, { x: x + 120, y: y + 180 }, { x, y: y + 180 }];
const pathPoints = (x, y) => [{ x, y }, { x: x + 120, y }, { x: x + 180, y: y + 90 }, { x: x + 120, y: y + 180 }, { x, y: y + 90 }];
panel.addNodeRect({ code: { text: "T10-N-Rect" }, base: { point: { x: startX, y: startY }, size: { w: 120, h: 80 }, rotate: 5 } });
panel.addNodeEllipse({ code: { text: "T10-N-Ellipse" }, base: { point: { x: startX + gapX, y: startY }, size: { w: 120, h: 80 }, rotate: 10 } });
panel.addNodePoly({ code: { text: "T10-N-Poly" }, base: { point: { x: startX + gapX * 2, y: startY }, points: polyPoints(startX + gapX * 2, startY), closed: true, rotate: 15 } });
panel.addNodePath({ code: { text: "T10-N-Path" }, base: { point: { x: startX + gapX * 3, y: startY }, points: pathPoints(startX + gapX * 3, startY), closed: true, rotate: 20 } });
panel.addZoneRect({ code: { text: "T10-Z-Rect" }, base: { point: { x: startX, y: startY + gapY }, size: { w: 140, h: 90 }, rotate: 5 } });
panel.addZoneEllipse({ code: { text: "T10-Z-Ellipse" }, base: { point: { x: startX + gapX, y: startY + gapY }, size: { w: 140, h: 90 }, rotate: 10 } });
panel.addZonePoly({ code: { text: "T10-Z-Poly" }, base: { point: { x: startX + gapX * 2, y: startY + gapY }, points: polyPoints(startX + gapX * 2, startY + gapY), closed: true, rotate: 15 } });
panel.addZonePath({ code: { text: "T10-Z-Path" }, base: { point: { x: startX + gapX * 3, y: startY + gapY }, points: pathPoints(startX + gapX * 3, startY + gapY), closed: true, rotate: 20 } });
panel.addTagRect({ code: { text: "T10-T-Rect" }, base: { point: { x: startX, y: startY + gapY * 2 }, size: { w: 140, h: 90 }, rotate: 5 } });
panel.addTagEllipse({ code: { text: "T10-T-Ellipse" }, base: { point: { x: startX + gapX, y: startY + gapY * 2 }, size: { w: 140, h: 90 }, rotate: 10 } });
panel.addTagPoly({ code: { text: "T10-T-Poly" }, base: { point: { x: startX + gapX * 2, y: startY + gapY * 2 }, points: polyPoints(startX + gapX * 2, startY + gapY * 2), closed: true, rotate: 15 } });
panel.addTagPath({ code: { text: "T10-T-Path" }, base: { point: { x: startX + gapX * 3, y: startY + gapY * 2 }, points: pathPoints(startX + gapX * 3, startY + gapY * 2), closed: true, rotate: 20 } });
const nodeRect = panel.getNode({ code: { text: "T10-N-Rect" } });
const nodeEllipse = panel.getNode({ code: { text: "T10-N-Ellipse" } });
const nodePoly = panel.getNode({ code: { text: "T10-N-Poly" } });
const nodePath = panel.getNode({ code: { text: "T10-N-Path" } });
panel.addEdgeBeeline({ code: { text: "T10-E-Line" }, base: { lineWidth: 3, startNode: nodeRect, endNode: nodeEllipse } });
panel.addEdgeArc({ code: { text: "T10-E-Arc" }, base: { lineWidth: 3, startNode: nodeEllipse, endNode: nodePoly, p1: { x: startX + gapX * 1.5, y: startY - 100 } } });
panel.addEdgeQuadratic({ code: { text: "T10-E-Quadratic" }, base: { lineWidth: 3, startNode: nodePoly, endNode: nodePath, p1: { x: startX + gapX * 2.5, y: startY + 120 } } });
panel.addEdgeBezier({ code: { text: "T10-E-Bezier" }, base: { lineWidth: 3, startNode: nodePath, endNode: nodeRect, p1: { x: startX + gapX * 2, y: startY + 260 }, p2: { x: startX + gapX * 0.5, y: startY + 260 } } });
panel.addCarForklift({ code: { text: "T10-C-Forklift" }, name: { text: "Forklift" }, base: { point: { x: startX, y: startY + gapY * 3 }, rotate: 45 } });
panel.addCarConveyor({ code: { text: "T10-C-Conveyor" }, name: { text: "Conveyor" }, base: { point: { x: startX + gapX, y: startY + gapY * 3 }, rotate: 90 } });
panel.addCarTugger({ code: { text: "T10-C-Tugger" }, name: { text: "Tugger" }, base: { point: { x: startX + gapX * 2, y: startY + gapY * 3 }, rotate: 135 } });
panel.addCarCarrier({ code: { text: "T10-C-Carrier" }, name: { text: "Carrier" }, base: { point: { x: startX + gapX * 3, y: startY + gapY * 3 }, rotate: 180 } });
},
test2: () => {
page.testUtil.log("测试2:车辆");
const panel = page.panel;
const cars = page.testUtil.buildCarFrame(panel);
panel.addOrUpdateOrDeleteCars(cars);
},
test3: () => {
page.testUtil.log("测试3:运动");
page.testUtil.carStart(testActions.test2, 20);
},
test4: () => {
page.testUtil.log("测试4:停止");
page.testUtil.carStop();
page.testConfig.car.pointX = 0;
page.testConfig.car.pointY = 0;
page.testConfig.car.rotate = 0;
},
test5: () => {
page.testUtil.log("测试5:轨迹");
page.testUtil.resetPanel();
const panel = page.panel;
panel.addNodeRect({ code: { text: "1" }, base: { point: { x: 300, y: 200 } } });
panel.addNodeRect({ code: { text: "2" }, base: { point: { x: 400, y: 200 } } });
panel.addNodeRect({ code: { text: "3" }, base: { point: { x: 500, y: 200 } } });
panel.addNodeRect({ code: { text: "4" }, base: { point: { x: 600, y: 200 } } });
panel.addNodeEllipse({ code: { text: "5" }, base: { point: { x: 300, y: 300 } } });
panel.addNodeEllipse({ code: { text: "6" }, base: { point: { x: 400, y: 300 } } });
panel.addNodeEllipse({ code: { text: "7" }, base: { point: { x: 500, y: 300 } } });
panel.addNodeEllipse({ code: { text: "8" }, base: { point: { x: 600, y: 300 } } });
panel.addNodeRect({ code: { text: "9" }, base: { point: { x: 300, y: 400 } } });
panel.addNodeRect({ code: { text: "10" }, base: { point: { x: 400, y: 400 } } });
panel.addNodeRect({ code: { text: "11" }, base: { point: { x: 500, y: 400 } } });
panel.addNodeRect({ code: { text: "12" }, base: { point: { x: 600, y: 400 } } });
panel.addNodeEllipse({ code: { text: "13" }, base: { point: { x: 300, y: 500 } } });
panel.addNodeEllipse({ code: { text: "14" }, base: { point: { x: 400, y: 500 } } });
panel.addNodeEllipse({ code: { text: "15" }, base: { point: { x: 500, y: 500 } } });
panel.addNodeEllipse({ code: { text: "16" }, base: { point: { x: 600, y: 500 } } });
panel.addEdgeBeeline({ code: { text: "1-2" }, base: { lineWidth: 4, strokeStyle: "#FFFFFF", startNode: panel.getNode({ code: { text: "1" } }), endNode: panel.getNode({ code: { text: "2" } }) } });
panel.addEdgeBeeline({ code: { text: "3-4" }, base: { lineWidth: 4, strokeStyle: "#FFFFFF", startNode: panel.getNode({ code: { text: "3" } }), endNode: panel.getNode({ code: { text: "4" } }) } });
panel.addEdgeArc({ code: { text: "5-6" }, base: { lineWidth: 4, strokeStyle: "#FFFFFF", startNode: panel.getNode({ code: { text: "5" } }), endNode: panel.getNode({ code: { text: "6" } }) } });
panel.addEdgeArc({ code: { text: "7-8" }, base: { lineWidth: 4, strokeStyle: "#FFFFFF", startNode: panel.getNode({ code: { text: "7" } }), endNode: panel.getNode({ code: { text: "8" } }) } });
panel.addEdgeQuadratic({ code: { text: "9-10" }, base: { lineWidth: 4, strokeStyle: "#FFFFFF", startNode: panel.getNode({ code: { text: "9" } }), endNode: panel.getNode({ code: { text: "10" } }) } });
panel.addEdgeQuadratic({ code: { text: "11-12" }, base: { lineWidth: 4, strokeStyle: "#FFFFFF", startNode: panel.getNode({ code: { text: "11" } }), endNode: panel.getNode({ code: { text: "12" } }) } });
panel.addEdgeBezier({ code: { text: "13-14" }, base: { lineWidth: 4, strokeStyle: "#FFFFFF", startNode: panel.getNode({ code: { text: "13" } }), endNode: panel.getNode({ code: { text: "14" } }) } });
panel.addEdgeBezier({ code: { text: "15-16" }, base: { lineWidth: 4, strokeStyle: "#FFFFFF", startNode: panel.getNode({ code: { text: "15" } }), endNode: panel.getNode({ code: { text: "16" } }) } });
panel.addEdgeBeeline({ code: { text: "1-5" }, base: { lineWidth: 4, strokeStyle: "#FFFFFF", startNode: panel.getNode({ code: { text: "1" } }), endNode: panel.getNode({ code: { text: "5" } }) } });
panel.addEdgeBeeline({ code: { text: "5-9" }, base: { lineWidth: 4, strokeStyle: "#FFFFFF", startNode: panel.getNode({ code: { text: "5" } }), endNode: panel.getNode({ code: { text: "9" } }) } });
panel.addEdgeBeeline({ code: { text: "9-13" }, base: { lineWidth: 4, strokeStyle: "#FFFFFF", startNode: panel.getNode({ code: { text: "9" } }), endNode: panel.getNode({ code: { text: "13" } }) } });
panel.addEdgeArc({ code: { text: "2-6" }, base: { lineWidth: 4, strokeStyle: "#FFFFFF", startNode: panel.getNode({ code: { text: "2" } }), endNode: panel.getNode({ code: { text: "6" } }) } });
panel.addEdgeArc({ code: { text: "6-10" }, base: { lineWidth: 4, strokeStyle: "#FFFFFF", startNode: panel.getNode({ code: { text: "6" } }), endNode: panel.getNode({ code: { text: "10" } }) } });
panel.addEdgeArc({ code: { text: "10-14" }, base: { lineWidth: 4, strokeStyle: "#FFFFFF", startNode: panel.getNode({ code: { text: "10" } }), endNode: panel.getNode({ code: { text: "14" } }) } });
panel.addEdgeQuadratic({ code: { text: "3-7" }, base: { lineWidth: 4, strokeStyle: "#FFFFFF", startNode: panel.getNode({ code: { text: "3" } }), endNode: panel.getNode({ code: { text: "7" } }) } });
panel.addEdgeQuadratic({ code: { text: "7-11" }, base: { lineWidth: 4, strokeStyle: "#FFFFFF", startNode: panel.getNode({ code: { text: "7" } }), endNode: panel.getNode({ code: { text: "11" } }) } });
panel.addEdgeQuadratic({ code: { text: "11-15" }, base: { lineWidth: 4, strokeStyle: "#FFFFFF", startNode: panel.getNode({ code: { text: "11" } }), endNode: panel.getNode({ code: { text: "15" } }) } });
panel.addEdgeBezier({ code: { text: "4-8" }, base: { lineWidth: 4, strokeStyle: "#FFFFFF", startNode: panel.getNode({ code: { text: "4" } }), endNode: panel.getNode({ code: { text: "8" } }) } });
panel.addEdgeBezier({ code: { text: "8-12" }, base: { lineWidth: 4, strokeStyle: "#FFFFFF", startNode: panel.getNode({ code: { text: "8" } }), endNode: panel.getNode({ code: { text: "12" } }) } });
panel.addEdgeBezier({ code: { text: "12-16" }, base: { lineWidth: 4, strokeStyle: "#FFFFFF", startNode: panel.getNode({ code: { text: "12" } }), endNode: panel.getNode({ code: { text: "16" } }) } });
panel.addOrUpdateCar({
type: "CarForklift",
code: { text: "9000", enable: true },
name: { text: "第[9000]号车", enable: true },
lock: { enable: true },
base: {
point: panel.getNode({ code: { text: "5" } }).base.point,
rotate: 45,
carEdges: [
{ code: { text: "1-2" }, type: "Prev", process: 1 },
{ code: { text: "2-6" }, type: "Prev", process: 1 },
{ code: { text: "5-6" }, type: "Prev", process: 1 },
{ code: { text: "5-9" }, type: "Curr", process: 0.5 },
{ code: { text: "9-10" }, type: "Curr", process: 0.5 },
{ code: { text: "10-14" }, type: "Next", process: 0 },
{ code: { text: "13-14" }, type: "Next", process: 0 }
],
carNodes: [
{ code: { text: "1" }, type: "Prev", process: 1 },
{ code: { text: "2" }, type: "Prev", process: 1 },
{ code: { text: "6" }, type: "Prev", process: 1 },
{ code: { text: "5" }, type: "Curr", process: 0.5 },
{ code: { text: "9" }, type: "Curr", process: 0.5 },
{ code: { text: "10" }, type: "Curr", process: 0.5 },
{ code: { text: "14" }, type: "Next", process: 0 },
{ code: { text: "13" }, type: "Next", process: 0 }
]
}
});
panel.addOrUpdateCar({
type: "CarConveyor",
code: { text: "9001", enable: true },
name: { text: "第[9001]号车", enable: true },
base: {
point: panel.getNode({ code: { text: "7" } }).base.point,
rotate: 135,
carEdges: [
{ code: { text: "3-4" }, type: "Prev", process: 1 },
{ code: { text: "3-7" }, type: "Prev", process: 1 },
{ code: { text: "7-8" }, type: "Curr", process: 0.5 },
{ code: { text: "8-12" }, type: "Curr", process: 0.5 },
{ code: { text: "11-12" }, type: "Next", process: 0 },
{ code: { text: "11-15" }, type: "Next", process: 0 },
{ code: { text: "15-16" }, type: "Next", process: 0 }
],
carNodes: [
{ code: { text: "4" }, type: "Prev", process: 1 },
{ code: { text: "3" }, type: "Prev", process: 1 },
{ code: { text: "7" }, type: "Curr", process: 0.5 },
{ code: { text: "8" }, type: "Curr", process: 0.5 },
{ code: { text: "12" }, type: "Curr", process: 0.5 },
{ code: { text: "11" }, type: "Next", process: 0 },
{ code: { text: "15" }, type: "Next", process: 0 },
{ code: { text: "16" }, type: "Next", process: 0 }
]
}
});
},
test6: () => {
page.testUtil.log("测试6:处理");
page.testUtil.resetPanel();
const panel = page.panel;
panel.addNodeRect({ code: { text: "T11-N1" }, base: { point: { x: 200, y: 200 }, size: { w: 120, h: 80 } } });
panel.addNodeEllipse({ code: { text: "T11-N2" }, base: { point: { x: 420, y: 200 }, size: { w: 120, h: 80 } } });
panel.updateNode({ code: { text: "T11-N1", font: "16px Arial" }, name: { text: "Node-1", font: "14px Arial" }, base: { point: { x: 240, y: 220 }, size: { w: 140, h: 90 }, rotate: 12 } });
panel.updateNode({ code: { text: "T11-N2" }, base: { point: { x: 460, y: 220 }, rotate: 18 } });
panel.addEdgeBeeline({ code: { text: "T11-E1" }, base: { lineWidth: 4, startNode: panel.getNode({ code: { text: "T11-N1" } }), endNode: panel.getNode({ code: { text: "T11-N2" } }) } });
panel.updateEdge({ code: { text: "T11-E1" }, base: { lineWidth: 6 } });
panel.addZoneRect({ code: { text: "T11-Z1" }, base: { point: { x: 200, y: 380 }, size: { w: 160, h: 90 } } });
panel.updateZone({ code: { text: "T11-Z1" }, base: { point: { x: 220, y: 400 }, rotate: 15 } });
panel.addTagEllipse({ code: { text: "T11-T1" }, base: { point: { x: 420, y: 380 }, size: { w: 140, h: 90 } } });
panel.updateTag({ code: { text: "T11-T1" }, name: { text: "Tag-1" }, base: { rotate: 25 } });
panel.addCarForklift({ code: { text: "T11-C1" }, base: { point: { x: 640, y: 380 }, rotate: 0 } });
panel.updateCar({ code: { text: "T11-C1" }, base: { rotate: 45 } });
panel.deleteTag({ code: { text: "T11-T1" } });
panel.deleteZone({ code: { text: "T11-Z1" } });
panel.deleteEdge({ code: { text: "T11-E1" } });
panel.deleteCar({ code: { text: "T11-C1" } });
panel.deleteNode({ code: { text: "T11-N2" } });
panel.deleteNode({ code: { text: "T11-N1" } });
},
test7: () => {
page.testUtil.log("测试7:流程");
page.testUtil.resetPanel();
const panel = page.panel;
const baseX = 200;
const baseY = 200;
panel.addNodeRect({ code: { text: "T14-N1" }, base: { point: { x: baseX, y: baseY }, size: { w: 100, h: 70 } } });
panel.addNodeEllipse({ code: { text: "T14-N2" }, base: { point: { x: baseX + 200, y: baseY }, size: { w: 100, h: 70 } } });
panel.addEdgeBeeline({ code: { text: "T14-E1" }, base: { lineWidth: 4, startNode: panel.getNode({ code: { text: "T14-N1" } }), endNode: panel.getNode({ code: { text: "T14-N2" } }) } });
panel.addZoneRect({ code: { text: "T14-Z1" }, base: { point: { x: baseX, y: baseY + 200 }, size: { w: 140, h: 80 } } });
panel.addTagRect({ code: { text: "T14-T1" }, base: { point: { x: baseX + 200, y: baseY + 200 }, size: { w: 140, h: 80 } } });
panel.addCarForklift({ code: { text: "T14-C1" }, base: { point: { x: baseX + 400, y: baseY + 200 }, rotate: 30 } });
panel.addNodeRect({ code: { text: "T15-N1", pointRatio: { w: -0.5, h: -0.5 } }, name: { text: "T15-N2", pointRatio: { w: 0.5, h: 0.5 } }, base: { point: { x: baseX + 500, y: baseY - 100 }, size: { w: 100, h: 100 } } });
panel.addZoneRect({ code: { text: "T15-Z1", pointRatio: { w: 0, h: -0.5 } }, name: { text: "T15-Z2", pointRatio: { w: 0, h: 0.5 } }, base: { point: { x: baseX + 500, y: baseY }, size: { w: 150, h: 150 } } });
panel.addTagRect({ code: { text: "T15-T1", pointRatio: { w: -0.5, h: 0 } }, name: { text: "T15-T2", pointRatio: { w: 0.5, h: 0 } }, base: { point: { x: baseX + 500, y: baseY + 200 }, size: { w: 200, h: 200 } } });
panel.addNodeEllipse({ code: { text: "T16-N1", pointRatio: { w: 0, h: 0 } }, name: { text: "T16-N2", pointRatio: { w: 0, h: 0 } }, base: { point: { x: baseX, y: baseY + 400 }, size: { w: 100, h: 100 } } });
panel.addZoneEllipse({ code: { text: "T16-Z1", pointRatio: { w: 0.5, h: 0 } }, name: { text: "T16-Z2", pointRatio: { w: -0.5, h: 0 } }, base: { point: { x: baseX + 100, y: baseY + 400 }, size: { w: 150, h: 150 } } });
panel.addTagEllipse({ code: { text: "T16-T1", pointRatio: { w: 0.5, h: 0.5 } }, name: { text: "T16-T2", pointRatio: { w: -0.5, h: -0.5 } }, base: { point: { x: baseX + 300, y: baseY + 400 }, size: { w: 200, h: 200 } } });
panel.setModeEdit();
panel.setSwitchGrid();
panel.setSwitchInfo();
panel.setSwitchArea();
panel.setSwitchZoom();
panel.setSwitchCarRoute();
panel.setSwitchCarEdges();
panel.setSwitchCarNodes();
panel.setSwitchFixed();
panel.setSwitchFixedCode();
panel.setSwitchFixedName();
panel.setScalingAdapt();
panel.setScalingNormal();
panel.setSwitchInfo();
panel.setSwitchArea();
panel.setSwitchZoom();
panel.addActiveAction((e) => e.code && e.code.text === "T14-N1");
panel.switchActiveAction((e) => e.code && e.code.text === "T14-E1");
panel.addActiveAction((e) => e.code && e.code.text === "T14-Z1");
panel.addActiveAction((e) => e.code && e.code.text === "T14-T1");
panel.addActiveAction((e) => e.code && e.code.text === "T14-C1");
page.updateStatusBar();
},
test8: (count) => {
page.testUtil.log("测试8:性能");
page.testUtil.resetSeed(Date.now());
const panel = page.panel;
const shapeCount = Math.max(0, Math.floor(Number.isFinite(count) ? count : page.testConfig.shapeCount));
const scatter = page.testUtil.scatterPoints(shapeCount, { jitter: 0.25 });
const adders = page.testUtil.shuffleInPlace([
page.testUtil.createRotateAdder(panel, "addNodeRect", "P-NR", { formatCode: (i) => `P-NR-${i.toString().padStart(4, "0")}` }),
page.testUtil.createRotateAdder(panel, "addNodeEllipse", "P-NE", { formatCode: (i) => `P-NE-${i.toString().padStart(4, "0")}` }),
page.testUtil.createRotateAdder(panel, "addZoneRect", "P-ZR"),
page.testUtil.createRotateAdder(panel, "addZoneEllipse", "P-ZE"),
page.testUtil.createRotateAdder(panel, "addTagRect", "P-TR"),
page.testUtil.createRotateAdder(panel, "addTagEllipse", "P-TE"),
page.testUtil.createRotateAdder(panel, "addCarForklift", "P-CF"),
page.testUtil.createRotateAdder(panel, "addCarConveyor", "P-CC"),
page.testUtil.createRotateAdder(panel, "addCarTugger", "P-CT"),
page.testUtil.createRotateAdder(panel, "addCarCarrier", "P-CR")
]);
page.testUtil.measureBatchAdd(panel, scatter.points, adders, "perf:addShapes");
page.testUtil.measureBatchEdges(panel, Math.floor(shapeCount * 1.2), "P", "perf:addEdges");
},
test9: (count) => {
page.testUtil.log("测试9:压力");
page.testUtil.resetSeed(Date.now());
const panel = page.panel;
const shapeCount = Math.max(0, Math.floor(Number.isFinite(count) ? count : page.testConfig.shapeCount));
const scatter = page.testUtil.scatterPoints(shapeCount, { jitter: 0.25 });
const minGap = Math.min(scatter.gapX, scatter.gapY);
const baseSize = Math.max(50, Math.floor(minGap * 0.5));
const sizeJitter = Math.max(6, Math.floor(baseSize * 0.25));
const rectSize = () => {
const w = Math.max(36, baseSize + page.testUtil.randInt(-sizeJitter, sizeJitter));
const h = Math.max(28, Math.floor(w * 0.7));
return { w, h };
};
const polySize = () => Math.max(40, baseSize + page.testUtil.randInt(-sizeJitter, sizeJitter));
const rotate = () => page.testUtil.randInt(0, 359);
const adders = page.testUtil.shuffleInPlace([
page.testUtil.createSizedAdder(panel, "addNodeRect", "S-NR", rectSize, rotate),
page.testUtil.createSizedAdder(panel, "addNodeEllipse", "S-NE", rectSize, rotate),
page.testUtil.createPolyAdder(panel, "addNodePoly", "S-NP", page.testUtil.polyPoints, polySize, rotate),
page.testUtil.createPolyAdder(panel, "addNodePath", "S-NH", page.testUtil.pathPoints, polySize, rotate),
page.testUtil.createSizedAdder(panel, "addZoneRect", "S-ZR", rectSize, rotate),
page.testUtil.createSizedAdder(panel, "addZoneEllipse", "S-ZE", rectSize, rotate),
page.testUtil.createPolyAdder(panel, "addZonePoly", "S-ZP", page.testUtil.polyPoints, polySize, rotate),
page.testUtil.createPolyAdder(panel, "addZonePath", "S-ZH", page.testUtil.pathPoints, polySize, rotate),
page.testUtil.createSizedAdder(panel, "addTagRect", "S-TR", rectSize, rotate),
page.testUtil.createSizedAdder(panel, "addTagEllipse", "S-TE", rectSize, rotate),
page.testUtil.createPolyAdder(panel, "addTagPoly", "S-TP", page.testUtil.polyPoints, polySize, rotate),
page.testUtil.createPolyAdder(panel, "addTagPath", "S-TH", page.testUtil.pathPoints, polySize, rotate),
page.testUtil.createRotateAdder(panel, "addCarForklift", "S-CF"),
page.testUtil.createRotateAdder(panel, "addCarConveyor", "S-CC"),
page.testUtil.createRotateAdder(panel, "addCarTugger", "S-CT"),
page.testUtil.createRotateAdder(panel, "addCarCarrier", "S-CR")
]);
page.testUtil.measureBatchAdd(panel, scatter.points, adders, "stress:addShapes");
page.testUtil.measureBatchEdges(panel, 2e3, "S", "stress:addEdges");
}
};
panelNamespace.test = Object.freeze({
page,
config: page.testConfig,
util: page.testUtil,
names: Object.freeze(Object.keys(testActions)),
has(name) {
return typeof testActions[name] === "function";
},
stop() {
page.testUtil.carStop();
},
run(name, ...args) {
const handler = testActions[name];
if (typeof handler !== "function") {
throw new Error(`未找到测试方法:${name}`);
}
return handler(...args);
}
});
page.syncTestButtons?.();
})();