在SVG中呈现的graphviz节点中进行简单的颜色循环和突出显示

时间:2015-01-29 01:29:53

标签: css svg graphviz

我使用graphviz制作了一些工程图纸。他们使用蝴蝶结方法(在一些重型工程行业中很受欢迎)使用风险模型。 Graphviz可以很好地模拟风险,尽管它们不是严格的图形。

我的graphviz bow-ties被导出到SVG,我将它们直接嵌入到HTML中并将它们作为静态文件发布。

一些图形节点被称为"威胁"在领结模型。我将这些威胁节点超链接到其他针对这些威胁的HTML页面。

我在每个威胁页面的顶部都有相同的SVG蝴蝶结副本,以帮助读者(我每次都会复制它而不是链接到它。)

这一切都按计划进行,但我希望页面更加生动。

1)我希望每个相关的威胁节点能够进入"脉冲"有颜色(可能从它的SVG填充颜色循环到浅色再回来)。 (每页一个威胁。脉冲是为了帮助读者记住他们正在看哪个威胁。)

我可以在graphviz中添加静态节点填充颜色,但我不知道如何处理SVG或CSS代码。

2)如果可能的话,可以将某些泛型添加到SVG / CSS中,以便当指针经过它时,以用户友好的方式突出显示具有超链接的每个节点,以显示它具有到HTML页面?

这是来自graphviz的SVG导出,后面是(更短)graphviz点代码。我通常不会直接手动编辑SVG代码,所以我希望任何更改都要尽可能基本。

我在这里做了一个通用的例子来保持长度,但我的所有风险图在概念上是相同的。

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
 "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 2.26.3 (20100126.1600)
 -->
<!-- Title: tiger Pages: 1 -->
<svg width="864pt" height="354pt"
 viewBox="0.00 0.00 864.00 354.43" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph1" class="graph" transform="scale(0.44582 0.44582) rotate(0) translate(4 791)">
