コード例 #1
0
    def __init__(
            self, template_path, options=None, styles=None, stencils=tuple()):
        """
        :param str template_path: Path where graph HTML templates are
            located.
        :param GraphOptions options: Options of graph drawing widget,
            uses default if not given.
        :param GraphStyles styles: Styles available in graph drawing
            widget, uses default if not given.
        :param iterable[str] stencils: Stencils available in graph drawing
            widget.
        """
        self.template_path = template_path

        from qmxgraph.configuration import GraphStyles
        from qmxgraph.configuration import GraphOptions

        if options is None:
            options = GraphOptions()

        if styles is None:
            styles = GraphStyles()

        self.options = options
        self.styles = styles
        self.stencils = stencils
コード例 #2
0
ファイル: main.py プロジェクト: HowardLee1992/qmxgraph
    def __init__(self):
        QMainWindow.__init__(self)

        self.setMinimumSize(QSize(640, 480))
        self.setWindowTitle("Qmx Styles")

        styles_cfg = {
            'round_node': {
                'shape': 'ellipse',
                'fill_color': '#D88',
                'vertical_label_position': 'bottom',
                'vertical_align': 'top',
            },
            'bold_edge': {
                'end_arrow': 'classic',
                'shape': 'connector',
                'stroke_width': 5.0,
            },
        }

        self.graph_widget = QmxGraph(styles=GraphStyles(styles_cfg),
                                     parent=self)
        # Only operate with the qmx's api after the widget has been loaded.
        self.graph_widget.loadFinished.connect(self.graph_load_handler)
        self.setCentralWidget(self.graph_widget)
コード例 #3
0
ファイル: test_js_graph.py プロジェクト: tadeu/qmxgraph
def test_custom_shapes(selenium, port, tmpdir, wait_graph_page_ready):
    """
    :type selenium: selenium.webdriver.remote.webdriver.WebDriver
    :type port: qmxgraph.tests.conftest.Port
    """
    # Shape found in by https://www.draw.io/stencils/basic.xml
    custom_stencil = '''\
<shapes>
    <shape name="Moon" h="103.05" w="77.05" aspect="variable" strokewidth="inherit">
        <connections>
            <constraint x="0.48" y="0" perimeter="0" name="N"/>
            <constraint x="1" y="0.89" perimeter="0" name="SE"/>
        </connections>
        <background>
            <path>
                <move x="37.05" y="0"/>
                    <arc rx="48" ry="48" x-axis-rotation="0" large-arc-flag="1" sweep-flag="0" x="77.05" y="92"/>
                    <arc rx="60" ry="60" x-axis-rotation="0" large-arc-flag="0" sweep-flag="1" x="37.05" y="0"/>
                <close/>
            </path>
        </background>
        <foreground>
            <fillstroke/>
        </foreground>
    </shape>
</shapes>'''  # noqa

    stencil_file = tmpdir.mkdir("stencils").join("custom.xml")
    stencil_file.write(custom_stencil)
    stencils = [str(stencil_file)]

    styles = GraphStyles({
        'moon': {
            'shape': 'Moon',
            'fill_color': '#ffff00',
        },
    })

    def has_custom_shape():
        return bool(
            selenium.find_elements_by_css_selector('g>g>path[fill="#ffff00"]'))

    with server.host(port=port.get(), styles=styles,
                     stencils=stencils) as host:
        wait_graph_page_ready(host=host)
        assert not has_custom_shape()
        selenium.execute_script(
            "api.insertVertex(10, 10, 20, 20, 'custom', 'moon')")
        assert has_custom_shape()
コード例 #4
0
ファイル: test_js_graph.py プロジェクト: tadeu/qmxgraph
def test_edge_with_style(port, mode, graph_cases_factory):
    """
    :type port: qmxgraph.tests.conftest.Port
    :type mode: str
    :type graph_cases_factory: callable
    """
    styles = GraphStyles({
        'edge': {
            'stroke_color': '#000000',
        },
    })

    with server.host(port=port.get(), styles=styles) as host:
        cases = graph_cases_factory(host)
        graph = cases('2v_1e' if mode == 'by_code' else '2v_1eDD')
        assert graph.get_edge(
            *graph.get_vertices()).get_attribute('stroke') == '#000000'
