Gaphas is the diagramming widget library for Python.

Overview

Gaphas

Build state Maintainability Test Coverage Docs build state Code style: black standard-readme compliant Gitter All Contributors

Gaphas is the diagramming widget library for Python.

Gaphas Demo

Gaphas is a library that provides the user interface component (widget) for drawing diagrams. Diagrams can be drawn to screen and then easily exported to a variety of formats, including SVG and PDF. Want to build an app with chart-like diagrams? Then Gaphas is for you! Use this library to build a tree, network, flowchart, or other diagrams.

This library is currently being used by Gaphor for UML drawing, RAFCON for state-machine based robot control, and ASCEND for solving mathematical models.

📑 Table of Contents

📜 Background

Gaphas was built to provide the foundational diagramming portions of Gaphor. Since Gaphor is built on GTK and Cairo, PyGObject provides access to the GUI toolkit and PyCairo to the 2D graphics library. However, there wasn't a project that abstracted these technologies to easily create a diagramming tool. Hence, Gaphas was created as a library to allow others to create a diagramming tool using GTK and Cairo.

Here is how it works:

  • Items (Canvas items) can be added to a Canvas.
  • The Canvas maintains the tree structure (parent-child relationships between items).
  • A constraint solver is used to maintain item constraints and inter-item constraints.
  • The item (and user) should not be bothered with things like bounding-box calculations.
  • Very modular--e.g., handle support could be swapped in and swapped out.
  • Rendering using Cairo.

The main portions of the library include:

  • canvas - The main canvas class (container for Items).
  • items - Objects placed on a Canvas.
  • solver - A constraint solver to define the layout and connection of items.
  • gtkview - A view to be used in GTK applications that interacts with users with tools.
  • painters - The workers used to paint items.
  • tools - Tools are used to handle user events (such as mouse movement and button presses).
  • aspects - Provides an intermediate step between tools and items.

Gaphas contains default implementations for Canvas and Items. There are protocols in place to allow you to make your own canvas.

💾 Install

To install Gaphas, simply use pip:

$ pip install gaphas

Use of a virtual environment is highly recommended.

Development

To setup a development environment with Linux:

$ sudo apt-get install -y python3-dev python3-gi python3-gi-cairo
    gir1.2-gtk-3.0 libgirepository1.0-dev libcairo2-dev
$ pip install poetry
$ poetry install

🔦 Usage

API docs and tutorials can be found on Read the Docs.

Contributing

Thanks goes to these wonderful people (emoji key):

Arjan Molenaar
Arjan Molenaar

💻 🐛 📖 👀 💬 🔌
Dan Yeaw
Dan Yeaw

💻 ⚠️ 👀 🐛 💬 🚇 📖
wrobell
wrobell

💻 ⚠️ 👀
Jean-Luc Stevens
Jean-Luc Stevens

💻 🐛 📖
Franz Steinmetz
Franz Steinmetz

💻 🐛
Adrian Boguszewski
Adrian Boguszewski

💻
Rico Belder
Rico Belder

🐛 👀
Adam Boduch
Adam Boduch

🐛
Janet Jose
Janet Jose

📖

This project follows the all-contributors specification. Contributions of any kind are welcome!

  1. Check for open issues or open a fresh issue to start a discussion around a feature idea or a bug. There is a first-timers-only tag for issues that should be ideal for people who are not very familiar with the codebase yet.
  2. Fork the repository on GitHub to start making your changes to the master branch (or branch off of it).
  3. Write a test which shows that the bug was fixed or that the feature works as expected.
  4. Send a pull request and bug the maintainers until it gets merged and published. 😄

See the contributing file!

© License

Copyright © Arjan Molenaar and Dan Yeaw

Licensed under the Apache License 2.0.

Summary: You can do what you like with Gaphas, as long as you include the required notices. This permissive license contains a patent license from the contributors of the code.