<title>tiger</title>
<polygon fill="white" stroke="white" points="-4,5 -4,-791 1935,-791 1935,5 -4,5"/>
<!-- ESCAPED \nTIGER -->
<g id="node1" class="node"><title>ESCAPED \nTIGER</title>
<a xlink:title="Top Event">
<ellipse fill="crimson" stroke="crimson" cx="977" cy="-372" rx="148.01" ry="148.01"/>
<ellipse fill="none" stroke="crimson" cx="977" cy="-372" rx="148.01" ry="148.01"/>
<ellipse fill="none" stroke="crimson" cx="977" cy="-372" rx="152.01" ry="152.01"/>
<text text-anchor="middle" x="977" y="-382" font-family="Times Roman,serif" font-size="40.00" fill="white">ESCAPED </text>
<text text-anchor="middle" x="977" y="-336" font-family="Times Roman,serif" font-size="40.00" fill="white">TIGER</text>
</a>
</g>
<!-- TIGERPIC -->
<g id="node2" class="node"><title>TIGERPIC</title>
<a xlink:title="Hazard">
<image xlink:href="tiger.gif" width="376px" height="203px" preserveAspectRatio="xMinYMin meet" x="789" y="-202.5"/>
<polygon fill="none" stroke="none" points="1165,-202.5 789,-202.5 789,0.5 1165,0.5 1165,-202.5"/>
</a>
</g>
<!-- ESCAPED \nTIGER&#45;&gt;TIGERPIC -->
<g id="edge5" class="edge"><title>ESCAPED \nTIGER&#45;&gt;TIGERPIC</title>
<path fill="none" stroke="black" stroke-width="10" d="M977,-219.683C977,-213.821 977,-207.958 977,-202.096"/>
</g>
<!-- SEARCH\nPLAN -->
<g id="node14" class="node"><title>SEARCH\nPLAN</title>
<a xlink:href="./search.html" xlink:title="Control">
<polygon fill="darkgreen" stroke="darkgreen" points="1318,-437 1202,-437 1202,-369 1318,-369 1318,-437"/>
<polygon fill="none" stroke="darkgreen" points="1318,-437 1202,-437 1202,-369 1318,-369 1318,-437"/>
<text text-anchor="middle" x="1260" y="-410.5" font-family="Times Roman,serif" font-size="25.00" fill="white">SEARCH</text>
<text text-anchor="middle" x="1260" y="-380.5" font-family="Times Roman,serif" font-size="25.00" fill="white">PLAN</text>
</a>
</g>
<!-- ESCAPED \nTIGER&#45;&gt;SEARCH\nPLAN -->
<g id="edge15" class="edge"><title>ESCAPED \nTIGER&#45;&gt;SEARCH\nPLAN</title>
<path fill="none" stroke="green" stroke-width="10" d="M1128.44,-388.589C1154.59,-391.454 1180.29,-394.269 1201.94,-396.64"/>
</g>
<!-- INSURANCE -->
<g id="node16" class="node"><title>INSURANCE</title>
<a xlink:href="./insurance.html" xlink:title="Control">
<polygon fill="darkgreen" stroke="darkgreen" points="1513,-354 1355,-354 1355,-316 1513,-316 1513,-354"/>
<polygon fill="none" stroke="darkgreen" points="1513,-354 1355,-354 1355,-316 1513,-316 1513,-354"/>
<text text-anchor="middle" x="1434" y="-327.5" font-family="Times Roman,serif" font-size="25.00" fill="white">INSURANCE</text>
</a>
</g>
<!-- ESCAPED \nTIGER&#45;&gt;INSURANCE -->
<g id="edge19" class="edge"><title>ESCAPED \nTIGER&#45;&gt;INSURANCE</title>
<path fill="none" stroke="brown" stroke-width="10" d="M1128.54,-359.731C1204.02,-353.62 1292.18,-346.482 1354.34,-341.45"/>
</g>
<!-- GATE\nPASSABLE\n\by\nTIGER -->
<g id="node4" class="node"><title>GATE\nPASSABLE\n\by\nTIGER</title>
<a xlink:title="Threat">
<polygon fill="red" stroke="red" points="202,-743.019 -0.232539,-471.49 404.233,-471.49 202,-743.019"/>
<polygon fill="none" stroke="red" points="202,-743.019 -0.232539,-471.49 404.233,-471.49 202,-743.019"/>
<text text-anchor="middle" x="202" y="-599.5" font-family="Times Roman,serif" font-size="25.00" fill="white">GATE</text>
<text text-anchor="middle" x="202" y="-569.5" font-family="Times Roman,serif" font-size="25.00" fill="white">PASSABLE</text>
<text text-anchor="middle" x="202" y="-539.5" font-family="Times Roman,serif" font-size="25.00" fill="white">by</text>
<text text-anchor="middle" x="202" y="-509.5" font-family="Times Roman,serif" font-size="25.00" fill="white">TIGER</text>
</a>
</g>
<!-- GATE\nDESIGN -->
<g id="node11" class="node"><title>GATE\nDESIGN</title>
<a xlink:href="./design.html" xlink:title="Control">
<polygon fill="darkgreen" stroke="darkgreen" points="551,-406 441,-406 441,-338 551,-338 551,-406"/>
<polygon fill="none" stroke="darkgreen" points="551,-406 441,-406 441,-338 551,-338 551,-406"/>
<text text-anchor="middle" x="496" y="-379.5" font-family="Times Roman,serif" font-size="25.00" fill="white">GATE</text>
<text text-anchor="middle" x="496" y="-349.5" font-family="Times Roman,serif" font-size="25.00" fill="white">DESIGN</text>
</a>
</g>
<!-- GATE\nPASSABLE\n\by\nTIGER&#45;&gt;GATE\nDESIGN -->
<g id="edge7" class="edge"><title>GATE\nPASSABLE\n\by\nTIGER&#45;&gt;GATE\nDESIGN</title>
<path fill="none" stroke="red" stroke-width="10" d="M342.112,-471.452C378.198,-448.13 414.84,-424.451 443.311,-406.05"/>
</g>
<!-- KEEPER\nLEAVES\nGATE\nOPEN -->
<g id="node5" class="node"><title>KEEPER\nLEAVES\nGATE\nOPEN</title>
<a xlink:title="Threat">
<polygon fill="red" stroke="red" points="202,-363.019 45.0223,-91.4903 358.978,-91.4903 202,-363.019"/>
<polygon fill="none" stroke="red" points="202,-363.019 45.0223,-91.4903 358.978,-91.4903 202,-363.019"/>
<text text-anchor="middle" x="202" y="-219.5" font-family="Times Roman,serif" font-size="25.00" fill="white">KEEPER</text>
<text text-anchor="middle" x="202" y="-189.5" font-family="Times Roman,serif" font-size="25.00" fill="white">LEAVES</text>
<text text-anchor="middle" x="202" y="-159.5" font-family="Times Roman,serif" font-size="25.00" fill="white">GATE</text>
<text text-anchor="middle" x="202" y="-129.5" font-family="Times Roman,serif" font-size="25.00" fill="white">OPEN</text>
</a>
</g>
<!-- KEEPER\nLEAVES\nGATE\nOPEN&#45;&gt;GATE\nDESIGN -->
<g id="edge11" class="edge"><title>KEEPER\nLEAVES\nGATE\nOPEN&#45;&gt;GATE\nDESIGN</title>
<path fill="none" stroke="blue" stroke-width="10" d="M278.478,-231.424C330.2,-264.85 397.187,-308.141 443.078,-337.799"/>
</g>
<!-- EATS\nMEMBER\nof\nPUBLIC -->
<g id="node7" class="node"><title>EATS\nMEMBER\nof\nPUBLIC</title>
<a xlink:title="Consequence">
<polygon fill="red" stroke="red" points="1740,-787.019 1566.05,-515.49 1913.95,-515.49 1740,-787.019"/>
<polygon fill="none" stroke="red" points="1740,-787.019 1566.05,-515.49 1913.95,-515.49 1740,-787.019"/>
<text text-anchor="middle" x="1740" y="-643.5" font-family="Times Roman,serif" font-size="25.00" fill="white">EATS</text>
<text text-anchor="middle" x="1740" y="-613.5" font-family="Times Roman,serif" font-size="25.00" fill="white">MEMBER</text>
<text text-anchor="middle" x="1740" y="-583.5" font-family="Times Roman,serif" font-size="25.00" fill="white">of</text>
<text text-anchor="middle" x="1740" y="-553.5" font-family="Times Roman,serif" font-size="25.00" fill="white">PUBLIC</text>
</a>
</g>
<!-- LOSS\nof\nREVENUE -->
<g id="node8" class="node"><title>LOSS\nof\nREVENUE</title>
<a xlink:title="Consequence">
<polygon fill="red" stroke="red" points="1740,-407.593 1551,-199.704 1929,-199.704 1740,-407.593"/>
<polygon fill="none" stroke="red" points="1740,-407.593 1551,-199.704 1929,-199.704 1740,-407.593"/>
<text text-anchor="middle" x="1740" y="-291.5" font-family="Times Roman,serif" font-size="25.00" fill="white">LOSS</text>
<text text-anchor="middle" x="1740" y="-261.5" font-family="Times Roman,serif" font-size="25.00" fill="white">of</text>
<text text-anchor="middle" x="1740" y="-231.5" font-family="Times Roman,serif" font-size="25.00" fill="white">REVENUE</text>
</a>
</g>
<!-- INSPECTION\n\&amp;\nTESTING -->
<g id="node12" class="node"><title>INSPECTION\n\&amp;\nTESTING</title>
<a xlink:href="./inspection.html" xlink:title="Control">
<polygon fill="darkgreen" stroke="darkgreen" points="752,-464 588,-464 588,-366 752,-366 752,-464"/>
<polygon fill="none" stroke="darkgreen" points="752,-464 588,-464 588,-366 752,-366 752,-464"/>
<text text-anchor="middle" x="670" y="-437.5" font-family="Times Roman,serif" font-size="25.00" fill="white">INSPECTION</text>
<text text-anchor="middle" x="670" y="-407.5" font-family="Times Roman,serif" font-size="25.00" fill="white">&amp;</text>
<text text-anchor="middle" x="670" y="-377.5" font-family="Times Roman,serif" font-size="25.00" fill="white">TESTING</text>
</a>
</g>
<!-- GATE\nDESIGN&#45;&gt;INSPECTION\n\&amp;\nTESTING -->
<g id="edge8" class="edge"><title>GATE\nDESIGN&#45;&gt;INSPECTION\n\&amp;\nTESTING</title>
<path fill="none" stroke="red" stroke-width="10" d="M551.533,-385.724C563.07,-388.575 575.46,-391.637 587.725,-394.668"/>
</g>
<!-- TRAINING -->
<g id="node13" class="node"><title>TRAINING</title>
<a xlink:href="./training.html" xlink:title="Control">
<polygon fill="darkgreen" stroke="darkgreen" points="737,-348 603,-348 603,-310 737,-310 737,-348"/>
<polygon fill="none" stroke="darkgreen" points="737,-348 603,-348 603,-310 737,-310 737,-348"/>
<text text-anchor="middle" x="670" y="-321.5" font-family="Times Roman,serif" font-size="25.00" fill="white">TRAINING</text>
</a>
</g>
<!-- GATE\nDESIGN&#45;&gt;TRAINING -->
<g id="edge12" class="edge"><title>GATE\nDESIGN&#45;&gt;TRAINING</title>
<path fill="none" stroke="blue" stroke-width="10" d="M551.533,-358.276C567.844,-354.245 585.861,-349.793 602.817,-345.603"/>
</g>
<!-- INSPECTION\n\&amp;\nTESTING&#45;&gt;ESCAPED \nTIGER -->
<g id="edge9" class="edge"><title>INSPECTION\n\&amp;\nTESTING&#45;&gt;ESCAPED \nTIGER</title>
<path fill="none" stroke="red" stroke-width="10" d="M752.27,-403.477C775.182,-400.268 800.815,-396.677 826.342,-393.102"/>
</g>
<!-- TRAINING&#45;&gt;ESCAPED \nTIGER -->
<g id="edge13" class="edge"><title>TRAINING&#45;&gt;ESCAPED \nTIGER</title>
<path fill="none" stroke="blue" stroke-width="10" d="M737.372,-338.437C763.76,-342.132 795.168,-346.532 826.415,-350.908"/>
</g>
<!-- DART\nGUN -->
<g id="node15" class="node"><title>DART\nGUN</title>
<a xlink:href="./dartgun.html" xlink:title="Control">
<polygon fill="darkgreen" stroke="darkgreen" points="1475,-573 1393,-573 1393,-505 1475,-505 1475,-573"/>
<polygon fill="none" stroke="darkgreen" points="1475,-573 1393,-573 1393,-505 1475,-505 1475,-573"/>
<text text-anchor="middle" x="1434" y="-546.5" font-family="Times Roman,serif" font-size="25.00" fill="white">DART</text>
<text text-anchor="middle" x="1434" y="-516.5" font-family="Times Roman,serif" font-size="25.00" fill="white">GUN</text>
</a>
</g>
<!-- SEARCH\nPLAN&#45;&gt;DART\nGUN -->
<g id="edge16" class="edge"><title>SEARCH\nPLAN&#45;&gt;DART\nGUN</title>
<path fill="none" stroke="green" stroke-width="10" d="M1303.91,-437.319C1331.19,-458.643 1366.04,-485.88 1392.8,-506.797"/>
</g>
<!-- DART\nGUN&#45;&gt;EATS\nMEMBER\nof\nPUBLIC -->
<g id="edge17" class="edge"><title>DART\nGUN&#45;&gt;EATS\nMEMBER\nof\nPUBLIC</title>
<path fill="none" stroke="green" stroke-width="10" d="M1475.27,-548.036C1508.79,-555.376 1558.05,-566.162 1605.02,-576.445"/>
</g>
<!-- INSURANCE&#45;&gt;LOSS\nof\nREVENUE -->
<g id="edge20" class="edge"><title>INSURANCE&#45;&gt;LOSS\nof\nREVENUE</title>
<path fill="none" stroke="brown" stroke-width="10" d="M1513.6,-317.832C1550.43,-309.887 1594.7,-300.338 1634.29,-291.8"/>
</g>
</g>
</svg>