コード例 #5
0
ファイル: conftest.py プロジェクト: HowardLee1992/qmxgraph
def host(port):
    """
    Hosts a graph page, with a series of simple default options and styles.

    :type port: Port
    :rtype: qmxgraph.host_graph.Host
    :return: Object with details about hosted graph page.
    """
    from qmxgraph.configuration import GraphStyles
    styles = GraphStyles({
        'group': {
            'shape': 'rectangle',
            'fill_color': '#ff93ba',
            'dashed': True,
        },
        'table': {
            'fill_color': '#ffffff',
            'stroke_opacity': 0,
            'fill_opacity': 0,
        },
        'yellow': {
            'fill_color': '#ffff00',
        },
        'purple': {
            'fill_color': '#ff00ff',
        },
    })

    from qmxgraph.configuration import GraphOptions
    options = GraphOptions(
        # Highlight disabled for this kind of test as interferes a lot with
        # some mouse events, preventing Selenium from clicking desired
        # HTML elements.
        show_highlight=False,
    )

    from qmxgraph import server
    with server.host(port=port.get(), styles=styles, options=options) as host_:
        yield host_
コード例 #6
0
    def __init__(
            self,
            options=None,
            styles=None,
            stencils=tuple(),
            auto_load=True,
            parent=None,
    ):
        """
        :param qmxgraph.configuration.GraphOptions|None options: Features
            enabled in graph drawing widget. If none given, uses defaults.
        :param qmxgraph.configuration.GraphStyles|None styles: Additional
            styles made available for graph drawing widget besides mxGraph's
            default ones. If none given only mxGraph defaults are available.
        :param iterable[str] stencils: A sequence of XMLs available in Qt
            resource collections. Each XML must respect format defined by
            mxGraph (see
            https://jgraph.github.io/mxgraph/docs/js-api/files/shape/mxStencil-js.html#mxStencil
            and
            https://jgraph.github.io/mxgraph/javascript/examples/stencils.xml
            for reference).
        :param bool auto_load: If should load page as soon as widget is
            initialized.
        :param QWidget|None parent: Parent widget.
        """
        QWidget.__init__(self, parent)

        self._own_path = ':/qmxgraph'
        self._mxgraph_path = ':/mxgraph'

        if options is None:
            options = GraphOptions()
        self._options = options

        if styles is None:
            styles = GraphStyles(styles={})
        self._styles = styles

        self._stencils = stencils

        # Web view fills whole widget area
        self._layout = QGridLayout(self)
        self._layout.setContentsMargins(0, 0, 0, 0)  # no margin to web view

        self._web_view = QWebViewWithDragDrop()
        self._web_view.setSizePolicy(QSizePolicy.Expanding,
                                     QSizePolicy.Expanding)
        # Starts disabled, only enable once finished loading page (as user
        # interaction before that would be unsafe)
        # TODO: widget remain with disabled appearance even after enabled
        # self.setEnabled(False)

        self._layout.addWidget(self._web_view, 0, 0, 1, 1)

        self._error_bridge = None
        self._events_bridge = None
        self._drag_drop_handler = None

        # Similar to a browser, QmxGraph widget is going to allow inspection by
        # typing F12
        self._inspector_dialog = None
        inspector_shortcut = QShortcut(self)
        inspector_shortcut.setKey("F12")
        inspector_shortcut.activated.connect(self.toggle_inspector)

        self._execute_on_load_finished()

        self._api = QmxGraphApi(graph=self)

        self._web_view.on_drag_enter_event.connect(self._on_drag_enter)
        self._web_view.on_drag_move_event.connect(self._on_drag_move)
        self._web_view.on_drop_event.connect(self._on_drop)

        self._double_click_bridge = _DoubleClickBridge()
        self._popup_menu_bridge = _PopupMenuBridge()

        if auto_load:
            self._load_graph_page()