예제 #1
0
def view_model(data_source,
               outfile='n2.html',
               show_browser=True,
               embeddable=False,
               title=None,
               use_declare_partial_info=False):
    """
    Generates 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 and also shown on the page.

    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)
    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)

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

    code_dir = os.path.dirname(os.path.abspath(__file__))
    vis_dir = os.path.join(code_dir, "visualization")
    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.v4.min',
        'awesomplete': 'awesomplete',
        'vk_beautify': 'vkBeautify'
    }
    libs = read_files(itervalues(lib_dct), libs_dir, 'js')
    src_names = 'constants', 'draw', 'legend', 'modal', 'ptN2', 'search', 'svg'
    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")

    if use_declare_partial_info:
        h.insert(
            '{{component_connectivity}}',
            'Note: Component internal connectivity computed using derivative declarations'
        )
    else:
        h.insert(
            '{{component_connectivity}}',
            'Note: Derivative declarations ignored, so dense component connectivity is assumed'
        )

    # Write output file
    h.write(outfile)

    # open it up in the browser
    if show_browser:
        from openmdao.devtools.webview import webview
        webview(outfile)
예제 #2
0
def write_html(outfile, source_data=None, data_file=None, embeddable=False):
    """
    Writes XDSMjs HTML output file, with style and script files embedded.

    The source data can be the name of a JSON file or a dictionary.
    If a JSON file name is provided, the file will be referenced in the HTML.
    If the input is a dictionary, it will be embedded.

    If both data file and source data are given, data file is

    Parameters
    ----------
    outfile : str
        Output HTML file
    source_data : str or dict or None
        XDSM data in a dictionary or string
    data_file : str or None
        Output HTML file
    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.
    """

    # directories
    main_dir = os.path.dirname(os.path.abspath(__file__))
    code_dir = os.path.join(main_dir, 'XDSMjs')
    build_dir = os.path.join(code_dir, "build")
    style_dir = code_dir  # CSS

    with open(os.path.join(build_dir, "xdsm.bundle.js"), "r") as f:
        code = f.read()
        xdsm_bundle = write_script(code, {'type': 'text/javascript'})

    xdsm_attrs = {'class': 'xdsm'}
    # grab the data
    if data_file is not None:
        # Add name of the data file
        xdsm_attrs['data-mdo-file'] = data_file
    elif source_data is not None:
        if isinstance(source_data, (dict, str)):
            data_str = str(source_data)  # dictionary converted to string
        else:
            msg = (
                'Invalid data type for source data: {} \n'
                'The source data should be a JSON file name or a dictionary.')
            raise ValueError(msg.format(type(source_data)))

        # Replace quote marks for the HTML syntax
        for i in ('u"', "u'", '"', "'"):  # quote marks and unicode prefixes
            data_str = data_str.replace(i, r'&quot;')
        xdsm_attrs['data-mdo'] = data_str
    else:  # both source data and data file name are None
        msg = 'Specify either "source_data" or "data_file".'
        raise ValueError(msg.format(type(source_data)))

    # grab the style
    styles = read_files(('fontello', 'xdsm'), style_dir, 'css')
    styles_elem = write_style(content='\n\n'.join(itervalues(styles)))

    # put all style and JS into index
    toolbar_div = write_div(attrs={'class': 'xdsm-toolbar'})
    xdsm_div = write_div(attrs=xdsm_attrs)
    body = '\n\n'.join([toolbar_div, xdsm_div])

    if embeddable:
        index = '\n\n'.join([styles_elem, xdsm_bundle, body])
    else:
        meta = '<meta charset="{}">'.format(_CHAR_SET)

        head = '\n\n'.join([meta, styles_elem, xdsm_bundle])

        index = head_and_body(head, body, attrs={'class': "js", 'lang': ""})

    # Embed style, scripts and data to HTML
    with open(outfile, 'w') as f:
        f.write(index)
예제 #3
0
def view_model(data_source, outfile='n2.html', show_browser=True, embeddable=False,
               title=None):
    """
    Generates 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 and also shown on the page.

    """
    # grab the model viewer data
    model_data = _get_viewer_data(data_source)
    model_data = 'var modelData = %s' % json.dumps(model_data, default=make_serializable)

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

    code_dir = os.path.dirname(os.path.abspath(__file__))
    vis_dir = os.path.join(code_dir, "visualization")
    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.v4.min', 'awesomplete': 'awesomplete', 'vk_beautify': 'vkBeautify'}
    libs = read_files(itervalues(lib_dct), libs_dir, 'js')
    src_names = 'constants', 'draw', 'legend', 'modal', 'ptN2', 'search', 'svg'
    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("Show Params", uid="showParamsButtonId", content="icon-exchange")
    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.devtools.webview import webview
        webview(outfile)
예제 #4
0
def write_html(outfile, source_data=None, data_file=None, embeddable=False):
    """
    Writes XDSMjs HTML output file, with style and script files embedded.

    The source data can be the name of a JSON file or a dictionary.
    If a JSON file name is provided, the file will be referenced in the HTML.
    If the input is a dictionary, it will be embedded.

    If both data file and source data are given, data file is

    Parameters
    ----------
    outfile : str
        Output HTML file
    source_data : str or dict or None
        XDSM data in a dictionary or string
    data_file : str or None
        Output HTML file
    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.
    """

    # directories
    main_dir = os.path.dirname(os.path.abspath(__file__))
    code_dir = os.path.join(main_dir, 'XDSMjs')
    build_dir = os.path.join(code_dir, "build")
    style_dir = code_dir  # CSS

    with open(os.path.join(build_dir, "xdsm.bundle.js"), "r") as f:
        code = f.read()
        xdsm_bundle = write_script(code, {'type': 'text/javascript'})

    xdsm_attrs = {'class': 'xdsm'}
    # grab the data
    if data_file is not None:
        # Add name of the data file
        xdsm_attrs['data-mdo-file'] = data_file
    elif source_data is not None:
        if isinstance(source_data, (dict, str)):
            data_str = str(source_data)  # dictionary converted to string
        else:
            msg = ('Invalid data type for source data: {} \n'
                   'The source data should be a JSON file name or a dictionary.')
            raise ValueError(msg.format(type(source_data)))

        # Replace quote marks for the HTML syntax
        for i in ('u"', "u'", '"', "'"):  # quote marks and unicode prefixes
            data_str = data_str.replace(i, r'&quot;')
        xdsm_attrs['data-mdo'] = data_str
    else:  # both source data and data file name are None
        msg = 'Specify either "source_data" or "data_file".'
        raise ValueError(msg.format(type(source_data)))

    # grab the style
    styles = read_files(('fontello', 'xdsm'), style_dir, 'css')
    styles_elem = write_style(content='\n\n'.join(itervalues(styles)))

    # put all style and JS into index
    toolbar_div = write_div(attrs={'class': 'xdsm-toolbar'})
    xdsm_div = write_div(attrs=xdsm_attrs)
    body = '\n\n'.join([toolbar_div, xdsm_div])

    if embeddable:
        index = '\n\n'.join([styles_elem, xdsm_bundle, body])
    else:
        meta = '<meta charset="{}">'.format(_CHAR_SET)

        head = '\n\n'.join([meta, styles_elem, xdsm_bundle])

        index = head_and_body(head, body, attrs={'class': "js", 'lang': ""})

    # Embed style, scripts and data to HTML
    with open(outfile, 'w') as f:
        f.write(index)
예제 #5
0
def view_model(data_source, outfile='n2.html', show_browser=True, embeddable=False,
               draw_potential_connections=True):
    """
    Generates 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.

    draw_potential_connections : bool, optional
        If true, allows connections to be drawn on the N2 that do not currently exist
        in the model. Defaults to True.
    """
    # grab the model viewer data
    model_viewer_data = _get_viewer_data(data_source)
    model_viewer_data = 'var modelData = %s' % json.dumps(model_viewer_data)

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

    code_dir = os.path.dirname(os.path.abspath(__file__))
    vis_dir = os.path.join(code_dir, "visualization")
    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.v4.min', 'awesomplete': 'awesomplete', 'vk_beautify': 'vkBeautify'}
    libs = read_files(itervalues(lib_dct), libs_dir, 'js')
    src_names = 'constants', 'draw', 'legend', 'modal', 'ptN2', 'search', 'svg'
    srcs = read_files(src_names, src_dir, 'js')
    styles = read_files(('awesomplete', 'partition_tree'), style_dir, 'css')
    style_elems = '\n\n'.join([write_style(content=s) for s in itervalues(styles)])

    with open(os.path.join(style_dir, "fontello.woff"), "rb") as f:
        encoded_font = str(base64.b64encode(f.read()).decode("ascii"))

    # grab the index.html
    with open(os.path.join(vis_dir, "index.html"), "r") as f:
        index = f.read()

    # add the necessary HTML tags if we aren't embedding
    if embeddable:
        index = '\n\n'.join([style_elems, index])
    else:
        meta = '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'
        head = '\n\n'.join([meta, style_elems])  # Write styles to head
        index = head_and_body(head=head, body=index)

    # put all style and JS into index
    index = index.replace('{{fontello}}', encoded_font)

    for k, v in iteritems(lib_dct):
        index = index.replace('{{{}_lib}}'.format(k), write_script(libs[v], indent=4))

    for name, code in iteritems(srcs):
        index = index.replace('{{{}_lib}}'.format(name.lower()), write_script(code, indent=4))

    index = index.replace('{{model_data}}', write_script(model_viewer_data, indent=4))
    index = index.replace('{{draw_potential_connections}}', str(draw_potential_connections).lower())

    with open(outfile, 'w') as f:  # write output file
        f.write(index)

    # open it up in the browser
    if show_browser:
        from openmdao.devtools.webview import webview
        webview(outfile)
예제 #6
0
def view_model(data_source,
               outfile='n2.html',
               show_browser=True,
               embeddable=False,
               draw_potential_connections=True):
    """
    Generates 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.

    draw_potential_connections : bool, optional
        If true, allows connections to be drawn on the N2 that do not currently exist
        in the model. Defaults to True.
    """
    # grab the model viewer data
    model_viewer_data = _get_viewer_data(data_source)
    model_viewer_data = 'var modelData = %s' % json.dumps(model_viewer_data)

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

    code_dir = os.path.dirname(os.path.abspath(__file__))
    vis_dir = os.path.join(code_dir, "visualization")
    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.v4.min',
        'awesomplete': 'awesomplete',
        'vk_beautify': 'vkBeautify'
    }
    libs = read_files(itervalues(lib_dct), libs_dir, 'js')
    src_names = 'constants', 'draw', 'legend', 'modal', 'ptN2', 'search', 'svg'
    srcs = read_files(src_names, src_dir, 'js')
    styles = read_files(('awesomplete', 'partition_tree'), style_dir, 'css')
    style_elems = '\n\n'.join(
        [write_style(content=s) for s in itervalues(styles)])

    with open(os.path.join(style_dir, "fontello.woff"), "rb") as f:
        encoded_font = str(base64.b64encode(f.read()).decode("ascii"))

    # grab the index.html
    with open(os.path.join(vis_dir, "index.html"), "r") as f:
        index = f.read()

    # add the necessary HTML tags if we aren't embedding
    if embeddable:
        index = '\n\n'.join([style_elems, index])
    else:
        meta = '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'
        head = '\n\n'.join([meta, style_elems])  # Write styles to head
        index = head_and_body(head=head, body=index)

    # put all style and JS into index
    index = index.replace('{{fontello}}', encoded_font)

    for k, v in iteritems(lib_dct):
        index = index.replace('{{{}_lib}}'.format(k),
                              write_script(libs[v], indent=4))

    for name, code in iteritems(srcs):
        index = index.replace('{{{}_lib}}'.format(name.lower()),
                              write_script(code, indent=4))

    index = index.replace('{{model_data}}',
                          write_script(model_viewer_data, indent=4))
    index = index.replace('{{draw_potential_connections}}',
                          str(draw_potential_connections).lower())

    with open(outfile, 'w') as f:  # write output file
        f.write(index)

    # open it up in the browser
    if show_browser:
        from openmdao.devtools.webview import webview
        webview(outfile)