jupyrdf / ipyforcegraph Goto Github PK
View Code? Open in Web Editor NEWJupyter Widgets for force-directed graphs
Home Page: https://ipyforcegraph.rtfd.io
License: BSD 3-Clause "New" or "Revised" License
Jupyter Widgets for force-directed graphs
Home Page: https://ipyforcegraph.rtfd.io
License: BSD 3-Clause "New" or "Revised" License
Add visibility
to nodes
and links
.
color
to rgb(0,0,0,0)
, i.e., zero opacity.force-graph
API a bit closer.alpha
in rgb
.visible
to NodeShapes
and LinkShapes
.
visible: TBoolFeature = _make_trait("is the link visible", boolish=True)
Add the ability to intercept more node and link events.
This is useful for linking other controls if the hover labels are not sufficient.
...
The ability to control the simulation heat/reheat parameters when making changes to the source and/or behaviors. A method for ex. pausing the simulation when applying certain style changes (e.g. node color), and a recommended design patter (within docs?) for how to achieve this desired effect.
We are developing apps using ipyforcegraph, and updating this such as node/edge visibility, color, and other styles (as part of the ipyforcegraph supported behaviors) causes the visualization to "reheat" the graph layout. Under certain conditions it would be valuable to allow users of ipyforcegraph to control the heat settings so that operations can be performed on the source and behaviors without causing the visualization to reheat. A recommended implementation from the dev team will help ensure that the most effective manner for controlling these options is used downstream.
Possibly set the config on the ForceGraph class (simplified e.g. fg.reheat = False
) before modifying behaviors/source/etc.
Expose behaviors to help control the DAG constraints.
Adds a layout mechanism that is more readable for DAG structure.
Force Graph Example:
Method to return the current x,y (or x,y,z for 3D) positions of the graph nodes as a DataFrame. The node data on the frontend updates those field values when the forcegraph layout sim runs. It would be useful to return those positions.
This would allow for better manual positioning of nodes between user interaction (e.g. reset-graph option without running sim), and potentially enable some interesting capability when toggling between 2D and 3D engines.
Not sure how this would be connected to the sim process (i.e. requesting before sim runs/completes).
N/A (at the moment)
Add an instrumented frontend build with istanbuljs
and reporting with nyc
. Run the jupyter_server
and ipykernel
processes under coverage
.
At present, the frontend has no assessment of test coverage, and the backend coverage from unit tests is lower than what is actually covered.
codecov
, etc. for capturing coverage trendsFor some concrete examples, see jupyterlab-deck.
ID
), have an option to retain their x,y,z
locationx,y,z
locations in the new dataframe and giving that back to ipyforcegraph
. But this adds complexity and overhead to the process.forcegraph
that determines if node locations should be retained. default=True
x,y,z
(and vx,vy,vz
?) if the node already exists.Particles are a unique story telling device in the force-graph library. Having the ability to specify a set of links to emit particles can allow more nuances to those stories.
Some ways we might use particle links:
Example from the force-graph library
Be able to show labels with the nodeLabel
feature.
Add a new Behavior
subclass that shows labels.
Explore whether this makes sense in metadata
, or as a separate ndarray, or something else entirely.
Rather than inferencing order of behaviors, would see adding a rank
to the behaviors, which get sorted out on the front-end, with some sensible defaults... warnings and complex validation methods can still get swallowed when things are done "live,"
Originally posted by @nrbgt in #69 (comment)
ForceGraph
can produce different effects, the more common issue is Selection
and Shape
, if Shape
is included first in the <ForceGraph>.behaviors
trait, the selection shapes will not be displayed. As we add behaviors, these ordering interactions can become more complex.ForceGraph
, links
, nodes
), it would be good to have that information specified in the Behavior itself. This was refined in #69, but is intended to be refactored in #61.Behaviors
to check order of behaviors and specifies the context they apply to, e.g., None
, links
, nodes
.Utils.ipynb
) to use this information.Currently, NodelLabels
are ephemeral (displayed upon hover). It would be useful to have a feature where all node labels could be displayed permanently at once.
Seeing identifying information about many nodes at once helps interpret the graph.
Image from https://studentwork.prattsi.org/infovis/visualization/visualizing-les-miserables-social-network-1862/:
Add cache=True
to most facets.
While a number of facets require a simulation-driven value (e.g. x
and y
) or a dynamic value (such as created by a Selection
) behavior, a number can be cached based on when the underlying graphData
changes.
This is particularly noticeable on e.g. LinkShape.line_dash
, which can make a graph with a high link count drop to a very low framerate, as noticed on #68, which has a few hundred nodes and a few thousand edges.
cache=False
to all aspectsExpose more DataFrameSource
subclasses that know how to work with different files/local features.
Inspecting the current environment and local files is good for delivering novel data, at scale, in a way that is relevant to the user's current environment and tools. The WidgetSource
added in #35 demonstrates some useful patterns, and could be extended in useful ways, such as toggling features to include in the graph.
PythonSource([imported_module, "module_name"])
importlib.metadata
to discover the relationships between packages and have interesting features like versioned dependencies, named entry_points
and other useful featuresCondaSource(["package-name"])
SphinxInventorySource(["path/to/objects.inv])
LabPluginsSource(["plugin:id"])
DoitSource("path/to/dodo.py", ["task", "path/to/target.file"])
doit
tasks
doit
task loader pattern is... complexThese would all have some common patterns, which would be useful to extract into a common BaseSource
, which would become the superclass of DataFrameSource
(where most would be no-op`) and these new sources:
BaseSource.value: TypedTuple(Any())
value
Path
/string/JSONBaseSource.node_features: Enum
and CustomSource.link_features: Enum
type
field in the node
and link
dataBaseSource.find_graph_data()
async
entry point, if data will be expensive to discover/parseBaseSource.get_default_behaviors(self) -> Tuple[Behavior]
BaseSource.add_default_behaviors = True
Reduce the number of packages and complexity required to run binder demo.
Using binder in the PR review cycle is very handy: having them build and load faster would increase reviewability, and might uncover dependency issues.
The binder environment can't be faster than the total npm build time, but otherwise might be better optimized.
Ability to toggle node/link visibility (style method in force-graph
) would be great.
In conjunction with #36, this would allow filtering on node/edge, thereby reducing visual clutter, without causing significant layout changes.
n/a
Allow changing the background color
This would be useful for customizing the display.
Either:
layout.background_color
can be used
background_color
The default library behaviors includes NodeSelection
with the optional kwarg multiple: bool
that changes the ability to select multiple nodes. The default ForceGraph behavior is that shift+click allows user to select multiple nodes, and if a node is already selected this deselects the node.
When multiple=False
the deselect behavior no longer works.
Behaviors.ipynb
NodeSelection
behaviormultiple=False
)I would expect multiselect to be disabled, but deselect to still work.
3.6.1
0.1.0
(also on binder)doit
)main
dist
archive and unpack somewhere (maybe a fresh dist
)cd dist
twine upload *.tar.gz *.whl
npm login
npm publish jupyrdf-jupyter-forcegraph-$VERSION.tgz
npm logout
conda-forge
feedstock tasks
CACHE_EPOCH
yarn.lock
Add visual representation for the directionality of links.
force-graph
libraries offer static (arrows) and dynamic (particles) representations for this.linkDirectionalArrowRelPos
, linkDirectionalArrowColor
, linkDirectionalArrowLength
from python sidelinkDirectionalParticleSpeed
, linkDirectionalParticleWidth
, linkDirectionalParticleColor
, maybe we need a separate behavior for doing particle emission (i.e., emitParticle
)As a reader of the docs, I want to dig deeper into ipywidgets
upstreams.
In the API documentation, drill down further into ipywidgets.rtfd.io
More/cached external link checking.
Provide a read/write JSON-compatible structure for instantiating and "serializing" the configuration of a forcegraph
Having a single, JSON-schema constrained description of a force graph's configuration would simplify a number of use cases.
Additionally, as JSON, it would be theoretically possible to create a mime renderer of a force graph, with this as the metadata. This might be a lower-touch way for other modules to emit a snaphshot of a graph.
This would allow for something like:
ForceGraph(
source=src,
json={
"alpha_decay": {},
"node_labels": {"template": "{{ node.label }}"},
"node_selection": {"selected": [1,2,3]}
}
)
Under the hood these would map to the existing behaviors.
It should then also be possible to extract this back out.
It would be challenging to extract de-referenced pointers to the behaviors: this could be somewhat fixed by one of:
behaviors
an OrderedDict
or InstanceDict
name
to each of the behaviors, and exposing them as a "squishy" @property
or other getter approach
@T.validate
to ensure each has a unique nameIt would be good to be able to request a snapshot of the graph back from the browser for the kernel to have access to it.
Many use cases would benefit from having access to the image, not least of which would be testing.
Add a ImageSnapshot
behavior which can stuff the canvas as a png
into a buffer. As this would be pretty expensive, this would have a enabled
flag so it could be turned on and off.
ForceGraph
.Clean up documentation after #58, which needs to land to unblock other things.
CHANGELOG.md
README.md
CONTRIBUTING.md
examples/Shapes.ipynb
reference/forces.html
" characters after
node`, etc.examples/Behaviors.ipynb
task_arrows
and task_particles
labels (addressed in #69)docs/reference/base.html
HasDimensions
, etc. so downstream inheritance links are also broken
xref
not inside a link
(link check will find if a link is broken, but not missing)future
notebooks that don't work anymoreForce layout diagrams will be more flexible by exposing some of the underlying forceLayout
simulation parameters. Specifically the d3Forces link
, charge
and center
can enable tuning of the layout based on communities in the graph.
This will let users tune their simulation engine to generate more nuanced layouts.
Examples
doit
)main
dist
archive and unpack somewhere (maybe a fresh dist
)cd dist
twine upload *.tar.gz *.whl
npm login
npm publish jupyrdf-jupyter-forcegraph-$VERSION.tgz
npm logout
conda-forge
feedstock tasks
CACHE_EPOCH
yarn.lock
.github/locks
and doit lock
Create a more full-featured example notebook application.
For a better demonstration of the capability (and value of being connected to the widget bus), create an annotated App.ipynb
(with an importnb
"for show" notebook that imports it)
n
nearest neighbors from graphjupyterlab-deck
experiencedoit
)main
dist
archive and unpack somewhere (maybe a fresh dist
)cd dist
twine upload *.tar.gz *.whl
npm login
npm publish jupyrdf-jupyter-forcegraph-$VERSION.tgz
npm logout
conda-forge
feedstock tasks
CACHE_EPOCH
yarn.lock
Add ability to color nodes
and links
.
graph
.force-graph
has a means to do this without much effort, e.g., this example.Behavior
Behaviors
(that need to be composable in a predictable way), or to have broader Behaviors
, e.g., instead of just color
, one that allows changing opacity
, size
or edge-width
, shape
of nodes, the color
of the labels, other aesthetic properties.nodes
or links
called color
that can be used to color the nodes by, but it would leave most of the work to the back-end.ForceGraph
?), but would need to change the unselected
color in the Selection
behavior.python
side, but the behavior could have a color_by
property that uses the node or link properties to color them by.
force-graph
library already has a nodeAutoColorBy
method that can be used, but unclear how to expose the palettes.Behaviors
(e.g., NodeSelection
) which should either not have an unselected
color option, or prefer the ColorNode
behavior's color and only use the unselected
one if nodes don't have a set color.There are enough capabilities to merit making this conda installable.
Other projects can start testing the library, but it'd make it easier for them to do that if they could conda install ipyforcegraph
.
conda-forge
It would be extremely helpful if ipyforcegraph
supported continuous colormaps (e.g. viridis
) as part of the Nunjucks templating. Users would be able to specify columns that contain continuous values (age, weight, etc.) and a colormap, and ipyforcegraph
would be able to apply the color as part of the e.g. NodeShape behavior without requiring additional dependencies i.e. matplotlib
.
Bringing in additional dependencies to support styling with ipyforcegraph
can complicate build chains, recipes, etc. It would be valuable to reduce complexity of leveraging ipyforcegraph to include common colormaps for continuous values, which are more complicated to implement than discrete maps (which can be easily added with e.g. dictionaries).
Something akin to {{ node.value | colormap('viridis') }}
would be extremely powerful.
Serialization to JSON got nastier: all our half-specified serializers break.
Test_Forces.ipynb
DOMException: Failed to execute 'structuredClone' on 'Window': #<Promise> could not be cloned.
No error message
Fixed here, needs backport and hotfix release.
Nunjucks
templating..md
, so that it is searchable within the docsNunjucks
class itselfOffer the threejs-based 3d-source-graph
.
There are some nice features available here.
Having the Python API be very similar would be useful, as would 3d and 2d views of the same data, with linked selection, etc.
@jupyrdf/jupyter-3dforcegraph
that depends on @jupyrdf/jupyter-forcegraph
Instead of a single column, node labels could be composed on the front end from many columns.
The return value of nodeLabel
can be an HTML string, and might be interesting to have more data. With access to the node and full graph data, one could print out some nice values, including:
template
node
and the graphData
Start a long-lived dev
branch. Target main
only with hotfixes, docs fixes, and releases. Target all other PRs on main
.
This would simplify the binder badge situation, and make it a bit easier to have up-to-date dev docs for unreleased stuff, as well as the stable releases on PyPI.
dev
CONTRIBUTING.md
and release.md
to reflect the changesRight now, even if one makes a new DataFrame
for the nodes
or links
in a DataFrameSource
, the data does not get propagated to the front-end. This may be by design or something that has not yet been implemented.
import json
from pathlib import Path
import ipywidgets as W
from ipyforcegraph.forcegraph import DataFrameSource, ForceGraph
def make_a_simple_example(
source=None, dataset="datasets/miserables.json", GraphClass=ForceGraph, node_color=None,
):
if source is None:
data = json.loads(Path(dataset).read_text())
source = DataFrameSource(**data)
if node_color:
source.nodes["color"] = node_color
fg = GraphClass(source=source, layout=dict(height="500px"))
box = W.HBox([fg, W.VBox([])])
return fg, box
if __name__ == "__main__":
fg, box = make_a_simple_example(node_color="red")
display(box)
Nodes should be red
but they show up the default steelblue
. If a new source
is made, or we run fg.source.send_state()
the nodes show up red
.
id
s?)
node
's id
match?This issue is used to collect screenshots and animated GIFs.
Add line_dash
and curvature
to the links
.
curvature
and line dashes
could be used to convey information about relationships.force-graph
API.python
side.
curvature: TNumFeature = _make_trait("the curvature of the link, 0: straight, 1: circular", numeric=True)
line_dash
presents a more complicated challenge, as the data is really a list of numbers, as per the HTML Canvas setLineDash
method.
line_dash: TListNumFeature = _make_trait(
"the dash pattern, e.g., [5, 15] to draw a repeating pattern of a 5 pixel segment followed by a 15 pixel blank",
numeric=True,
is_list=True,
)
linkCanvasObject
, a "simple" wrapper for only Text
will probably be more than sufficient, therefore, we could add the following attributes to LinkShapes
:
label
the text label to use, could be str
, Column
, or Nunjucks
.label_max_font_size
: equivalent of MAX_FONT_SIZE
in the 2D example.label_margin
: equivalent of LABEL_NODE_MARGIN
in the 2D example.label_font
: the font to use, not including size as that needs to be calculatedlabel_color
: the color of the label (maybe label_fill
would be a better name, specially if we also add label_stroke
)label_background
: the fill to use for the rectangle backgroundLinkShapes
, once we figure out a good pattern for NodeShapes
.links
by clicking on the link or their label.Inevitably it's about what will actually be needed for weird edge cases:
\n
with some indicator (e.g., |
)font-size
Text
shape, where the stroke
(for example) can be changed based on selected column_name
curvature
, line-dash
curvature
line-dash
particles
? and arrows
?
particles
and arrows
?particles
:
arrows
:
ascii
arrow at the end (or beginning) of the label (this may make things complicated because text should probably never be upside down)A source
should be able to control the columns and rows in links
and nodes
that are synced with the front end.
This would allow for using a "big and tall" DataFrame
that included more data than was relevant to a graph without creating intermediate frames.
include_(node|link)_columns
?ignore_(node|link)_columns
?iloc_
?Python 3.7 (apparently) doesn't actually like using tuple[Behavior]
.
Probably also add mypy
to catch these in the future.
doit
)main
dist
archive and unpack somewhere (maybe a fresh dist
)cd dist
twine upload *.tar.gz *.whl
npm login
npm publish jupyrdf-jupyter-forcegraph-$VERSION.tgz
npm logout
conda-forge
feedstock tasks
CACHE_EPOCH
yarn.lock
.github/locks
and doit lock
Graphs that use id's that can be coerced into numbers, get their nodes
and links
sorted when the preserve columns functionality is used, breaking the indexing used by the NodeSelection
and LinkSelection
.
import json
from pathlib import Path
from time import sleep
import ipyforcegraph.graphs as G
import ipyforcegraph.sources as S
import ipyforcegraph.behaviors as B
source_data = json.loads(Path("./datasets/blocks.json").read_text())
source = S.DataFrameSource(
**source_data,
node_preserve_columns=["x", "y"],
)
selection, get_data = behaviors = [
B.NodeSelection(column_name="_selected"),
B.GraphData(),
]
fg = G.ForceGraph(
source=source,
behaviors=behaviors,
layout=dict(height="100%"),
)
# select a node
selection.selected = [850]
# capture data from front-end
get_data.capturing = True
# compare id of selected node as per the backend and the frontend
# note: need to add appropriate async awaits for this to work
id_per_backend_source = source.nodes.id[selection.selected[0]]
frontend_nodes_data = get_data.sources[0].nodes
id_per_frontend_source = frontend_nodes_data.id[frontend_nodes_data._selected == True].iloc[0]
# this assert fails
assert id_per_backend_source == id_per_frontend_source
# as does this one:
assert tuple(source.nodes.id) == tuple(frontend_nodes_data.id)
Would have expected the nodes to be in the same order as that is what the NodeSelection
and LinkSelection
use.
Believe the issue is that Object.values
(used here) sorts the results by the keys if those can be coerced into numbers, and because in this example some of the keys can be while others are alphanumeric, some nodes show up in a different order in the front-end vs the back-end. This can also be verified by looking at the order of the nodes
dataframe retrieved by GraphData
, which may be a better test. Also manually prepended "_"
to all the id
s in the graph and the issue did not pop up.
Config dir: C:\Users\sb282\.jupyterConfig dir: C:\sandboxes\ipyforcegraph\envs\py3.11_lab3.6\etc\jupyter
jupyter_server_fileid enabled
- Validating jupyter_server_fileid...
Package jupyter_server_fileid took 0.0117s to import
jupyter_server_fileid 0.9.0 ok
jupyter_server_terminals enabled
- Validating jupyter_server_terminals...
Package jupyter_server_terminals took 0.0412s to import
jupyter_server_terminals 0.4.4 ok
jupyter_server_ydoc enabled
- Validating jupyter_server_ydoc...
Package jupyter_server_ydoc took 0.3604s to import
jupyter_server_ydoc 0.8.0 ok
jupyterlab enabled
- Validating jupyterlab...
Package jupyterlab took 0.3751s to import
jupyterlab 3.6.3 ok
jupyterlab_link_share enabled
- Validating jupyterlab_link_share...
Package jupyterlab_link_share took 0.3288s to import
jupyterlab_link_share 0.2.5 ok
nbclassic enabled
- Validating nbclassic...
Package nbclassic took 0.0000s to import
A_jupyter_server_extension_points
function was not found in nbclassic. Instead, a_jupyter_server_extension_paths
function was found and will be used for now. This function name will be deprecated in future releases of Jupyter Server.
nbclassic 1.0.0 ok
notebook_shim enabled
- Validating notebook_shim...
Package notebook_shim took 0.0000s to import
A_jupyter_server_extension_points
function was not found in notebook_shim. Instead, a_jupyter_server_extension_paths
function was found and will be used for now. This function name will be deprecated in future releases of Jupyter Server.
notebook_shim okConfig dir: C:\ProgramData\jupyter
bqplot v0.5.40 enabled ok (python, bqplot) ipydatagrid v1.1.15 enabled ok ipylab v0.7.1 enabled ok (python, ipylab) jupyterlab-link-share v0.2.5 enabled ok (python, jupyterlab-link-share) jupyterlab_pygments v0.2.2 enabled ok (python, jupyterlab_pygments) @deathbeds/jupyterlab-deck v0.1.3 enabled ok @deathbeds/jupyterlab-font-anonymous-pro v2.1.1 enabled ok (python, jupyterlab-fonts) @deathbeds/jupyterlab-font-dejavu-sans-mono v2.1.1 enabled ok (python, jupyterlab-fonts) @deathbeds/jupyterlab-font-fira-code v2.1.1 enabled ok (python, jupyterlab-fonts) @deathbeds/jupyterlab-fonts v2.1.1 enabled ok (python, jupyterlab-fonts) @jupyrdf/jupyter-forcegraph v0.3.2 enabled ok @jupyter-widgets/jupyterlab-manager v5.0.7 enabled ok (python, jupyterlab_widgets) @jupyterlite/pyodide-kernel-extension v0.0.8 enabled ok (python, jupyterlite_pyodide_kernel)
$PATH: C:\sandboxes\ipyforcegraph\envs\py3.11_lab3.6 C:\sandboxes\ipyforcegraph\envs\py3.11_lab3.6\Library\mingw-w64\bin C:\sandboxes\ipyforcegraph\envs\py3.11_lab3.6\Library\usr\bin C:\sandboxes\ipyforcegraph\envs\py3.11_lab3.6\Library\bin C:\sandboxes\ipyforcegraph\envs\py3.11_lab3.6\Scripts C:\sandboxes\ipyforcegraph\envs\py3.11_lab3.6\bin C:\mf\envs\doit\condabin C:\Program Files (x86)\Integrity\ILMClient11.2\bin C:\WINDOWS\system32 C:\WINDOWS C:\WINDOWS\System32\Wbem C:\WINDOWS\System32\WindowsPowerShell\v1.0 C:\WINDOWS\System32\OpenSSH C:\PROGRA~2\INTEGR~1\Toolkit\mksnt C:\Program Files (x86)\Webex\Plugins C:\HashiCorp\Vagrant\bin C:\Program Files\Docker\Docker\resources\bin C:\ProgramData\DockerDesktop\version-bin C:\Program Files\RedHat\java-14-openjdk-14.0.1-1\bin C:\Program Files\MATLAB\R2021b\bin . C:\Program Files\RedHat\Podman C:\Users\sb282\AppData\Local\Microsoft\WindowsApps C:\Users\sb282\AppData\Local\Programs\Microsoft VS Code\bin C:\Program Files\Java\jdk-13\bin C:\Gradle\gradle-6.5.1\bin C:\Users\sb282\AppData\Local\Programs\Git\cmdsys.path:
C:\sandboxes\ipyforcegraph\envs\py3.11_lab3.6\Scripts
C:\sandboxes\ipyforcegraph\envs\py3.11_lab3.6\python311.zip
C:\sandboxes\ipyforcegraph\envs\py3.11_lab3.6\DLLs
C:\sandboxes\ipyforcegraph\envs\py3.11_lab3.6\Lib
C:\sandboxes\ipyforcegraph\envs\py3.11_lab3.6
C:\sandboxes\ipyforcegraph\envs\py3.11_lab3.6\Lib\site-packages
C:\sandboxes\ipyforcegraph\src
C:\sandboxes\ipyforcegraph\envs\py3.11_lab3.6\Lib\site-packages\win32
C:\sandboxes\ipyforcegraph\envs\py3.11_lab3.6\Lib\site-packages\win32\lib
C:\sandboxes\ipyforcegraph\envs\py3.11_lab3.6\Lib\site-packages\Pythonwinsys.executable:
C:\sandboxes\ipyforcegraph\envs\py3.11_lab3.6\python.exesys.version:
3.11.3 | packaged by conda-forge | (main, Apr 6 2023, 08:50:54) [MSC v.1934 64 bit (AMD64)]platform.platform():
Windows-10-10.0.19045-SP0where jupyter:
C:\sandboxes\ipyforcegraph\envs\py3.11_lab3.6\Scripts\jupyter.exepip list:
Package Version Editable project location
------------------------------ ----------- --------------------------
accessible-pygments 0.0.4
aiofiles 22.1.0
aiosqlite 0.19.0
alabaster 0.7.13
ansi2html 0.0.0
anyio 3.6.1
argon2-cffi 21.3.0
argon2-cffi-bindings 21.2.0
asttokens 2.2.1
async-generator 1.10
attrs 23.1.0
autodoc-traits 1.1.0
autopep8 2.0.2
Babel 2.12.1
backcall 0.2.0
backports.functools-lru-cache 1.6.4
beautifulsoup4 4.12.2
black 23.3.0
bleach 6.0.0
bqplot 0.12.39
brotlipy 0.7.0
cattrs 22.2.0
certifi 2023.5.7
cffi 1.15.1
charset-normalizer 3.1.0
click 8.1.3
cloudpickle 2.2.1
cmarkgfm 0.8.0
colorama 0.4.6
comm 0.1.3
coverage 7.2.5
cryptography 40.0.2
debugpy 1.6.7
decorator 5.1.1
defusedxml 0.7.1
docutils 0.19
doit 0.36.0
entrypoints 0.4
exceptiongroup 1.1.1
execnet 1.9.0
executing 1.2.0
fastjsonschema 2.16.3
flit 3.8.0
flit_core 3.8.0
gast 0.4.0
greenlet 2.0.2
h11 0.14.0
html5lib 1.1
idna 3.4
imagesize 1.4.1
importlib-metadata 6.6.0
importlib-resources 5.12.0
importnb 2023.1.7
iniconfig 2.0.0
ipydatagrid 1.1.15
ipyforcegraph 0.3.2 C:\sandboxes\ipyforcegraph
ipykernel 6.23.0
ipylab 0.7.1
ipython 8.13.2
ipython-genutils 0.2.0
ipywidgets 8.0.6
itsdangerous 2.1.2
jaraco.classes 3.2.3
jedi 0.18.2
Jinja2 3.1.2
json5 0.9.5
jsonschema 4.17.3
jupyter-cache 0.6.1
jupyter_client 8.2.0
jupyter_core 5.3.0
jupyter-events 0.6.3
jupyter_server 2.5.0
jupyter_server_fileid 0.9.0
jupyter_server_terminals 0.4.4
jupyter_server_ydoc 0.8.0
jupyter-ydoc 0.2.3
jupyterlab 3.6.3
jupyterlab-deck 0.1.3
jupyterlab-fonts 2.1.1
jupyterlab-link-share 0.3.0
jupyterlab-pygments 0.2.2
jupyterlab_server 2.22.1
jupyterlab-widgets 3.0.7
jupyterlite-core 0.1.0
jupyterlite-pyodide-kernel 0.0.8
keyring 23.13.1
libarchive-c 4.0
livereload 2.6.3
lxml 4.9.2
markdown-it-py 2.2.0
MarkupSafe 2.1.2
matplotlib-inline 0.1.6
mdit-py-plugins 0.3.5
mdurl 0.1.0
mistune 2.0.5
more-itertools 9.1.0
msgpack 1.0.5
mypy 1.2.0
mypy-extensions 1.0.0
myst-nb 0.17.2
myst-parser 0.18.1
natsort 8.3.1
nbclassic 1.0.0
nbclient 0.7.4
nbconvert 7.4.0
nbformat 5.8.0
nbqa 1.7.0
nbstripout 0.6.1
nest-asyncio 1.5.6
networkx 3.1
notebook 6.5.4
notebook_shim 0.2.3
numcodecs 0.11.0
numpy 1.24.3
orjson 3.8.12
outcome 1.2.0
packaging 23.1
pandas 2.0.1
pandocfilters 1.5.0
parso 0.8.3
pathspec 0.11.1
pickleshare 0.7.5
pip 23.1.2
pkginfo 1.9.6
pkgutil_resolve_name 1.3.10
platformdirs 3.5.0
pluggy 1.0.0
prometheus-client 0.16.0
prompt-toolkit 3.0.38
psutil 5.9.5
pure-eval 0.2.2
py 1.11.0
py2vega 0.6.1
pycodestyle 2.10.0
pycparser 2.21
pydata-sphinx-theme 0.13.3
Pygments 2.15.1
pyOpenSSL 23.1.1
pyproject-fmt 0.11.2
pyrsistent 0.19.3
PySocks 1.7.1
pytest 7.3.1
pytest-asyncio 0.21.0
pytest_check_links 0.8.0
pytest-cov 4.0.0
pytest-html 3.2.0
pytest-json-report 1.5.0
pytest-metadata 2.0.4
pytest-xdist 3.2.1
python-dateutil 2.8.2
python-json-logger 2.0.7
pytz 2023.3
pywin32 304
pywin32-ctypes 0.2.0
pywinpty 2.0.10
PyYAML 6.0
pyzmq 25.0.2
readme-renderer 37.3
requests 2.29.0
requests-cache 1.0.1
requests-toolbelt 1.0.0
rfc3339-validator 0.1.4
rfc3986 2.0.0
rfc3986-validator 0.1.1
rich 13.3.5
rich-click 1.6.1
robotframework 6.0.2
robotframework-jupyterlibrary 0.4.2
robotframework-pabot 2.15.0
robotframework-pythonlibcore 4.1.2
robotframework-robocop 3.1.1
robotframework-seleniumlibrary 6.1.0
robotframework-stacktrace 0.4.1
robotframework-tidy 4.2.1
ruff 0.0.265
scour 0.38.2
selenium 4.9.1
Send2Trash 1.8.2
setuptools 67.7.2
six 1.16.0
sniffio 1.3.0
snowballstemmer 2.2.0
sortedcontainers 2.4.0
soupsieve 2.3.2.post1
Sphinx 5.3.0
sphinx-autobuild 2021.3.14
sphinx_autodoc_typehints 1.21.8
sphinx-copybutton 0.5.2
sphinxcontrib-applehelp 1.0.4
sphinxcontrib-devhelp 1.0.2
sphinxcontrib-htmlhelp 2.0.1
sphinxcontrib-jsmath 1.0.1
sphinxcontrib-qthelp 1.0.3
sphinxcontrib-serializinghtml 1.1.5
SQLAlchemy 2.0.12
ssort 0.11.6
stack-data 0.6.2
stringcase 1.2.0
tabulate 0.9.0
terminado 0.17.0
tinycss2 1.2.1
tokenize-rt 5.0.0
toml 0.10.2
tomli 2.0.1
tomli_w 1.0.0
tomlkit 0.11.8
tornado 6.3
traitlets 5.9.0
traittypes 0.2.1
trio 0.22.0
trio-websocket 0.10.2
twine 4.0.2
typing_extensions 4.5.0
tzdata 2023.3
ujson 5.7.0
url-normalize 1.4.3
urllib3 1.26.15
wcwidth 0.2.6
webencodings 0.5.1
websocket-client 1.5.1
wheel 0.40.0
widgetsnbextension 4.0.7
win-inet-pton 1.1.0
wsproto 1.2.0
y-py 0.5.9
ypy-websocket 0.8.2
zipp 3.15.0
The 2d plot should center and fit the view by default.
Just like behaviors.NodeSelection
, but for links.
Display information for links onClick, etc.
n/a
Refactor Behaviors
to use the new Column
and Nunjuck
widgets, as developed in #54.
Behavior.(column_name|template)
, favoring dedicated widget subclasses Column
and Nunjuck
.
Nunjuck
templates, this will help make falsey
python types evaluate to false
in js
NodeStyle
combines NodeColors
and NodeSizes
LinkStyle
combines LinkColors
and LinkWidths
LinkArrow
combines LinkDirectionalArrowColor
, LinkDirectionalArrowLength
, and LinkDirectionalArrowRelPos
LinkParticles
combines LinkDirectionalParticleColor
, LinkDirectionalParticleSpeed
, LinkDirectionalParticleWidth
, amd LinkDirectionalParticles
Forces
? It does not seem to be immediately relevant, but maybe there is a common way to think about them?python
API and put the style
related behaviors in their own submodule, e.g., ipyforcegraph/behaviors/style/
where we would have node.py
, link.py
, and shape.py
?dev
doit preflight:release
CHANGELOG.md
is up-to-datedev
to main
main
dist
archive and unpack somewherecd dist
twine upload *.tar.gz *.whl
npm login
npm publish jupyrdf-jupyter-forcegraph-$VERSION.tgz
npm logout
conda-forge
feedstock tasks
requirements.txt
environment.yml
main
targeting dev
CACHE_EPOCH
yarn.lock
.github/locks
doit env:lock
rm -rf .github/locks
source envs/lock/bin/activate
call envs/lock/Scripts/activate.bat
)doit lock
.github/ISSUE_TEMPLATE/release.md
Update the test infrastructure to include JupyterLab 3.5.* and 3.6.1
JupyterLab 3.6.1 is a semi-breaking release.
JupyterLite will not be adopting it.
We should make sure everything works in both lines.
Add an additional factor to the lock files, testing lab 3.5.2+ on the oldest python and 3.6.1+ on the newest.
Better/smoother story telling through controlled panning and zooming on nodes / neighborhoods.
Two things:
Under https://github.com/vasturiano/force-graph#render-control there is a section that highlights several different camera control functions:
https://github.com/vasturiano/force-graph#utility
Other rendering functions that could be wrapped. Potentially for a follow on ticket.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.