Belle II Software  release-08-01-10
viewer.py
1 
8 from hep_ipython_tools import viewer
9 import random
10 import string
11 
12 
14  """The css string for styling the notebook."""
15 
16 
17  css_string = """
18  #notebook {
19  background-color: rgba(20, 166, 255, 0.3);
20  background-image: url("http://www-ekp.physik.uni-karlsruhe.de/~nbraun/belle.svg");
21  background-repeat: no-repeat;
22  background-position: right bottom;
23  }
24 
25  #notebook-container {
26  width: 90%;
27  }
28 
29  #menubar-container {
30  width: 90%;
31  }
32 
33  #header-container {
34  width: 90%;
35  }
36  """
37 
38 
40 
41  """
42  Viewer object for the ipython_handler_basf2 path.
43  Do not use it on your own.
44  """
45 
46  def __init__(self, path, standalone=False):
47  """
48  Create a new path viewer object with the path from the process
49  """
50 
51  try:
52  self.pathpath = path.modules()
53  except BaseException:
54  self.pathpath = path
55 
56 
57  self.standalonestandalone = standalone
58 
59  def create(self):
60  """
61  Create the widget
62  """
63 
64  import ipywidgets as widgets
65 
66  if self.pathpath is None:
67  return widgets.HTML("No modules in path.")
68 
69  a = widgets.Accordion()
70  children = []
71 
72  for i, element in enumerate(self.pathpath):
73  html = ModuleViewer(element, standalone=self.standalonestandalone)
74  children.append(html.create())
75  if isinstance(html.module.name, str):
76  a.set_title(i, html.module.name)
77  else:
78  a.set_title(i, html.module.name())
79 
80  a.children = children
81 
82  return a
83 
84 
86  """
87  A widget for showing module parameter with their content (not standalone)
88  or with their description (standalone).
89  """
90 
91  def __init__(self, module, standalone=True):
92  """ Init with a module as a string or a registered one. """
93 
94 
95  if isinstance(module, str):
96  import basf2.core as _basf2
97  self.modulemodule = _basf2.register_module(module)
98  else:
99  self.modulemodule = module
100 
101 
102  self.standalonestandalone = standalone
103 
104 
105  self.table_beginning_htmltable_beginning_html = """<table style="margin-left: auto; margin-right: auto;
106  border-collapse: separate; border-spacing: 0px;">"""
107 
108 
109  self.td_htmltd_html = "style=\"padding: 10px;\""
110 
111 
112  self.table_row_parameterstable_row_parameters = """<tr><td {td_style}>{param.name}</td>
113  <td{color_text} {td_style}>{param.values}</td>
114  <td style="color: gray; {td_style}>{param.default}</td></tr>"""
115 
116 
117  self.table_row_helptable_row_help = """<tr><td {td_style}>{param.name}</td>
118  <td {td_style}>{param.type}</td>
119  <td {td_style}>{param.values}</td>
120  <td style="color: gray; {td_style}>{param.description}</td></tr>"""
121 
122 
123  self.table_row_html_singletable_row_html_single = """<tr><td colspan="4" {td_style}>{text}</td></tr>"""
124 
125 
126  self.table_title_htmltable_title_html = """<thead><td colspan="4" style="text-align: center;
127  font-size: 18pt;" {td_style}>{module_name} ({package})</td></thead>"""
128 
129  def get_color_code(self, param):
130  """
131  Handy function for getting a color based on a parameter:
132  if it has the default value, no color,
133  if not, red color.
134  """
135  if str(param.values) != str(param.default) and str(param.default) != "":
136  color_text = " style='color: red;'"
137  else:
138  color_text = ""
139  return color_text
140 
141  def create(self):
142  """
143  Show the widget.
144  """
145  import ipywidgets as widgets
146 
147  html = widgets.HTML()
148  html.value = self.table_beginning_htmltable_beginning_html
149 
150  if self.standalonestandalone:
151  if isinstance(self.modulemodule.name, str):
152  module_name = self.modulemodule.name
153  else:
154  module_name = self.modulemodule.name()
155 
156  html.value += self.table_title_htmltable_title_html.format(module_name=module_name, package=self.modulemodule.package(),
157  td_style=self.td_htmltd_html)
158 
159  html.value += self.table_row_html_singletable_row_html_single.format(text=self.modulemodule.description(), td_style=self.td_htmltd_html)
160 
161  if len(self.modulemodule.available_params()) == 0:
162  html.value += self.table_row_html_singletable_row_html_single.format(text="No parameters available.", td_style=self.td_htmltd_html)
163  else:
164  for param in self.modulemodule.available_params():
165  color_text = self.get_color_codeget_color_code(param)
166 
167  if self.standalonestandalone:
168  table_row_html = self.table_row_helptable_row_help
169  else:
170  table_row_html = self.table_row_parameterstable_row_parameters
171 
172  html.value += table_row_html.format(param=param, color_text=color_text, td_style=self.td_htmltd_html)
173  html.value += "</table>"
174 
175  return html
176 
177 
179  """Show the dependencies in a nice and fancy way :-)"""
180 
181  def __init__(self, store_arrays_with_dependencies_JSON):
182  """Create a new dependency viewer."""
183 
184  self.store_arrays_with_dependencies_JSONstore_arrays_with_dependencies_JSON = store_arrays_with_dependencies_JSON
185 
186 
187  self.random_namerandom_name = ''.join(random.choice(string.ascii_letters) for _ in range(10))
188 
189  self.element_nameelement_name = "dependencies_" + self.random_namerandom_name
190 
191 
192  self.d3_include_stringd3_include_string = """<script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>"""
193 
194 
195  self.d3_element_stringd3_element_string = f"""<div id="{self.element_name}"></div>"""
196 
197 
198  self.style_templatestyle_template = """<style>
199  /* d3 related settings */
200  .node {
201  font: 300 14px "Helvetica Neue", Helvetica, Arial, sans-serif;
202  fill: #bbb;
203  cursor: pointer;
204  }
205 
206  .node:hover {
207  fill: #000;
208  }
209 
210  .link {
211  stroke: rgba(20, 166, 255, 0.3);
212  stroke-width: 2px;
213  fill: none;
214  pointer-events: none;
215  }
216 
217  .node:hover,
218  .node--source,
219  .node--target {
220  font-weight: 700;
221  }
222 
223  .node--source {
224  fill: #2ca02c;
225  }
226 
227  .node--target {
228  fill: #d62728;
229  }
230 
231  .link--source,
232  .link--target {
233  stroke-opacity: 1;
234  stroke-width: 4px;
235  }
236 
237  .link--source {
238  stroke: #d62728;
239  }
240 
241  .link--target {
242  stroke: #2ca02c;
243  }
244  </style>"""
245 
246 
247  self.nodes_templatenodes_template = """<script>var test_nodes = JSON.parse('{nodes_json}');</script>""".format(
248  nodes_json=self.store_arrays_with_dependencies_JSONstore_arrays_with_dependencies_JSON)
249 
250 
251  self.viewer_templateviewer_template = self.d3_include_stringd3_include_string + self.nodes_templatenodes_template + self.d3_element_stringd3_element_string + self.style_templatestyle_template + """
252  <script>
253  var diameter = 960;
254  var radius = diameter / 2;
255  var innerRadius = radius - 120;
256 
257  var cluster = d3.layout.cluster()
258  .size([360, innerRadius])
259  .sort(null)
260  .value(function(d) { return d.size; });
261 
262  var bundle = d3.layout.bundle();
263 
264  var line = d3.svg.line.radial()
265  .interpolate("bundle")
266  .tension(.85)
267  .radius(function(d) { return d.y; })
268  .angle(function(d) { return d.x / 180 * Math.PI; });
269 
270  var svg = d3.select("#""" + self.element_nameelement_name + """").append("svg")
271  .attr("width", diameter)
272  .attr("height", diameter)
273  .append("g")
274  .attr("transform", "translate(" + radius + "," + radius + ")");
275 
276  var link = svg.append("g").selectAll(".link");
277  var node = svg.append("g").selectAll(".node");
278 
279  var nodes = cluster.nodes(test_nodes);
280  var links = relations(nodes);
281 
282  link = link
283  .data(bundle(links))
284  .enter()
285  .append("path")
286  .each(function(d) { d.source = d[0], d.target = d[d.length - 1]; })
287  .attr("class", "link")
288  .attr("d", line);
289 
290  node = node
291  .data(nodes.filter(function(n) { return !n.children; }))
292  .enter()
293  .append("text")
294  .attr("class", "node")
295  .attr("dy", ".31em")
296  .attr("transform", function(d) {
297  return "rotate(" + (d.x - 90) +
298  ")translate(" + (d.y + 8) + ",0)"
299  + (d.x < 180 ? "" : "rotate(180)");})
300  .style("text-anchor", function(d) { return d.x < 180 ? "start" : "end"; })
301  .text(function(d) { return d.key; })
302  .on("mouseover", mouseovered)
303  .on("mouseout", mouseouted);
304 
305  function mouseovered(d) {
306  node.each(function(n) { n.target = n.source = false; });
307 
308  link.classed("link--target", function(l) { if (l.target === d) return l.source.source = true; })
309  .classed("link--source", function(l) { if (l.source === d) return l.target.target = true; })
310  .filter(function(l) { return l.target === d || l.source === d; })
311  .each(function() { this.parentNode.appendChild(this); });
312 
313  node.classed("node--target", function(n) { return n.target; })
314  .classed("node--source", function(n) { return n.source; });
315  }
316 
317  function mouseouted(d) {
318  link.classed("link--target", false)
319  .classed("link--source", false);
320 
321  node.classed("node--target", false)
322  .classed("node--source", false);
323  }
324 
325  d3.select(self.frameElement).style("height", diameter + "px");
326 
327  // Return a list of imports for the given array of nodes.
328  function relations(nodes) {
329  var map = {},
330  relation = [];
331 
332  // Compute a map from name to node.
333  nodes.forEach(function(d) {
334  map[d.name] = d;
335  });
336 
337  // For each import, construct a link from the source to target node.
338  nodes.forEach(function(d) {
339  if (d.relation) d.relation.forEach(function(i) {
340  relation.push({source: map[d.name], target: map[i]});
341  });
342  });
343 
344  return relation;
345  }
346  </script>
347  """
348 
349  def create(self):
350  """
351  Create the widget.
352  """
353  import ipywidgets as widgets
354  html = widgets.HTML(self.viewer_templateviewer_template)
355 
356  return html
random_name
Part of the name representing the object for javascript.
Definition: viewer.py:187
def __init__(self, store_arrays_with_dependencies_JSON)
Definition: viewer.py:181
store_arrays_with_dependencies_JSON
A JSON from the processing of dependencies.
Definition: viewer.py:184
nodes_template
Template for inserting the node JSON.
Definition: viewer.py:247
element_name
The name representing the object for javascript.
Definition: viewer.py:189
table_beginning_html
Template for the table beginning.
Definition: viewer.py:105
standalone
In the standalone mode, the basic parameters of the modules are shown.
Definition: viewer.py:102
table_row_parameters
Template for the row of parameters.
Definition: viewer.py:112
def __init__(self, module, standalone=True)
Definition: viewer.py:91
standalone
In the standalone mode, the basic parameters of the modules are shown.
Definition: viewer.py:57
def __init__(self, path, standalone=False)
Definition: viewer.py:46