Comments
  • Convert from PyGTK to PyGObject

    Convert from PyGTK to PyGObject

    Conversion from PyGTK to PyGObject (and Gtk+ 2 to 3). Steps taken include:

    1. Automatic rename using pygi-convert.sh to do basic find and replace between PyGTK and PyGObject syntax.
    2. Fixed some additional Python 3 compatibility cleanups with ez_setup and the tests
    3. Completed manual updates to finish the conversion, including the largest update which was to replace the scroll adjustment signals to inherit from Gtk.Scrollable

    All tests pass with both Python 2.7.15 and 3.7.0.

    opened by danyeaw 17
  • Record drawn items

    Record drawn items

    PR Type

    What kind of change does this PR introduce?

    • [ ] Bugfix
    • [X] Feature
    • [ ] Code style update (formatting, local variables)
    • [ ] Refactoring (no functional changes, no api changes)
    • [ ] Documentation content changes

    What is the current behavior?

    Drawing of complex (diagrams) is relatively slow, especially on platforms like macOS. Although the GtkView already uses a back-buffer, it still needs to draw() all elements when the widget is repainted. Worst case it needs to redraw it multiple times: once for bounding box calculation and any number of times to refresh the back buffer.

    Issue Number: N/A

    What is the new behavior?

    This PR contains a couple of improvements:

    • When items are painted for bounding box calculation, the resulting drawing (a cairo surface) is cached, so subsequent drawing operations can reuse this effort.
    • A special painter, RenderedItemPainter, can be used to draw items previously rendered.
    • The view is now automatically redrawn if the view's matrix has changed.
    • Update handling has been simplified. There are no matrix-updates anymore.

    Does this PR introduce a breaking change?

    • [X] Yes
    • [ ] No
    • update API

    Other information

    Since items were already drawn with the right offset (done by ItemPainter), it makes no sense to have a separate matrix-update. Such an update will result in a redraw anyway.

    As a result all matrix-update logic has been removed from GtkView, which resulted in a simpler interface. A nice bonus.

    I also considered putting a cache in ItemPainter. It is not easy to pass on data on which item needs updating and which items are removed. Therefore it seemed more logical to keep this data in the view and instead create a separate renderer (RenderedItemPainter), that takes a rendered surface from the view and draws that instead.

    BoundingBoxPainter is not needed anymore. It's kept in for now to ease the transition to the new drawing model.

    It looks like drawing is considerably slower when the demo app is in full screen. Small windows are fast, bigger ones are slow.

    To do

    • [x] There's still an issue where attached elements are not properly redrawn
    feature 
    opened by amolenaar 11
  • Back buffer: No drawing during resize of widget

    Back buffer: No drawing during resize of widget

    Is it intended/desired that during a resize operation of the GtkView, the canvas is not drawn, i.e. only the background color is visible?

    Our canvas is nested in (several) Gtk.Paned and resides next to a Gtk.Revealer. Thus, in three situations, no state machine now shown:

    • the panes are resized
    • the revealer slides up
    • the window is resized

    Personally, I would want the canvas to be drawn in all these situations.

    opened by franzlst 10
  • Updated README

    Updated README

    Hello,

    I have updated the README of Gaphas. I have reviewed and edited the file for :

    1. Spelling and grammar
    2. Edited the hyperlinks for virtual env

    I do have comments on this line-- The constraint solver can also be used to keep constraints contained within the item true, for example, to make sure a box maintains its rectangular shape. (the word "true" is confusing).

    opened by janettech 10
  • Is gaphas accepting new contributions and pull requests?

    Is gaphas accepting new contributions and pull requests?

    First, I wish to thank you for your work on gaphas!

    Gaphas has been a real delight to use. The code is of excellent quality, very readable and well documented. I love that gaphas has minimal dependencies, is written in pure Python and successfully abstracts away the more painful parts of using a gtk.DrawingArea as a canvas. Gaphas is quite wonderful, thank you!

    I've been working on a prototype project using gaphas to implement something like the Blender node editor. This project is currently in a private repository but I hope to make it public very soon.

    My main concern with gaphas is that the last public commit is from July 2012. Is development still active? Are you accepting pull requests? While learning gaphas, I have made several improvements that I would like to contribute back. Some suggestions that I would be happy to submit as a series of pull requests:

    • Multiple typo fixes.
    • Deletion of trailing whitespace.
    • Possible addition of a .gitignore to the gaphas repository.
    • Deletion of code that has been commented out (only a few instances of this).
    • Wrapping docstrings to 80 characters (mostly good already, but a few places could do with better wrapping).
    • A few other more technical ideas if you are interested!

    Please do tell me if you are interested in accepting these sorts of PRs!

    opened by jlstevens 8
  • simplegeneric => singledispatch: backward compatibility

    simplegeneric => singledispatch: backward compatibility

    With the change from simplegeneric to singledispatch, gaphas is no longer backward compatible with code that registers custom types, as you now need to call register instead of when_type.

    This is fine, as you increase the minor version.

    I was just wondering, whether you think there is an easy way for other software not requiring any code changes. Maybe somehow monkeypatching singledispatch? Doesn't sound like the best solution :-D

    opened by franzlst 6
  • Comments on the Gaphas documentation

    Comments on the Gaphas documentation

    Hello Dan,

    As discussed earlier, here are my review comments on Gaphas docs. I hope you find them useful. If you find anything that is not clear, please do ask. Also, ignore if I did any mistakes.

    The latter part of my document you will find just the grammatical correction on the content. I hope you find the corrections.

    Thanks! Janet Gaphas.docx

    opened by janettech 6
  • Update from LGPL 2.0 to 2.1 (or Apache)

    Update from LGPL 2.0 to 2.1 (or Apache)

    This issue goes along with https://github.com/gaphor/gaphor/issues/61. GitHub supports displaying the license on the repository overview. It only supports licenses from choose a license, which includes the LGPL 2.1, but not 2.0.

    The main changes are rewording Library to Lesser, and adding another option for using a shared library mechanism: b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with.

    We are also considering moving to Apache instead of the LGPL, the summary of differences are:

    • LGPL requires that derivative works must be licensed using the LGPL as well
    • LGPL requires that source code must be disclosed with distribution, Apache does not
    • Apache requires an express grant of patent rights for contributions, LGPL v2.1 does not (v3 does)
    • Apache is more compatible, so we could include MIT or BSD software in our project, but we need to ensure that there is no other LGPL libraries that exist within the current software.

    Any other thoughts on upgrading to a newer version of the LGPL or to Apache?

    • [X] @danyeaw
    • [x] @amolenaar
    • [x] @wrobell
    • [X] @jlstevens - verified only removed whitespace and changed width of text
    • [X] @adrianboguszewski - no commits remain in current code base
    • [X] @franzlst
    opened by danyeaw 6
  • Fix Travis CI Build Config

    Fix Travis CI Build Config

    This change is to fix segmentation faults when trying to test Gaphas on Travis CI. These faults aren't reproducible locally, so this PR is to test the code using the CI.

    Signed-off-by: Dan Yeaw [email protected]

    opened by danyeaw 5
  • Improve render speed

    Improve render speed

    Is your feature request related to a problem?

    Currently, when implementing Item.draw(), you have to take into account speed: every time a canvas is redrawn, this method is called.

    Rendering is relatively slow, esp. on macOS.

    I did some trails with cairo.RecordingSurface, but that's probably not what we need: to render a surface it has to be applied as a pattern on the target surface. For our purposes it would be enough to just replay any drawing operation on the target surface. My assumption is that that will also be faster.

    Describe the solution you'd like

    When an item is drawn (the first time this happens is when the bounding box is calculated), the drawing operations should be recorded. On subsequent draws, the recorded items should be replayed. This ensures that:

    1. we always draw the same thing, until the item requires an update (keeps bounding box consistent)
    2. the concern of draw() being fast is less strict

    Solution to be determined still. See alternatives.

    Describe alternatives you've considered

    • Create a custom DrawingContext for Gaphas. Instead of calling DrawingContext.cairo methods, expose all required methods through DrawingContext directly. This should also expose methods for rendering Pango Layouts and SVG images (librsvg).
    • Use RecordingSurface. For one, @danyeaw got artifacts in the diagram. Secondly it's applied via patterns, where it's more logical for us to just just replay the recorded events on a surface.
    • Maybe add a bit of C/Cython) code that hooks into cairo and provides the required capabilities (e.g. expose RecordingSurface.replay or expose the surface observer code).

    Additional context

    We should handle SVG and Pango layouts as well. They render to a cairo.Context directly. Do we want to keep that interface, or provide a Gaphas specific way to render those?

    opened by amolenaar 4
  • GTK 4 support

    GTK 4 support

    PR Type

    What kind of change does this PR introduce?

    • [ ] Bugfix
    • [X] Feature
    • [ ] Code style update (formatting, local variables)
    • [ ] Refactoring (no functional changes, no api changes)
    • [ ] Documentation content changes

    The change

    Gaphas works for GTK+ 3. This PR adds support for GTK 4 -- without breaking backwards compatibility.

    Where there are incompatibilities between the GTK 3 and 4 api, a check for Gtk.get_major_version() == 3 is done.

    Tests can be executed with GTK 4 by running TEST_GTK_VERSION=4.0 pytest.

    Issue Number: https://github.com/gaphor/gaphor/issues/618

    Does this PR introduce a breaking change?

    • [ ] Yes
    • [X] No

    Other information

    In GTK 4, the canvas is a lot more responsive, on macOS at least.

    feature 
    opened by amolenaar 4
  • Line routing

    Line routing

    Many tools have an option to route lines, or at least create lines in a way that avoids other objects.

    Sources

    To create some sort of auto-layout thingy on top of this we'll need something like COLA (Constraint Layout)(https://www.adaptagrams.org/)

    Javascript implementation: https://ialab.it.monash.edu/webcola/ (github: https://github.com/tgdwyer/WebCola)

    opened by amolenaar 0
  • Obstacle avoidance for lines

    Obstacle avoidance for lines

    PR Type

    What kind of change does this PR introduce?

    • [ ] Bugfix
    • [X] Feature
    • [ ] Code style update (formatting, local variables)
    • [ ] Refactoring (no functional changes, no api changes)
    • [ ] Documentation content changes

    What is the current behavior?

    Lines are just straight.

    Issue Number: #360

    What is the new behavior?

    Gaphas has code that support object avoidance in the canvas.

    • [X] When a new line is drawn, the line tries to avoid obstacles
    • [ ] When an element is moved, the lines should move aside
    • [ ] When an element is moved, connected lines should reroute
    • [x] Avoidance for normal lines
    • [x] Avoidance for orthogonal lines
    • [ ] Sometimes the routing algorithm "hangs". Esp. when the paths are more complicated.

    Does this PR introduce a breaking change?

    • [X] Yes
    • [ ] No

    Other information

    Try examples/demo.py. The (experimental) collision avoidance code is activated there.

    feature 
    opened by amolenaar 1
