|
|
|
|
@@ -0,0 +1,361 @@
|
|
|
|
|
import { useMemo, useState } from 'react'
|
|
|
|
|
import { useNavigate } from 'react-router-dom'
|
|
|
|
|
import { processes } from '@/data'
|
|
|
|
|
|
|
|
|
|
interface Hotspot {
|
|
|
|
|
id: string
|
|
|
|
|
label: string
|
|
|
|
|
x: number
|
|
|
|
|
y: number
|
|
|
|
|
w: number
|
|
|
|
|
h: number
|
|
|
|
|
to: string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const svgStyles = `
|
|
|
|
|
.text { font-family: "Microsoft YaHei", "PingFang SC", sans-serif; font-size: 11px; fill: #333; text-anchor: middle; }
|
|
|
|
|
.group-title { font-size: 16px; font-weight: bold; }
|
|
|
|
|
.box { stroke-width: 1; rx: 4; ry: 4; }
|
|
|
|
|
.box-init { fill: #FFF9E6; stroke: #FAD266; }
|
|
|
|
|
.box-plan { fill: #EBF5FF; stroke: #91C7F2; }
|
|
|
|
|
.box-exec { fill: #F0F9EB; stroke: #C2E7B0; }
|
|
|
|
|
.box-moni { fill: #FFF9E6; stroke: #FAD266; }
|
|
|
|
|
.box-close { fill: #EBF5FF; stroke: #91C7F2; }
|
|
|
|
|
.box-red { fill: #FF0000; stroke: #CC0000; }
|
|
|
|
|
.text-white { fill: #FFFFFF; }
|
|
|
|
|
.arrow { stroke: #FF0000; stroke-width: 2; fill: none; }
|
|
|
|
|
.arrow-grey { stroke: #CCC; stroke-width: 1.5; fill: none; }
|
|
|
|
|
.marker { fill: #FF0000; }
|
|
|
|
|
.marker-grey { fill: #CCC; }
|
|
|
|
|
`
|
|
|
|
|
|
|
|
|
|
const staticSvgBody = `
|
|
|
|
|
<!-- 1. 启动过程组 -->
|
|
|
|
|
<rect x="20" y="20" width="100" height="350" class="box box-init" />
|
|
|
|
|
<rect x="30" y="30" width="80" height="40" class="box box-init" />
|
|
|
|
|
<text x="70" y="55" class="text group-title">启动</text>
|
|
|
|
|
<rect x="30" y="85" width="80" height="40" class="box" style="fill:white; stroke:#EEE;" />
|
|
|
|
|
<text x="70" y="110" class="text">10.1识别干系人</text>
|
|
|
|
|
<rect x="30" y="140" width="80" height="30" class="box box-red" />
|
|
|
|
|
<text x="70" y="159" class="text text-white">1.1制定项目章程</text>
|
|
|
|
|
|
|
|
|
|
<!-- 2. 规划过程组 -->
|
|
|
|
|
<rect x="130" y="20" width="450" height="350" class="box box-plan" />
|
|
|
|
|
<rect x="140" y="30" width="80" height="40" class="box" style="fill:#A0B7CC; stroke:none;" />
|
|
|
|
|
<text x="180" y="55" class="text group-title" style="fill:white;">规划</text>
|
|
|
|
|
|
|
|
|
|
<!-- 规划左侧列表 -->
|
|
|
|
|
<rect x="140" y="80" width="100" height="230" class="box" style="fill:#B8D5EB; stroke:none;" />
|
|
|
|
|
<text x="190" y="100" class="text">2.1规划范围管理</text>
|
|
|
|
|
<text x="190" y="123" class="text">3.1规划进度管理</text>
|
|
|
|
|
<text x="190" y="146" class="text">4.1规划成本管理</text>
|
|
|
|
|
<text x="190" y="169" class="text">5.1规划质量管理</text>
|
|
|
|
|
<text x="190" y="192" class="text">6.1规划资源管理</text>
|
|
|
|
|
<text x="190" y="215" class="text">7.1规划沟通管理</text>
|
|
|
|
|
<text x="190" y="238" class="text">8.1规划风险管理</text>
|
|
|
|
|
<text x="190" y="261" class="text">9.1规划采购管理</text>
|
|
|
|
|
<text x="190" y="284" class="text">10.2规划干系人</text>
|
|
|
|
|
|
|
|
|
|
<!-- 规划中部流程 -->
|
|
|
|
|
<rect x="250" y="30" width="70" height="30" class="box" style="fill:#C7E1F5; stroke:none;" />
|
|
|
|
|
<text x="285" y="49" class="text">2.2收集需求</text>
|
|
|
|
|
<path d="M320,45 L345,45" class="arrow-grey" marker-end="url(#arrowhead-grey)" />
|
|
|
|
|
<rect x="350" y="30" width="70" height="30" class="box" style="fill:#C7E1F5; stroke:none;" />
|
|
|
|
|
<text x="385" y="49" class="text">2.3定义范围</text>
|
|
|
|
|
<path d="M420,45 L445,45" class="arrow-grey" marker-end="url(#arrowhead-grey)" />
|
|
|
|
|
<rect x="450" y="30" width="70" height="30" class="box" style="fill:#C7E1F5; stroke:none;" />
|
|
|
|
|
<text x="485" y="49" class="text">2.4创建WBS</text>
|
|
|
|
|
<path d="M485,60 L485,85" class="arrow" marker-end="url(#arrowhead)" />
|
|
|
|
|
|
|
|
|
|
<rect x="250" y="90" width="70" height="35" class="box" style="fill:#C7E1F5; stroke:none;" />
|
|
|
|
|
<text x="285" y="102" class="text">6.2估算活动</text>
|
|
|
|
|
<text x="285" y="117" class="text">资源</text>
|
|
|
|
|
<path d="M285,125 L285,145" class="arrow" marker-end="url(#arrowhead)" />
|
|
|
|
|
|
|
|
|
|
<rect x="350" y="90" width="70" height="35" class="box" style="fill:#C7E1F5; stroke:none;" />
|
|
|
|
|
<text x="385" y="102" class="text">3.3排列活动</text>
|
|
|
|
|
<text x="385" y="117" class="text">顺序</text>
|
|
|
|
|
<path d="M350,107 L325,107" class="arrow-grey" marker-end="url(#arrowhead-grey)" />
|
|
|
|
|
|
|
|
|
|
<rect x="450" y="90" width="70" height="35" class="box" style="fill:#C7E1F5; stroke:none;" />
|
|
|
|
|
<text x="485" y="110" class="text">3.2定义活动</text>
|
|
|
|
|
<path d="M450,107 L425,107" class="arrow-grey" marker-end="url(#arrowhead-grey)" />
|
|
|
|
|
|
|
|
|
|
<rect x="250" y="150" width="70" height="35" class="box" style="fill:#C7E1F5; stroke:none;" />
|
|
|
|
|
<text x="285" y="162" class="text">3.4估算活动</text>
|
|
|
|
|
<text x="285" y="177" class="text">持续时间</text>
|
|
|
|
|
<path d="M320,167 L345,167" class="arrow-grey" marker-end="url(#arrowhead-grey)" />
|
|
|
|
|
|
|
|
|
|
<rect x="350" y="150" width="70" height="35" class="box" style="fill:#C7E1F5; stroke:none;" />
|
|
|
|
|
<text x="385" y="162" class="text">3.5制定进度</text>
|
|
|
|
|
<text x="385" y="177" class="text">计划</text>
|
|
|
|
|
<path d="M420,167 L445,167" class="arrow-grey" marker-end="url(#arrowhead-grey)" />
|
|
|
|
|
|
|
|
|
|
<rect x="450" y="150" width="70" height="35" class="box" style="fill:#C7E1F5; stroke:none;" />
|
|
|
|
|
<text x="485" y="167" class="text">4.2估算成本</text>
|
|
|
|
|
<path d="M485,185 L485,205" class="arrow" marker-end="url(#arrowhead)" />
|
|
|
|
|
|
|
|
|
|
<rect x="450" y="210" width="70" height="30" class="box" style="fill:#C7E1F5; stroke:none;" />
|
|
|
|
|
<text x="485" y="229" class="text">4.3制定预算</text>
|
|
|
|
|
|
|
|
|
|
<rect x="250" y="235" width="70" height="30" class="box" style="fill:#C7E1F5; stroke:none;" />
|
|
|
|
|
<text x="285" y="254" class="text">8.2识别风险</text>
|
|
|
|
|
<path d="M320,250 L345,250" class="arrow" marker-end="url(#arrowhead)" />
|
|
|
|
|
|
|
|
|
|
<rect x="350" y="235" width="70" height="35" class="box" style="fill:#C7E1F5; stroke:none;" />
|
|
|
|
|
<text x="385" y="247" class="text">8.3实施定性</text>
|
|
|
|
|
<text x="385" y="262" class="text">风险分析</text>
|
|
|
|
|
<path d="M420,250 L445,250" class="arrow" marker-end="url(#arrowhead)" />
|
|
|
|
|
|
|
|
|
|
<rect x="450" y="235" width="70" height="35" class="box" style="fill:#C7E1F5; stroke:none;" />
|
|
|
|
|
<text x="485" y="247" class="text">8.4实施定量</text>
|
|
|
|
|
<text x="485" y="262" class="text">风险分析</text>
|
|
|
|
|
<path d="M485,270 L485,285" class="arrow" marker-end="url(#arrowhead)" />
|
|
|
|
|
|
|
|
|
|
<rect x="450" y="290" width="70" height="35" class="box" style="fill:#C7E1F5; stroke:none;" />
|
|
|
|
|
<text x="485" y="302" class="text">8.5规划风险</text>
|
|
|
|
|
<text x="485" y="317" class="text">应对</text>
|
|
|
|
|
|
|
|
|
|
<rect x="140" y="325" width="430" height="30" class="box box-red" />
|
|
|
|
|
<text x="355" y="344" class="text text-white">1.2 制定项目管理计划</text>
|
|
|
|
|
|
|
|
|
|
<!-- 3. 执行过程组 -->
|
|
|
|
|
<rect x="590" y="20" width="220" height="350" class="box box-exec" />
|
|
|
|
|
<rect x="660" y="30" width="80" height="40" class="box" style="fill:#A5C294; stroke:none;" />
|
|
|
|
|
<text x="700" y="55" class="text group-title" style="fill:white;">执行</text>
|
|
|
|
|
|
|
|
|
|
<rect x="600" y="35" width="50" height="30" class="box" style="fill:#E2F0D9; stroke:none;" />
|
|
|
|
|
<text x="625" y="54" class="text" style="font-size:9px">6.3获取资源</text>
|
|
|
|
|
<path d="M625,65 L625,85" class="arrow" marker-end="url(#arrowhead)" />
|
|
|
|
|
|
|
|
|
|
<rect x="600" y="90" width="70" height="30" class="box" style="fill:#E2F0D9; stroke:none;" />
|
|
|
|
|
<text x="635" y="109" class="text">6.4建设团队</text>
|
|
|
|
|
<path d="M670,105 L695,105" class="arrow" marker-end="url(#arrowhead)" />
|
|
|
|
|
|
|
|
|
|
<rect x="700" y="90" width="70" height="30" class="box" style="fill:#E2F0D9; stroke:none;" />
|
|
|
|
|
<text x="735" y="109" class="text">6.5管理团队</text>
|
|
|
|
|
|
|
|
|
|
<rect x="600" y="140" width="70" height="35" class="box" style="fill:#E2F0D9; stroke:none;" />
|
|
|
|
|
<text x="635" y="152" class="text">8.6实施风险</text>
|
|
|
|
|
<text x="635" y="167" class="text">应对</text>
|
|
|
|
|
|
|
|
|
|
<rect x="700" y="140" width="70" height="30" class="box" style="fill:#E2F0D9; stroke:none;" />
|
|
|
|
|
<text x="735" y="159" class="text">9.2实施采购</text>
|
|
|
|
|
|
|
|
|
|
<rect x="600" y="190" width="70" height="30" class="box" style="fill:#E2F0D9; stroke:none;" />
|
|
|
|
|
<text x="635" y="209" class="text">7.2管理沟通</text>
|
|
|
|
|
|
|
|
|
|
<rect x="700" y="190" width="70" height="35" class="box" style="fill:#E2F0D9; stroke:none;" />
|
|
|
|
|
<text x="735" y="202" class="text">10.3干系人</text>
|
|
|
|
|
<text x="735" y="217" class="text">参与管理</text>
|
|
|
|
|
|
|
|
|
|
<rect x="600" y="245" width="200" height="30" class="box" style="fill:#E2F0D9; stroke:none;" />
|
|
|
|
|
<text x="700" y="264" class="text">5.2管理质量</text>
|
|
|
|
|
|
|
|
|
|
<rect x="600" y="285" width="80" height="35" class="box box-red" />
|
|
|
|
|
<text x="640" y="297" class="text text-white">1.4 管理项目</text>
|
|
|
|
|
<text x="640" y="312" class="text text-white">知识</text>
|
|
|
|
|
|
|
|
|
|
<rect x="600" y="325" width="200" height="30" class="box box-red" />
|
|
|
|
|
<text x="700" y="344" class="text text-white">1.3 指导与管理项目工作</text>
|
|
|
|
|
|
|
|
|
|
<!-- 4. 监控过程组 -->
|
|
|
|
|
<rect x="130" y="380" width="530" height="150" class="box box-moni" />
|
|
|
|
|
<rect x="140" y="470" width="80" height="40" class="box" style="fill:#FCDD8B; stroke:none;" />
|
|
|
|
|
<text x="180" y="495" class="text group-title">监控</text>
|
|
|
|
|
|
|
|
|
|
<g transform="translate(230, 390)">
|
|
|
|
|
<rect x="0" y="0" width="75" height="30" class="box" style="fill:#FFF2CC; stroke:none;" />
|
|
|
|
|
<text x="37" y="19" class="text">2.6控制范围</text>
|
|
|
|
|
<rect x="85" y="0" width="75" height="30" class="box" style="fill:#FFF2CC; stroke:none;" />
|
|
|
|
|
<text x="122" y="19" class="text">6.6控制资源</text>
|
|
|
|
|
<rect x="170" y="0" width="75" height="30" class="box" style="fill:#FFF2CC; stroke:none;" />
|
|
|
|
|
<text x="207" y="19" class="text">9.3控制采购</text>
|
|
|
|
|
<rect x="255" y="0" width="75" height="30" class="box" style="fill:#FFF2CC; stroke:none;" />
|
|
|
|
|
<text x="292" y="19" class="text">5.3控制质量</text>
|
|
|
|
|
|
|
|
|
|
<rect x="0" y="45" width="75" height="30" class="box" style="fill:#FFF2CC; stroke:none;" />
|
|
|
|
|
<text x="37" y="64" class="text">3.6控制进度</text>
|
|
|
|
|
<rect x="85" y="45" width="75" height="30" class="box" style="fill:#FFF2CC; stroke:none;" />
|
|
|
|
|
<text x="122" y="64" class="text">7.3监督沟通</text>
|
|
|
|
|
<rect x="170" y="45" width="85" height="35" class="box" style="fill:#FFF2CC; stroke:none;" />
|
|
|
|
|
<text x="212" y="57" class="text">10.4监督</text>
|
|
|
|
|
<text x="212" y="72" class="text">干系人参与</text>
|
|
|
|
|
|
|
|
|
|
<rect x="85" y="95" width="75" height="30" class="box" style="fill:#FFF2CC; stroke:none;" />
|
|
|
|
|
<text x="122" y="114" class="text">8.7监督风险</text>
|
|
|
|
|
<rect x="170" y="95" width="75" height="30" class="box" style="fill:#FFF2CC; stroke:none;" />
|
|
|
|
|
<text x="207" y="114" class="text">4.4控制成本</text>
|
|
|
|
|
<rect x="255" y="95" width="75" height="30" class="box" style="fill:#FFF2CC; stroke:none;" />
|
|
|
|
|
<text x="292" y="114" class="text">2.5确认范围</text>
|
|
|
|
|
</g>
|
|
|
|
|
|
|
|
|
|
<rect x="575" y="400" width="75" height="35" class="box box-red" />
|
|
|
|
|
<text x="612" y="412" class="text text-white">1.5监控项目</text>
|
|
|
|
|
<text x="612" y="427" class="text text-white">工作</text>
|
|
|
|
|
|
|
|
|
|
<rect x="575" y="445" width="75" height="35" class="box box-red" />
|
|
|
|
|
<text x="612" y="457" class="text text-white">1.6实施整体</text>
|
|
|
|
|
<text x="612" y="472" class="text text-white">变更控制</text>
|
|
|
|
|
|
|
|
|
|
<!-- 5. 收尾过程组 -->
|
|
|
|
|
<rect x="670" y="380" width="140" height="150" class="box box-close" />
|
|
|
|
|
<rect x="700" y="470" width="80" height="40" class="box" style="fill:#A0B7CC; stroke:none;" />
|
|
|
|
|
<text x="740" y="495" class="text group-title" style="fill:white;">收尾</text>
|
|
|
|
|
|
|
|
|
|
<rect x="690" y="400" width="100" height="35" class="box box-red" />
|
|
|
|
|
<text x="740" y="412" class="text text-white">1.7 结束项目</text>
|
|
|
|
|
<text x="740" y="427" class="text text-white">或阶段</text>
|
|
|
|
|
|
|
|
|
|
<!-- 核心流程箭头 -->
|
|
|
|
|
<path d="M110,155 L140,325" class="arrow" marker-end="url(#arrowhead)" />
|
|
|
|
|
<path d="M570,340 L590,340" class="arrow" marker-end="url(#arrowhead)" />
|
|
|
|
|
<path d="M700,355 L700,380 L612,380 L612,395" class="arrow" marker-end="url(#arrowhead)" />
|
|
|
|
|
<path d="M650,417 L685,417" class="arrow" marker-end="url(#arrowhead)" />
|
|
|
|
|
`
|
|
|
|
|
|
|
|
|
|
export function ProcessRoadmapPage() {
|
|
|
|
|
const navigate = useNavigate()
|
|
|
|
|
const [hoveredId, setHoveredId] = useState<string | null>(null)
|
|
|
|
|
|
|
|
|
|
const processIdByCode = useMemo(
|
|
|
|
|
() => new Map(processes.map((process) => [process.code, process.id])),
|
|
|
|
|
[]
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
const hotspots = useMemo<Hotspot[]>(() => {
|
|
|
|
|
const routeByCode = (code: string) => {
|
|
|
|
|
const processId = processIdByCode.get(code)
|
|
|
|
|
return processId ? `/process/${processId}` : '/process-matrix'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return [
|
|
|
|
|
{ id: '10.1', label: '10.1 识别干系人', x: 30, y: 85, w: 80, h: 40, to: routeByCode('10.1') },
|
|
|
|
|
{ id: '1.1', label: '1.1 制定项目章程', x: 30, y: 140, w: 80, h: 30, to: routeByCode('1.1') },
|
|
|
|
|
|
|
|
|
|
{ id: '2.1', label: '2.1 规划范围管理', x: 142, y: 87, w: 96, h: 20, to: routeByCode('2.1') },
|
|
|
|
|
{ id: '3.1', label: '3.1 规划进度管理', x: 142, y: 110, w: 96, h: 20, to: routeByCode('3.1') },
|
|
|
|
|
{ id: '4.1', label: '4.1 规划成本管理', x: 142, y: 133, w: 96, h: 20, to: routeByCode('4.1') },
|
|
|
|
|
{ id: '5.1', label: '5.1 规划质量管理', x: 142, y: 156, w: 96, h: 20, to: routeByCode('5.1') },
|
|
|
|
|
{ id: '6.1', label: '6.1 规划资源管理', x: 142, y: 179, w: 96, h: 20, to: routeByCode('6.1') },
|
|
|
|
|
{ id: '7.1', label: '7.1 规划沟通管理', x: 142, y: 202, w: 96, h: 20, to: routeByCode('7.1') },
|
|
|
|
|
{ id: '8.1', label: '8.1 规划风险管理', x: 142, y: 225, w: 96, h: 20, to: routeByCode('8.1') },
|
|
|
|
|
{ id: '9.1', label: '9.1 规划采购管理', x: 142, y: 248, w: 96, h: 20, to: routeByCode('9.1') },
|
|
|
|
|
{ id: '10.2', label: '10.2 规划相关方参与', x: 142, y: 271, w: 96, h: 20, to: routeByCode('10.2') },
|
|
|
|
|
|
|
|
|
|
{ id: '2.2', label: '2.2 收集需求', x: 250, y: 30, w: 70, h: 30, to: routeByCode('2.2') },
|
|
|
|
|
{ id: '2.3', label: '2.3 定义范围', x: 350, y: 30, w: 70, h: 30, to: routeByCode('2.3') },
|
|
|
|
|
{ id: '2.4', label: '2.4 创建WBS', x: 450, y: 30, w: 70, h: 30, to: routeByCode('2.4') },
|
|
|
|
|
{ id: '6.2', label: '6.2 估算活动资源', x: 250, y: 90, w: 70, h: 35, to: routeByCode('6.2') },
|
|
|
|
|
{ id: '3.3', label: '3.3 排列活动顺序', x: 350, y: 90, w: 70, h: 35, to: routeByCode('3.3') },
|
|
|
|
|
{ id: '3.2', label: '3.2 定义活动', x: 450, y: 90, w: 70, h: 35, to: routeByCode('3.2') },
|
|
|
|
|
{ id: '3.4', label: '3.4 估算活动持续时间', x: 250, y: 150, w: 70, h: 35, to: routeByCode('3.4') },
|
|
|
|
|
{ id: '3.5', label: '3.5 制定进度计划', x: 350, y: 150, w: 70, h: 35, to: routeByCode('3.5') },
|
|
|
|
|
{ id: '4.2', label: '4.2 估算成本', x: 450, y: 150, w: 70, h: 35, to: routeByCode('4.2') },
|
|
|
|
|
{ id: '4.3', label: '4.3 制定预算', x: 450, y: 210, w: 70, h: 30, to: routeByCode('4.3') },
|
|
|
|
|
{ id: '8.2', label: '8.2 识别风险', x: 250, y: 235, w: 70, h: 30, to: routeByCode('8.2') },
|
|
|
|
|
{ id: '8.3', label: '8.3 实施定性风险分析', x: 350, y: 235, w: 70, h: 35, to: routeByCode('8.3') },
|
|
|
|
|
{ id: '8.4', label: '8.4 实施定量风险分析', x: 450, y: 235, w: 70, h: 35, to: routeByCode('8.4') },
|
|
|
|
|
{ id: '8.5', label: '8.5 规划风险应对', x: 450, y: 290, w: 70, h: 35, to: routeByCode('8.5') },
|
|
|
|
|
{ id: '1.2', label: '1.2 制定项目管理计划', x: 140, y: 325, w: 430, h: 30, to: routeByCode('1.2') },
|
|
|
|
|
|
|
|
|
|
{ id: '6.3', label: '6.3 获取资源', x: 600, y: 35, w: 50, h: 30, to: routeByCode('6.3') },
|
|
|
|
|
{ id: '6.4', label: '6.4 建设团队', x: 600, y: 90, w: 70, h: 30, to: routeByCode('6.4') },
|
|
|
|
|
{ id: '6.5', label: '6.5 管理团队', x: 700, y: 90, w: 70, h: 30, to: routeByCode('6.5') },
|
|
|
|
|
{ id: '8.6', label: '8.6 实施风险应对', x: 600, y: 140, w: 70, h: 35, to: routeByCode('8.6') },
|
|
|
|
|
{ id: '9.2', label: '9.2 实施采购', x: 700, y: 140, w: 70, h: 30, to: routeByCode('9.2') },
|
|
|
|
|
{ id: '7.2', label: '7.2 管理沟通', x: 600, y: 190, w: 70, h: 30, to: routeByCode('7.2') },
|
|
|
|
|
{ id: '10.3', label: '10.3 管理相关方参与', x: 700, y: 190, w: 70, h: 35, to: routeByCode('10.3') },
|
|
|
|
|
{ id: '5.2', label: '5.2 管理质量', x: 600, y: 245, w: 200, h: 30, to: routeByCode('5.2') },
|
|
|
|
|
{ id: '1.4', label: '1.4 管理项目知识', x: 600, y: 285, w: 80, h: 35, to: routeByCode('1.4') },
|
|
|
|
|
{ id: '1.3', label: '1.3 指导与管理项目工作', x: 600, y: 325, w: 200, h: 30, to: routeByCode('1.3') },
|
|
|
|
|
|
|
|
|
|
{ id: '2.6', label: '2.6 控制范围', x: 230, y: 390, w: 75, h: 30, to: routeByCode('2.6') },
|
|
|
|
|
{ id: '6.6', label: '6.6 控制资源', x: 315, y: 390, w: 75, h: 30, to: routeByCode('6.6') },
|
|
|
|
|
{ id: '9.3', label: '9.3 控制采购', x: 400, y: 390, w: 75, h: 30, to: routeByCode('9.3') },
|
|
|
|
|
{ id: '5.3', label: '5.3 控制质量', x: 485, y: 390, w: 75, h: 30, to: routeByCode('5.3') },
|
|
|
|
|
{ id: '3.6', label: '3.6 控制进度', x: 230, y: 435, w: 75, h: 30, to: routeByCode('3.6') },
|
|
|
|
|
{ id: '7.3', label: '7.3 监督沟通', x: 315, y: 435, w: 75, h: 30, to: routeByCode('7.3') },
|
|
|
|
|
{ id: '10.4', label: '10.4 监督相关方参与', x: 400, y: 435, w: 85, h: 35, to: routeByCode('10.4') },
|
|
|
|
|
{ id: '8.7', label: '8.7 监督风险', x: 315, y: 485, w: 75, h: 30, to: routeByCode('8.7') },
|
|
|
|
|
{ id: '4.4', label: '4.4 控制成本', x: 400, y: 485, w: 75, h: 30, to: routeByCode('4.4') },
|
|
|
|
|
{ id: '2.5', label: '2.5 确认范围', x: 485, y: 485, w: 75, h: 30, to: routeByCode('2.5') },
|
|
|
|
|
{ id: '1.5', label: '1.5 监控项目工作', x: 575, y: 400, w: 75, h: 35, to: routeByCode('1.5') },
|
|
|
|
|
{ id: '1.6', label: '1.6 实施整体变更控制', x: 575, y: 445, w: 75, h: 35, to: routeByCode('1.6') },
|
|
|
|
|
{ id: '1.7', label: '1.7 结束项目或阶段', x: 690, y: 400, w: 100, h: 35, to: routeByCode('1.7') },
|
|
|
|
|
|
|
|
|
|
]
|
|
|
|
|
}, [processIdByCode])
|
|
|
|
|
|
|
|
|
|
const handleOpen = (to: string) => {
|
|
|
|
|
if (to.startsWith('/process/')) {
|
|
|
|
|
navigate(to, { state: { from: 'roadmap' } })
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
navigate(to)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div className="space-y-4">
|
|
|
|
|
<div>
|
|
|
|
|
<h1 className="text-2xl font-bold text-gray-900 dark:text-white">五组十域流程总览图</h1>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className="rounded-xl border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-900 p-2">
|
|
|
|
|
<svg
|
|
|
|
|
width="1260"
|
|
|
|
|
height="840"
|
|
|
|
|
viewBox="0 0 840 560"
|
|
|
|
|
className="block w-full h-auto max-w-[1260px] mx-auto"
|
|
|
|
|
>
|
|
|
|
|
<style>{svgStyles}</style>
|
|
|
|
|
<defs>
|
|
|
|
|
<marker id="arrowhead" markerWidth="6" markerHeight="6" refX="5" refY="3" orient="auto">
|
|
|
|
|
<path d="M0,0 L6,3 L0,6 Z" className="marker" />
|
|
|
|
|
</marker>
|
|
|
|
|
<marker id="arrowhead-grey" markerWidth="5" markerHeight="5" refX="4" refY="2.5" orient="auto">
|
|
|
|
|
<path d="M0,0 L5,2.5 L0,5 Z" className="marker-grey" />
|
|
|
|
|
</marker>
|
|
|
|
|
</defs>
|
|
|
|
|
|
|
|
|
|
<g dangerouslySetInnerHTML={{ __html: staticSvgBody }} />
|
|
|
|
|
|
|
|
|
|
{hotspots.map((spot) => {
|
|
|
|
|
const isHovered = hoveredId === spot.id
|
|
|
|
|
return (
|
|
|
|
|
<g
|
|
|
|
|
key={spot.id}
|
|
|
|
|
role="button"
|
|
|
|
|
tabIndex={0}
|
|
|
|
|
onClick={() => handleOpen(spot.to)}
|
|
|
|
|
onMouseEnter={() => setHoveredId(spot.id)}
|
|
|
|
|
onMouseLeave={() => setHoveredId(null)}
|
|
|
|
|
onFocus={() => setHoveredId(spot.id)}
|
|
|
|
|
onBlur={() => setHoveredId(null)}
|
|
|
|
|
onKeyDown={(event) => {
|
|
|
|
|
if (event.key === 'Enter' || event.key === ' ') {
|
|
|
|
|
event.preventDefault()
|
|
|
|
|
handleOpen(spot.to)
|
|
|
|
|
}
|
|
|
|
|
}}
|
|
|
|
|
style={{ cursor: 'pointer' }}
|
|
|
|
|
>
|
|
|
|
|
<title>{`${spot.label}(点击进入)`}</title>
|
|
|
|
|
<rect
|
|
|
|
|
x={spot.x}
|
|
|
|
|
y={spot.y}
|
|
|
|
|
width={spot.w}
|
|
|
|
|
height={spot.h}
|
|
|
|
|
fill={isHovered ? 'rgba(245, 158, 11, 0.12)' : 'transparent'}
|
|
|
|
|
stroke={isHovered ? '#F59E0B' : 'transparent'}
|
|
|
|
|
strokeWidth={1.5}
|
|
|
|
|
rx={4}
|
|
|
|
|
/>
|
|
|
|
|
</g>
|
|
|
|
|
)
|
|
|
|
|
})}
|
|
|
|
|
</svg>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
)
|
|
|
|
|
}
|