def n2(data_source, outfile='n2.html', case_id=None, show_browser=True, embeddable=False, title=None, use_declare_partial_info=False): """ Generate an HTML file containing a tree viewer. Optionally opens a web browser to view the file. Parameters ---------- data_source : <Problem> or str The Problem or case recorder database containing the model or model data. case_id : int, str, or None Case name or index of case in SQL file if data_source is a database. outfile : str, optional The name of the final output file show_browser : bool, optional If True, pop up the system default web browser to view the generated html file. Defaults to True. embeddable : bool, optional If True, gives a single HTML file that doesn't have the <html>, <DOCTYPE>, <body> and <head> tags. If False, gives a single, standalone HTML file for viewing. title : str, optional The title for the diagram. Used in the HTML title. use_declare_partial_info : ignored This option is no longer used because it is now always true. Still present for backwards compatibility. """ # grab the model viewer data model_data = _get_viewer_data(data_source, case_id=case_id) # if MPI is active only display one copy of the viewer if MPI and MPI.COMM_WORLD.rank != 0: return options = {} model_data['options'] = options if use_declare_partial_info: warn_deprecation("'use_declare_partial_info' is now the" " default and the option is ignored.") raw_data = json.dumps(model_data, default=default_noraise).encode('utf8') b64_data = str(base64.b64encode(zlib.compress(raw_data)).decode("ascii")) model_data = 'var compressedModel = "%s";' % b64_data import openmdao openmdao_dir = os.path.dirname(inspect.getfile(openmdao)) vis_dir = os.path.join(openmdao_dir, "visualization/n2_viewer") libs_dir = os.path.join(vis_dir, "libs") src_dir = os.path.join(vis_dir, "src") style_dir = os.path.join(vis_dir, "style") assets_dir = os.path.join(vis_dir, "assets") # grab the libraries, src and style lib_dct = { 'd3': 'd3.v5.min', 'awesomplete': 'awesomplete', 'vk_beautify': 'vkBeautify', 'pako_inflate': 'pako_inflate.min', 'json5': 'json5_2.2.0.min' } libs = read_files(lib_dct.values(), libs_dir, 'js') src_names = \ 'utils', \ 'SymbolType', \ 'N2TreeNode', \ 'ModelData', \ 'N2Style', \ 'N2Window', \ 'N2Layout', \ 'N2MatrixCell', \ 'N2Legend', \ 'N2Matrix', \ 'N2Arrow', \ 'N2Search', \ 'N2Toolbar', \ 'N2Diagram', \ 'NodeInfo', \ 'N2UserInterface', \ 'defaults', \ 'ptN2' srcs = read_files(src_names, src_dir, 'js') style_names = \ 'window', \ 'partition_tree', \ 'n2toolbar-icons', \ 'toolbar', \ 'legend', \ 'awesomplete' styles = read_files((style_names), style_dir, 'css') with open(os.path.join(style_dir, "n2toolbar-icons-font.woff"), "rb") as f: encoded_font = str(base64.b64encode(f.read()).decode("ascii")) with open(os.path.join(style_dir, "logo_png.b64"), "r") as f: logo_png = str(f.read()) with open(os.path.join(assets_dir, "spinner.png"), "rb") as f: waiting_icon = str(base64.b64encode(f.read()).decode("ascii")) with open(os.path.join(assets_dir, "n2toolbar_screenshot_png.b64"), "r") as f: n2toolbar_png = str(f.read()) if title: title = "OpenMDAO Model Hierarchy and N2 diagram: %s" % title else: title = "OpenMDAO Model Hierarchy and N2 diagram" src_names = ('N2ErrorHandling',) head_srcs = read_files(src_names, src_dir, 'js') h = DiagramWriter(filename=os.path.join(vis_dir, "index.html"), title=title, styles=styles, embeddable=embeddable, head_srcs=head_srcs) if (embeddable): h.insert("non-embedded-n2", "embedded-n2") # put all style and JS into index h.insert('{{n2toolbar-icons}}', encoded_font) h.insert('{{logo_png}}', logo_png) h.insert('{{waiting_icon}}', waiting_icon) h.insert('{{n2toolbar_png}}', n2toolbar_png) h.insert('{{om_version}}', openmdao_version) for k, v in lib_dct.items(): h.insert('{{{}_lib}}'.format(k), write_script(libs[v], indent=_IND)) for name, code in srcs.items(): h.insert('{{{}_lib}}'.format(name.lower()), write_script(code, indent=_IND)) h.insert('{{model_data}}', write_script(model_data, indent=_IND)) # Write output file h.write(outfile) if notebook: # display in Jupyter Notebook if not colab: display(IFrame(src=outfile, width=1000, height=1000)) else: display(HTML(outfile)) elif show_browser: # open it up in the browser from openmdao.utils.webview import webview webview(outfile)
def n2(data_source, outfile='n2.html', show_browser=True, embeddable=False, title=None, use_declare_partial_info=False): """ Generate an HTML file containing a tree viewer. Optionally opens a web browser to view the file. Parameters ---------- data_source : <Problem> or str The Problem or case recorder database containing the model or model data. outfile : str, optional The name of the final output file show_browser : bool, optional If True, pop up the system default web browser to view the generated html file. Defaults to True. embeddable : bool, optional If True, gives a single HTML file that doesn't have the <html>, <DOCTYPE>, <body> and <head> tags. If False, gives a single, standalone HTML file for viewing. title : str, optional The title for the diagram. Used in the HTML title. use_declare_partial_info : bool, optional If True, in the N2 matrix, component internal connectivity computed using derivative declarations, otherwise, derivative declarations ignored, so dense component connectivity is assumed. """ # grab the model viewer data model_data = _get_viewer_data(data_source) # if MPI is active only display one copy of the viewer if MPI and MPI.COMM_WORLD.rank != 0: return options = {'use_declare_partial_info': use_declare_partial_info} model_data['options'] = options model_data = 'var modelData = %s' % json.dumps(model_data, default=make_serializable) import openmdao openmdao_dir = os.path.dirname(inspect.getfile(openmdao)) vis_dir = os.path.join(openmdao_dir, "visualization/n2_viewer") libs_dir = os.path.join(vis_dir, "libs") src_dir = os.path.join(vis_dir, "src") style_dir = os.path.join(vis_dir, "style") assets_dir = os.path.join(vis_dir, "assets") # grab the libraries, src and style lib_dct = { 'd3': 'd3.v5.min', 'awesomplete': 'awesomplete', 'vk_beautify': 'vkBeautify' } libs = read_files(lib_dct.values(), libs_dir, 'js') src_names = \ 'modal', \ 'utils', \ 'SymbolType', \ 'N2TreeNode', \ 'ModelData', \ 'N2Style', \ 'N2Layout', \ 'N2MatrixCell', \ 'N2Legend', \ 'N2Matrix', \ 'N2Arrow', \ 'N2Search', \ 'N2Toolbar', \ 'N2Diagram', \ 'N2UserInterface', \ 'defaults', \ 'ptN2' srcs = read_files(src_names, src_dir, 'js') style_names = \ 'partition_tree', \ 'icon', \ 'toolbar', \ 'nodedata', \ 'legend', \ 'awesomplete' styles = read_files((style_names), style_dir, 'css') with open(os.path.join(style_dir, "icomoon.woff"), "rb") as f: encoded_font = str(base64.b64encode(f.read()).decode("ascii")) with open(os.path.join(style_dir, "logo_png.b64"), "r") as f: logo_png = str(f.read()) if title: title = "OpenMDAO Model Hierarchy and N2 diagram: %s" % title else: title = "OpenMDAO Model Hierarchy and N2 diagram" h = DiagramWriter(filename=os.path.join(vis_dir, "index.html"), title=title, styles=styles, embeddable=embeddable) if (embeddable): h.insert("non-embedded-n2", "embedded-n2") # put all style and JS into index h.insert('{{fontello}}', encoded_font) h.insert('{{logo_png}}', logo_png) for k, v in lib_dct.items(): h.insert('{{{}_lib}}'.format(k), write_script(libs[v], indent=_IND)) for name, code in srcs.items(): h.insert('{{{}_lib}}'.format(name.lower()), write_script(code, indent=_IND)) h.insert('{{model_data}}', write_script(model_data, indent=_IND)) # Help help_txt = ( 'Left clicking on a node in the partition tree will navigate to that node. ' 'Right clicking on a node in the model hierarchy will collapse/expand it. ' 'A click on any element in the N2 diagram will allow those arrows to persist.' ) help_diagram_svg_filepath = os.path.join(assets_dir, "toolbar_help.svg") h.add_help(help_txt, help_diagram_svg_filepath, footer="OpenMDAO Model Hierarchy and N2 diagram") # Write output file h.write(outfile) # open it up in the browser if show_browser: from openmdao.utils.webview import webview webview(outfile)
def n2(data_source, outfile='n2.html', show_browser=True, embeddable=False, title=None, use_declare_partial_info=False): """ Generate an HTML file containing a tree viewer. Optionally opens a web browser to view the file. Parameters ---------- data_source : <Problem> or str The Problem or case recorder database containing the model or model data. outfile : str, optional The name of the final output file show_browser : bool, optional If True, pop up the system default web browser to view the generated html file. Defaults to True. embeddable : bool, optional If True, gives a single HTML file that doesn't have the <html>, <DOCTYPE>, <body> and <head> tags. If False, gives a single, standalone HTML file for viewing. title : str, optional The title for the diagram. Used in the HTML title. use_declare_partial_info : bool, optional If True, in the N2 matrix, component internal connectivity computed using derivative declarations, otherwise, derivative declarations ignored, so dense component connectivity is assumed. """ # grab the model viewer data model_data = _get_viewer_data(data_source) # if MPI is active only display one copy of the viewer if MPI and MPI.COMM_WORLD.rank != 0: return options = {'use_declare_partial_info': use_declare_partial_info} model_data['options'] = options model_data = 'var modelData = %s' % json.dumps(model_data, default=make_serializable) import openmdao openmdao_dir = os.path.dirname(inspect.getfile(openmdao)) vis_dir = os.path.join(openmdao_dir, "visualization/n2_viewer") libs_dir = os.path.join(vis_dir, "libs") src_dir = os.path.join(vis_dir, "src") style_dir = os.path.join(vis_dir, "style") # grab the libraries, src and style lib_dct = { 'd3': 'd3.v5.min', 'awesomplete': 'awesomplete', 'vk_beautify': 'vkBeautify' } libs = read_files(itervalues(lib_dct), libs_dir, 'js') src_names = \ 'modal', \ 'utils', \ 'SymbolType', \ 'N2TreeNode', \ 'ModelData', \ 'N2Style', \ 'N2Layout', \ 'N2MatrixCell', \ 'N2Legend', \ 'N2Matrix', \ 'N2Arrow', \ 'N2Search', \ 'N2Diagram', \ 'N2UserInterface', \ 'defaults', \ 'ptN2' srcs = read_files(src_names, src_dir, 'js') styles = read_files(('awesomplete', 'partition_tree'), style_dir, 'css') with open(os.path.join(style_dir, "fontello.woff"), "rb") as f: encoded_font = str(base64.b64encode(f.read()).decode("ascii")) if title: title = "OpenMDAO Model Hierarchy and N2 diagram: %s" % title else: title = "OpenMDAO Model Hierarchy and N2 diagram" h = DiagramWriter(filename=os.path.join(vis_dir, "index.html"), title=title, styles=styles, embeddable=embeddable) # put all style and JS into index h.insert('{{fontello}}', encoded_font) for k, v in iteritems(lib_dct): h.insert('{{{}_lib}}'.format(k), write_script(libs[v], indent=_IND)) for name, code in iteritems(srcs): h.insert('{{{}_lib}}'.format(name.lower()), write_script(code, indent=_IND)) h.insert('{{model_data}}', write_script(model_data, indent=_IND)) # Toolbar toolbar = h.toolbar group1 = toolbar.add_button_group() group1.add_button("Return To Root", uid="returnToRootButtonId", disabled="disabled", content="icon-home") group1.add_button("Back", uid="backButtonId", disabled="disabled", content="icon-left-big") group1.add_button("Forward", uid="forwardButtonId", disabled="disabled", content="icon-right-big") group1.add_button("Up One Level", uid="upOneLevelButtonId", disabled="disabled", content="icon-up-big") group2 = toolbar.add_button_group() group2.add_button("Uncollapse In View Only", uid="uncollapseInViewButtonId", content="icon-resize-full") group2.add_button("Uncollapse All", uid="uncollapseAllButtonId", content="icon-resize-full bigger-font") group2.add_button("Collapse Outputs In View Only", uid="collapseInViewButtonId", content="icon-resize-small") group2.add_button("Collapse All Outputs", uid="collapseAllButtonId", content="icon-resize-small bigger-font") group2.add_dropdown("Collapse Depth", button_content="icon-sort-number-up", uid="idCollapseDepthDiv") group3 = toolbar.add_button_group() group3.add_button("Clear Arrows and Connections", uid="clearArrowsAndConnectsButtonId", content="icon-eraser") group3.add_button("Show Path", uid="showCurrentPathButtonId", content="icon-terminal") group3.add_button("Show Legend", uid="showLegendButtonId", content="icon-map-signs") group3.add_button("Toggle Solver Names", uid="toggleSolverNamesButtonId", content="icon-minus") group3.add_dropdown("Font Size", id_naming="idFontSize", options=_FONT_SIZES, option_formatter=lambda x: '{}px'.format(x), button_content="icon-text-height") group3.add_dropdown("Vertically Resize", id_naming="idVerticalResize", options=_MODEL_HEIGHTS, option_formatter=lambda x: '{}px'.format(x), button_content="icon-resize-vertical", header="Model Height") group4 = toolbar.add_button_group() group4.add_button("Save SVG", uid="saveSvgButtonId", content="icon-floppy") group5 = toolbar.add_button_group() group5.add_button("Help", uid="helpButtonId", content="icon-help") # Help help_txt = ( 'Left clicking on a node in the partition tree will navigate to that node. ' 'Right clicking on a node in the model hierarchy will collapse/uncollapse it. ' 'A click on any element in the N^2 diagram will allow those arrows to persist.' ) h.add_help(help_txt, footer="OpenMDAO Model Hierarchy and N^2 diagram") # Write output file h.write(outfile) # open it up in the browser if show_browser: from openmdao.utils.webview import webview webview(outfile)