Releases(3.9.2)
Owner
Gaphor
Gaphor is the simple modeling tool
Gaphor
Cartopy - a cartographic python library with matplotlib support

Cartopy is a Python package designed to make drawing maps for data analysis and visualisation easy. Table of contents Overview Get in touch License an

null 1.2k Jan 1, 2023
a plottling library for python, based on D3

Hello August 2013 Hello! Maybe you're looking for a nice Python interface to build interactive, javascript based plots that look as nice as all those

Mike Dewar 1.4k Dec 28, 2022
A Python Library for Self Organizing Map (SOM)

SOMPY A Python Library for Self Organizing Map (SOM) As much as possible, the structure of SOM is similar to somtoolbox in Matlab. It has the followin

Vahid Moosavi 497 Dec 29, 2022
Multi-class confusion matrix library in Python

Table of contents Overview Installation Usage Document Try PyCM in Your Browser Issues & Bug Reports Todo Outputs Dependencies Contribution References

Sepand Haghighi 1.3k Dec 31, 2022
NorthPitch is a python soccer plotting library that sits on top of Matplotlib

NorthPitch is a python soccer plotting library that sits on top of Matplotlib.

Devin Pleuler 30 Feb 22, 2022
The interactive graphing library for Python (includes Plotly Express) :sparkles:

