优化仿真求解性能并修复流量闭合问题(初版)

This commit is contained in:
ljz committed 2026-08-16 17:46:05 +08:00
1 parent 57b459bc72
commit 5332a788f3
55 files changed
+8973 -549

No files matched your search

+987 -262
View File
File diff suppressed because it is too large. Load diff
+39
View File
@@ -0,0 +1,39 @@
import { Background, BackgroundVariant } from "@xyflow/react";
export const CANVAS_GRID_SIZE = 18;
export type CanvasGridVisibility = {
lines: boolean;
dots: boolean;
};
type CanvasGridBackgroundProps = {
visibility: CanvasGridVisibility;
};
export function CanvasGridBackground({
visibility,
}: CanvasGridBackgroundProps) {
return (
<>
{visibility.lines ? (
<Background
color="#d6e0ea"
gap={CANVAS_GRID_SIZE * 5}
id="major-grid-lines"
lineWidth={1}
variant={BackgroundVariant.Lines}
/>
) : null}
{visibility.dots ? (
<Background
color="#c4d0dd"
gap={CANVAS_GRID_SIZE}
id="minor-grid-dots"
size={1}
variant={BackgroundVariant.Dots}
/>
) : null}
</>
);
}
+5 -2
View File
@@ -1,4 +1,4 @@
import { useLayoutEffect, useRef, useState } from "react";
import { memo, useLayoutEffect, useRef, useState } from "react";
import {
AmesimPnpl01Symbol,
@@ -665,7 +665,7 @@ export function componentSymbolVariantKey(
return definition.variantKey?.(parameters) ?? "";
}
export function ComponentSymbol({
function ComponentSymbolImpl({
symbol,
surface,
className,
@@ -752,3 +752,6 @@ export function ComponentSymbol({
</span>
);
}
export const ComponentSymbol = memo(ComponentSymbolImpl);
ComponentSymbol.displayName = "ComponentSymbol";
+37 -8
View File
@@ -20,15 +20,19 @@ import {
X,
} from "lucide-react";
import {
Background,
ConnectionLineType,
ConnectionMode,
Controls,
ReactFlow,
useReactFlow,
type Edge,
type Node,
type NodeTypes,
} from "@xyflow/react";
import {
CanvasGridBackground,
type CanvasGridVisibility,
} from "./CanvasGridBackground";
import { hasComponentSymbol } from "./ComponentSymbol";
import {
WorkspaceViewTabs,
type WorkspaceView,
@@ -52,6 +56,7 @@ type ResultNodeData = {
label: string;
componentType: string;
modelType: string;
symbol?: string;
ports: ResultPortDefinition[];
parameters: Record<string, number | string>;
parameterUnits?: Record<string, string>;
@@ -170,6 +175,7 @@ type SimulationResultFile = {
type SimulationResultsViewProps = {
snapshot: SimulationResultsSnapshot;
gridVisibility: CanvasGridVisibility;
nodeTypes: NodeTypes;
onViewChange: (view: WorkspaceView) => void;
onSnapshotLoad: (snapshot: SimulationResultsSnapshot) => void;
@@ -335,10 +341,12 @@ const RESULT_UNIT_OPTIONS: Record<string, ResultUnitOption[]> = {
export function SimulationResultsView({
snapshot,
gridVisibility,
nodeTypes,
onViewChange,
onSnapshotLoad,
}: SimulationResultsViewProps) {
const reactFlow = useReactFlow();
const resultStatus = simulationResultStatus(snapshot.result);
const [selectedNodeId, setSelectedNodeId] = useState<string | null>(
snapshot.project.nodes[0]?.id ?? null,
@@ -467,7 +475,15 @@ export function SimulationResultsView({
() =>
snapshot.project.nodes.map((node) => ({
...node,
className: "results-readonly-node",
className: [
"results-readonly-node",
hasComponentSymbol(node.data.symbol ?? node.data.componentType) ||
hasComponentSymbol(node.data.modelType)
? "component-icon-node"
: "",
]
.filter(Boolean)
.join(" "),
connectable: false,
draggable: false,
focusable: true,
@@ -1134,7 +1150,23 @@ export function SimulationResultsView({
<section className="results-system-panel">
<div className="results-section-heading">
<strong>系统图</strong>
<span>{snapshot.project.nodes.length} 个组件</span>
<div className="results-system-heading-tools">
<span>{snapshot.project.nodes.length} 个组件</span>
<button
aria-label="适应系统图窗口"
onClick={() => {
void reactFlow.fitView({
duration: 180,
minZoom: 0.1,
padding: 0.18,
});
}}
title="适应窗口"
type="button"
>
<Scaling aria-hidden="true" size={14} strokeWidth={1.8} />
</button>
</div>
</div>
<div className="results-system-canvas">
<ReactFlow
@@ -1166,10 +1198,7 @@ export function SimulationResultsView({
fitOnMount
requestKey={snapshot.id}
/>
<Background gap={18} />
<Controls
fitViewOptions={{ duration: 180, minZoom: 0.1, padding: 0.18 }}
/>
<CanvasGridBackground visibility={gridVisibility} />
</ReactFlow>
</div>
</section>
+38
View File
@@ -2138,6 +2138,32 @@ textarea {
font-size: 11px;
}
.results-system-heading-tools {
display: flex;
align-items: center;
gap: 8px;
}
.results-system-heading-tools button {
display: grid;
width: 28px;
height: 28px;
padding: 0;
border: 1px solid transparent;
border-radius: 4px;
place-items: center;
color: #526172;
background: transparent;
cursor: pointer;
}
.results-system-heading-tools button:hover,
.results-system-heading-tools button:focus-visible {
border-color: #c5cfda;
color: #1d6fb8;
background: #ffffff;
}
.results-chart-heading {
position: relative;
z-index: 25;
@@ -2265,6 +2291,18 @@ textarea {
cursor: pointer;
}
.results-system-canvas .react-flow__node.component-icon-node,
.results-system-canvas .react-flow__node.component-icon-node .sim-node {
pointer-events: none !important;
}
.results-system-canvas
.react-flow__node.component-icon-node
.node-symbol-envelope {
cursor: pointer;
pointer-events: auto;
}
.results-system-canvas .react-flow__handle {
cursor: default;
pointer-events: none;