Exemplo n.º 1
0
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 : 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)

    # 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'
    }
    libs = read_files(lib_dct.values(), libs_dir, 'js')
    src_names = \
        'utils', \
        'SymbolType', \
        'N2TreeNode', \
        'ModelData', \
        'N2Style', \
        'N2Layout', \
        'N2MatrixCell', \
        'N2Legend', \
        'N2Matrix', \
        'N2Arrow', \
        'N2Search', \
        'N2Toolbar', \
        'N2Diagram', \
        'NodeInfo', \
        '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())

    with open(os.path.join(assets_dir, "spinner.png"), "rb") as f:
        waiting_icon = 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)

    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)
    h.insert('{{waiting_icon}}', waiting_icon)

    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)
Exemplo n.º 2
0
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.

    """
    # if MPI is active only display one copy of the viewer
    if MPI and MPI.COMM_WORLD.rank != 0:
        return

    # grab the model viewer data
    model_data = _get_viewer_data(data_source)
    options = {}
    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 = \
        'legend', \
        'modal', \
        'utils', \
        'SymbolType', \
        'N2TreeNode', \
        'ModelData', \
        'N2Style', \
        'N2Layout', \
        'N2MatrixCell', \
        'N2Matrix', \
        'N2Arrow', \
        'N2Diagram', \
        'N2UserInterface', \
        'defaults', \
        'ptN2', \
        'search'
    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)