1# -*- coding: utf-8 -*-2# Copyright 2011 Takeshi KOMIYA3#4# Licensed under the Apache License, Version 2.0 (the "License");5# you may not use this file except in compliance with the License.6# You may obtain a copy of the License at7#8# http://www.apache.org/licenses/LICENSE-2.09#10# Unless required by applicable law or agreed to in writing, software11# distributed under the License is distributed on an "AS IS" BASIS,12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.13# See the License for the specific language governing permissions and14# limitations under the License.1516from __future__ import division1718import blockdiag.drawer19from blockdiag.utils import XY, Box2021from nwdiag.metrics import DiagramMetrics222324class DiagramDraw(blockdiag.drawer.DiagramDraw):25 def create_metrics(self, *args, **kwargs):26 return DiagramMetrics(*args, **kwargs)2728 def __init__(self, _format, diagram, filename=None, **kwargs):29 super(DiagramDraw, self).__init__(_format, diagram, filename, **kwargs)30 self.drawer.set_options(jump_forward='vertical',31 jump_radius=self.metrics.jump_radius,32 jump_shift=self.metrics.jump_shift)333435 def groups(self):36 return self.diagram.groups3738 def pagesize(self, scaled=False):39 return super(DiagramDraw, self).pagesize(scaled).to_integer_point()4041 def _draw_background(self):42 super(DiagramDraw, self)._draw_background()43 self.trunklines_shadow()4445 def trunklines_shadow(self):46 for network in self.diagram.networks:47 if network.hidden is False and network.color != 'none':48 self.trunkline(network, shadow=True)4950 def trunklines(self):51 metrics = self.metrics52 for network in self.diagram.networks:53 if network.hidden is False:54 self.trunkline(network)5556 if (self.diagram.external_connector and57 (network == self.diagram.networks[0])):58 r = metrics.trunk_diameter // 25960 pt = metrics.network(network).top61 pt0 = XY(pt.x, pt.y - metrics.span_height * 2 // 3)62 pt1 = XY(pt.x, pt.y - r)6364 self.drawer.line([pt0, pt1], fill=network.linecolor)6566 def trunkline(self, network, shadow=False):67 metrics = self.metrics68 m = metrics.network(network)69 r = metrics.trunk_diameter // 27071 pt1, pt2 = m.trunkline72 box = Box(pt1.x, pt1.y - r, pt2.x, pt2.y + r)7374 if shadow:75 xdiff = self.metrics.shadow_offset.x76 ydiff = self.metrics.shadow_offset.y // 27778 box = Box(pt1.x + xdiff, pt1.y - r + ydiff,79 pt2.x + xdiff, pt2.y + r + ydiff)8081 if self.format == 'SVG':82 from blockdiag.imagedraw.simplesvg import pathdata8384 path = pathdata(box[0], box[1])85 path.line(box[2], box[1])86 path.ellarc(r // 2, r, 0, 0, 1, box[2], box[3])87 path.line(box[0], box[3])88 path.ellarc(r // 2, r, 0, 0, 1, box[0], box[1])8990 if shadow:91 self.drawer.path(path, fill=self.shadow, filter='blur')92 else:93 self.drawer.path(path, fill=network.color,94 outline=network.linecolor)9596 path = pathdata(box[2], box[3])97 path.ellarc(r // 2, r, 0, 0, 1, box[2], box[1])98 self.drawer.path(path, fill='none', outline=network.linecolor)99100 # for edge jumping101 line = (XY(box[0], box[1]), XY(box[2], box[1]))102 self.drawer.line(line, fill='none', jump=True)103 else:104 lsection = Box(box[0] - r // 2, box[1], box[0] + r // 2, box[3])105 rsection = Box(box[2] - r // 2, box[1], box[2] + r // 2, box[3])106107 if shadow:108 color = self.shadow109 _filter = 'blur'110 else:111 color = network.color112 _filter = None113114 # fill background115 self.drawer.rectangle(box, outline=color,116 fill=color, filter=_filter)117 self.drawer.ellipse(lsection, outline=color,118 fill=color, filter=_filter)119 self.drawer.ellipse(rsection, outline=color,120 fill=color, filter=_filter)121122 if not shadow:123 upper = (XY(box[0], box[1]), XY(box[2], box[1]))124 self.drawer.line(upper, fill=network.linecolor, jump=True)125126 bottom = (XY(box[0], box[3]), XY(box[2], box[3]))127 self.drawer.line(bottom, fill=network.linecolor, jump=True)128129 self.drawer.arc(lsection, 90, 270, fill=network.linecolor)130 self.drawer.ellipse(rsection, outline=network.linecolor,131 fill=network.color)132133 def _draw_elements(self):134 self.trunklines()135136 for network in self.diagram.networks:137 self.trunkline_label(network)138139 super(DiagramDraw, self)._draw_elements()140141 def trunkline_label(self, network):142 if network.display_label:143 m = self.metrics.network(network)144 self.drawer.textarea(m.textbox, network.display_label,145 self.metrics.font_for(network),146 fill=network.textcolor, halign="right")147148 def node(self, node, **kwargs):149 m = self.metrics150151 for connector in m.node(node).connectors:152 self.draw_connector(connector)153 if hasattr(connector, 'subject'):154 network = connector.subject.network155 else:156 network = connector.network157158 if network in node.address:159 label = node.address[network]160 self.drawer.textarea(connector.textbox, label,161 self.metrics.font_for(node),162 fill=node.textcolor, halign="left")163164 super(DiagramDraw, self).node(node, **kwargs)165166 def draw_connector(self, connector):167 if hasattr(connector, 'subject'):168 linecolor = connector.subject.network.linecolor169 else:170 linecolor = connector.network.linecolor171 self.drawer.line(connector.line, fill=linecolor, jump=True)172173 def group_label(self, group):174 if group.label:175 m = self.metrics.cell(group)176 self.drawer.textarea(m.grouplabelbox, group.label,177 self.metrics.font_for(group),178 valign='top', fill=group.textcolor)