// This is graphviz dot code for the bow-ties


digraph tiger {


overlap=scale;
splines=true;
// clusters=dotted;
ordering=out;
size="12,12!"

bgcolor=white;
rankdir=LR;

root="ESCAPED \nTIGER" // for twopi and circo

// Middle nodes

"ESCAPED \nTIGER" [tooltip="Top Event", fontsize=40, width=2, height=2, shape=doublecircle, style=filled, color=crimson, fontcolor=white];

"TIGERPIC" [label="", image="tiger.gif", tooltip="Hazard", fontsize=40, width=2, height=2, shape=rectangle, color=none];

// Lining up!

{rank=same; "GATE\nPASSABLE\n\by\nTIGER" "KEEPER\nLEAVES\nGATE\nOPEN"}

{rank=same; "EATS\nMEMBER\nof\nPUBLIC" "LOSS\nof\nREVENUE"}

{rank=same; "ESCAPED \nTIGER" "TIGERPIC"}

// Top Event and Risk!


"ESCAPED \nTIGER" -> "TIGERPIC" [arrowhead = none, penwidth=10];

// Threats and consequences

"GATE\nPASSABLE\n\by\nTIGER" [tooltip="Threat", color=red, shape=triangle, style=filled, fontcolor=white, fontsize=25];
"KEEPER\nLEAVES\nGATE\nOPEN"  [tooltip="Threat", color=red, shape=triangle, style=filled, fontcolor=white, fontsize=25];
"EATS\nMEMBER\nof\nPUBLIC"  [tooltip="Consequence", color=red, shape=triangle, style=filled, fontcolor=white, fontsize=25];
"LOSS\nof\nREVENUE"  [tooltip="Consequence", color=red, shape=triangle, style=filled, fontcolor=white, fontsize=25];

// Controls!

"GATE\nDESIGN" [URL="./design.html", tooltip="Control", shape=box, style=filled, color=darkgreen, fontcolor=white, fontsize=25];
"INSPECTION\n\&\nTESTING" [URL="./inspection.html", tooltip="Control", shape=box, style=filled, color=darkgreen, fontcolor=white, fontsize=25];
"TRAINING" [URL="./training.html", tooltip="Control", shape=box, style=filled, color=darkgreen, fontcolor=white, fontsize=25];
"SEARCH\nPLAN" [URL="./search.html", tooltip="Control", shape=box, style=filled, color=darkgreen, fontcolor=white, fontsize=25];
"DART\nGUN" [URL="./dartgun.html", tooltip="Control", shape=box, style=filled, color=darkgreen, fontcolor=white, fontsize=25];
"INSURANCE" [URL="./insurance.html", tooltip="Control", shape=box, style=filled, color=darkgreen, fontcolor=white, fontsize=25];

// Joining up 

"GATE\nPASSABLE\n\by\nTIGER" -> "GATE\nDESIGN" -> "INSPECTION\n\&\nTESTING" -> "ESCAPED \nTIGER" [arrowhead = none, penwidth=10, color=red];
"KEEPER\nLEAVES\nGATE\nOPEN" -> "GATE\nDESIGN" -> "TRAINING" -> "ESCAPED \nTIGER" [arrowhead = none, penwidth=10, color=blue];
"ESCAPED \nTIGER" -> "SEARCH\nPLAN" -> "DART\nGUN" -> "EATS\nMEMBER\nof\nPUBLIC" [arrowhead = none, penwidth=10, color=green];
"ESCAPED \nTIGER" -> "INSURANCE" -> "LOSS\nof\nREVENUE" [arrowhead = none, penwidth=10, color=brown];


}