plotly.py Latest Release User forum PyPI Downloads License Data Science Workspaces Our recommended IDE for Plotly’s Python graphing library is Dash En

Plotly 12.7k Jan 5, 2023
🎨 Python Echarts Plotting Library

pyecharts Python ❤️ ECharts = pyecharts English README ?? 简介 Apache ECharts (incubating) 是一个由百度开源的数据可视化,凭借着良好的交互性,精巧的图表设计,得到了众多开发者的认可。而 Python 是一门富有表达

pyecharts 13.1k Jan 3, 2023
Declarative statistical visualization library for Python

Altair http://altair-viz.github.io Altair is a declarative statistical visualization library for Python. With Altair, you can spend more time understa

Altair 6.4k Feb 13, 2021
Python library that makes it easy for data scientists to create charts.

Chartify Chartify is a Python library that makes it easy for data scientists to create charts. Why use Chartify? Consistent input data format: Spend l

Spotify 3.2k Jan 4, 2023
:small_red_triangle: Ternary plotting library for python with matplotlib

python-ternary This is a plotting library for use with matplotlib to make ternary plots plots in the two dimensional simplex projected onto a two dime

Marc 611 Dec 29, 2022
The interactive graphing library for Python (includes Plotly Express) :sparkles:

plotly.py Latest Release User forum PyPI Downloads License Data Science Workspaces Our recommended IDE for Plotly’s Python graphing library is Dash En

