如何实现Mermaid脚本指定文本的可点击指针样式效果
实现Mermaid时序图中指定文本的悬停指针样式
问题场景
你需要给Mermaid时序图里的Warehouse文本添加悬停时的cursor: pointer样式,但之前的全局CSS会让图表中所有文本都显示指针状态,需要只针对目标文本生效。
现有代码
React渲染Mermaid的代码:
import mermaid from "mermaid"; mermaid.initialize({ startOnLoad: true, theme: "default", securityLevel: "loose", fontFamily: "Fira Code", htmlLabels: true }); export default function App() { const chart = `sequenceDiagram Warehouse->>Customer: getWarehouse() Customer-->>ChatBot: getCustomer() Customer--x WarehouseKey: getChatBot() Customer-x ChatBot: getUser() Note right of ChatBot: Customer thinks a long long time, so long that the text does not fit on a row. Customer-->Warehouse: Checking with ChatBot... WarehouseKey->ChatBot: Yes... ChatBot, how are you? `; return ( <div className="mermaid" > {chart} </div> ); }
之前的全局CSS(会让所有文本可点击):
.actor > tspan { cursor: pointer; } .messageText { cursor: pointer; } .noteText > tspan { cursor: pointer; }
解决方案
方法1:利用Mermaid内置的类定义语法(推荐)
直接在Mermaid脚本里给目标角色绑定自定义样式类,再通过CSS精准控制:
- 修改Mermaid时序图脚本,添加
classDef定义样式类,并用class给Warehouse角色绑定:
sequenceDiagram classDef clickableActor cursor: pointer; class Warehouse clickableActor; Warehouse->>Customer: getWarehouse() Customer-->>ChatBot: getCustomer() Customer--x WarehouseKey: getChatBot() Customer-x ChatBot: getUser() Note right of ChatBot: Customer thinks a long long time, so long that the text does not fit on a row. Customer-->Warehouse: Checking with ChatBot... WarehouseKey->ChatBot: Yes... ChatBot, how are you?
- 对应的CSS只需针对自定义类生效:
.clickableActor > tspan { cursor: pointer; }
这种方法完全基于Mermaid的语法规范,不会影响其他元素,维护性更强。
方法2:通过JS精准定位DOM元素(适合无法修改Mermaid脚本的场景)
如果不能修改Mermaid的图表脚本,可以在组件挂载后,通过JS找到对应文本的元素并添加样式:
修改React组件代码,添加useRef和useEffect来处理DOM:
import { useEffect, useRef } from 'react'; import mermaid from "mermaid"; mermaid.initialize({ startOnLoad: true, theme: "default", securityLevel: "loose", fontFamily: "Fira Code", htmlLabels: true }); export default function App() { const mermaidContainer = useRef(null); useEffect(() => { // 确保Mermaid渲染完成后再操作DOM const timer = setTimeout(() => { if (mermaidContainer.current) { // 找到所有角色文本元素 const actorTexts = mermaidContainer.current.querySelectorAll('.actor > tspan'); actorTexts.forEach(textEl => { // 匹配目标文本 if (textEl.textContent.trim() === 'Warehouse') { textEl.style.cursor = 'pointer'; } }); } }, 500); return () => clearTimeout(timer); }, []); const chart = `sequenceDiagram Warehouse->>Customer: getWarehouse() Customer-->>ChatBot: getCustomer() Customer--x WarehouseKey: getChatBot() Customer-x ChatBot: getUser() Note right of ChatBot: Customer thinks a long long time, so long that the text does not fit on a row. Customer-->Warehouse: Checking with ChatBot... WarehouseKey->ChatBot: Yes... ChatBot, how are you? `; return ( <div ref={mermaidContainer} className="mermaid" > {chart} </div> ); }
这里用定时器确保Mermaid完成渲染,再精准匹配文本内容为Warehouse的元素添加指针样式。
内容的提问来源于stack exchange,提问作者Karan S
相关产品推荐
相关产品推荐