//---------------------
// ----- The End! -----
//---------------------

1 个答案:

答案 0 :(得分:1)

以下是如何通过两个步骤以脉动颜色为威胁设置动画:

步骤1:添加id属性

为以威胁开头的每个威胁添加id属性,例如 threat1 threat2 ,...:

"GATE\nPASSABLE\n\by\nTIGER" [tooltip="Threat", id="threat1", ...];
"KEEPER\nLEAVES\nGATE\nOPEN"  [tooltip="Threat", id="threat2", ...];

这将使用此属性作为graphviz svg输出中的id。

第2步:添加CSS动画

添加CSS,根据这些ID将属性设置为包含svg的html页面。以下CSS将在红色和黄色之间产生威胁的脉动颜色:

g [id*="threat"] polygon {
    -webkit-animation: pulse 2s;
    -webkit-animation-iteration-count: infinite;
    -webkit-animation-direction: alternate;
    animation: pulse 2s;
    animation-iteration-count: infinite;
    animation-direction: alternate;
}
@-webkit-keyframes pulse {
    from {fill: red;}
    to {fill: yellow;}
}
@keyframes pulse {
    from {fill: red;}
    to {fill: yellow;}
} 

关于第二个问题,鼠标指针在浏览器中超过超链接时应该已经变为手形图标。否则,您也可以使用上述技术为这些链接添加一些特殊效果。