Plotly 8.9k Feb 18, 2021
🎨 Python Echarts Plotting Library

pyecharts Python ❤️ ECharts = pyecharts English README ?? 简介 Apache ECharts (incubating) 是一个由百度开源的数据可视化,凭借着良好的交互性,精巧的图表设计,得到了众多开发者的认可。而 Python 是一门富有表达

pyecharts 10.6k Feb 18, 2021
Declarative statistical visualization library for Python

Altair http://altair-viz.github.io Altair is a declarative statistical visualization library for Python. With Altair, you can spend more time understa

Altair 6.4k Feb 18, 2021
Python library that makes it easy for data scientists to create charts.

Chartify Chartify is a Python library that makes it easy for data scientists to create charts. Why use Chartify? Consistent input data format: Spend l

Spotify 2.8k Feb 18, 2021
:small_red_triangle: Ternary plotting library for python with matplotlib

python-ternary This is a plotting library for use with matplotlib to make ternary plots plots in the two dimensional simplex projected onto a two dime

Marc 391 Feb 17, 2021
A Python library created to assist programmers with complex mathematical functions

libmaths was created not only as a learning experience for me, but as a way to make mathematical models in seconds for Python users using mat

Simple 73 Oct 2, 2022
Python library that makes it easy for data scientists to create charts.

Chartify Chartify is a Python library that makes it easy for data scientists to create charts. Why use Chartify? Consistent input data format: Spend l

Spotify 3.2k Jan 1, 2023
Python histogram library - histograms as updateable, fully semantic objects with visualization tools. [P]ython [HYST]ograms.

physt P(i/y)thon h(i/y)stograms. Inspired (and based on) numpy.histogram, but designed for humans(TM) on steroids(TM). The goal is to unify different

Jan Pipek 120 Dec 8, 2022
High-level geospatial data visualization library for Python.

geoplot: geospatial data visualization geoplot is a high-level Python geospatial plotting library. It's an extension to cartopy and matplotlib which m

Aleksey Bilogur 1k Jan 1, 2023