I can add my shapes to the stage and get them to do fades and such, but I can't get them to morph - do I need to separate out into lines and curves somehow?
var shape = new Path('M 321.051,510.078 c 0,0-10.126-23.854-19.438-45.792 c -7.927-18.675-15.265-35.961-15.265-35.961 s -17.977-41.111-19.036-77.643 c -1.05-36.243,14.817-67.908,14.817-67.908 s -36.176,73.71-49.086,137.219 c -9.327,45.879,3.426,87.39,3.426,87.39 L 321.051,510.078 z').attr({fillColor: 'red'});
stage.addChild(shape);
var targetPath = new Path('M 321.75,515.816 c 0,0,8.678-42.28,0.604-77.096 c -8.102-34.936-32.956-62.408-32.956-62.408 l -76.102-96.41c0,0-39.866-41.142-45.55-84.785 c -4.992-38.332,24.108-79.856,24.108-79.856 s -55.379,72.451-63.818,141.683 c -6.186,50.745,33.857,104.106,33.857,104.106 s 36.746,38.732,51.061,75.346 c 13.283,33.975,4.212,66.029,4.212,66.029L326.75,515.816 z').attr({fillColor: 'blue'});
shape.addTo(stage);
shape.morphTo(targetPath, '3s');
Bonsai 0.4.1 doesn't support smooth curves (s, S) SVG commands. See related ticket: https://github.com/uxebu/bonsai/issues/191
I guess you get it to work by removing those commands.
Related
Is there anyway to create defined fixed edges directional graphs using dot notation? the following dot notation (fig 2) generates an automated edges that are curved. It doesnt have notations which will generate directions with straight edges (fig 1). Been on hours trying to find anything close, any hints will be great. thank you.
# fig 1
box A --- box B
|. \
|. \
box C. \
box D
# fig 2
digraph G {
node [shape=record];
rankdir="BT"
a -> b [color = red][arrowhead = diamond][taillabel = "tail"]
b -> c [shape = box]
c -> a
}
Not sure what a fixed edge is, but if you don't want splines for edges, look at the splines attribute (https://graphviz.org/docs/attrs/splines/).
Here is you graph with splines=false. You can also try splines=polyline.
You might also connect the edges to specific ports on one or both of the nodes (https://graphviz.org/docs/attr-types/portPos/).
# fig 2
digraph G {
node [shape=record];
// see https://graphviz.org/docs/attrs/splines/
// also look at ports https://graphviz.org/docs/attr-types/portPos/
splines=false // or try splines=polyline
rankdir="BT"
a -> b [color = red][arrowhead = diamond][taillabel = "tail"]
b -> c [shape = box]
c -> a
}
Giving:
Let's say I have the following data:
String[][] edges = { "A", "B"}, {"B", "C"}, {"C", "A"} };
Is there a library that would allow me to generate the equivalent in say mermaid:
stateDiagram
A --> B
B --> C
C --> A
or in Plantuml:
#startuml
A --> B
B --> C
C --> A
#enduml
or in dot:
digraph G {
A -> B
B -> C
C -> A
}
Obviously generating the above isn't too difficult as it has no customisation, but I'd like to know if there are libraries allowing for easier generation of above.
The motivation is to have a state machine describing a process and to generate the edges list mentioned above generated through code and the generated graph acting as live documentation.
I'm trying to replicate the following example from the mxnet main docs with mxnet.jl in Julia:
A = Variable('A')
B = Variable('B')
C = B * A
D = C + Constant(1)
# get gradient node.
gA, gB = D.grad(wrt=[A, B])
# compiles the gradient function.
f = compile([gA, gB])
grad_a, grad_b = f(A=np.ones(10), B=np.ones(10)*2)
The example shows how to autodiff a symoblic expression and obtain its gradients.
What is the equivalent in mxnet.jl (latest version 2016-03-07)?
Code in MXNet.jl/src/symbolic-node.jl may be helpful for you to find answers.
I am not familiar with this package.
Here is my Guess:
A = mx.Variable("A")
B = mx.Variable("B")
C = B .* A
D = C + 1
mx.normalized_gradient may be the solution to the remaining part if exists.
I have been given a problem to solve that I am fairly certain its insoluble.
For a system I am working in I need to take piece of branching logic (graph) and translate it to a linear path(flatten it), without node repeats. Given a tree I know that I can do this.
The rules are that the path must be traversed in order, but can 'skip' any panel if some condition is met.
Given the tree:
A > B > C
&&
A > D > E
Our tree can be flattened to:
A > B > C > D > E
So in this case B and C share the same conditional, and D, and E have the inverse of that condition. Thus if B is met so is C, but D and E will be skipped. Conversely, if B is not met, B and C are skipped, but D and E aren't.
So far, so simple. I am fairly convinced this is true for any tree. The problem I have is that the objects I have been given to flatten are graphs, and contain simple cycles, and closed walks.
After that huge preamble my questions are:
Am I right in stating that it is impossible to guarantee that such a graph can be flattened?
I know that closed walks cannot follow my rules (by virtue of returning to a node), but are there any other rules that describe a 'flatten-able' graph versus a 'non-flatten-able' one?
Cheers
If it is a directed graph, then the graph can be flattened if there are no directed cycles.
There is a handy library available JGraphT which will provide the necessary methods to determine if there is a cycle presnet as well a TopologicalOrderIterator which will perform the flattening as well.
Using the graph library and the example above this code will show an exmaple of how to do it.
DirectedGraph<String, DefaultEdge> graph = new DefaultDirectedGraph<String, DefaultEdge>(DefaultEdge.class);
graph.addVertex("A");
graph.addVertex("B");
graph.addVertex("C");
graph.addVertex("D");
graph.addVertex("E");
// A > B
graph.addEdge("A", "B");
// B > C
graph.addEdge("B", "C");
// A > D
graph.addEdge("A", "D");
// D > E
graph.addEdge("D", "E");
// Uncomment the following line to create a cyclic graph.
//graph.addEdge("E", "D");
CycleDetector<String, DefaultEdge> cycleDector = new CycleDetector<String, DefaultEdge>(graph);
if (cycleDector.detectCycles()) {
System.err.println("Cyclic graph");
} else {
StringBuilder sb = new StringBuilder();
// Create topological order iterator
for (TopologicalOrderIterator<String, DefaultEdge> iter = new TopologicalOrderIterator<String, DefaultEdge>(
graph); iter.hasNext();) {
String vertex = iter.next();
if (sb.length() > 0) {
sb.append(" > ");
}
sb.append(vertex);
}
System.out.println(sb.toString());
}
Sample output with the cycle disabled.
A > B > D > C > E
I am using Map to implement pure functional DFS and BFS for graph.
here is my code:
module IntMap = Map.Make(struct type t = int let compare = compare end);;
module IntSet = Set.Make(struct type t = int let compare = compare end);;
type digraph = int list IntMap.t;;
exception CantAddEdge;;
let create v =
let rec fill i acc =
if i < v then
fill (i+1) (IntMap.add i [] acc)
else
acc
in
fill 0 IntMap.empty;;
let num_vertices g = IntMap.cardinal g;;
let add_edge u v g =
if IntMap.mem u g && IntMap.mem v g then
let add u v g =
let l = IntMap.find u g in
if List.mem v l then g
else IntMap.add u (v::l) g
in
add u v (add v u g)
else
raise CantAddEdge;;
let dfs_path u g =
let rec dfs current visited path =
let dfs_child current (visited, path) c =
if not (IntSet.mem c visited) then
dfs c (IntSet.add c visited) (IntMap.add c current path)
else
(visited, path)
in
List.fold_left (dfs_child current) (visited, path) (IntMap.find current g)
in
let (v, p) = dfs u (IntSet.singleton u) IntMap.empty
in
p;;
let bfs_path u g =
let rec bfs current_list v p n =
let bfs_current (v,p,n) current =
let bfs_child current (v, p, n) c =
if not (IntSet.mem c v) then begin
print_int c;
((IntSet.add c v), (IntMap.add c current p), (c::n))
end
else
(v, p, n)
in
List.fold_left (bfs_child current) (v, p, n) (IntMap.find current g)
in
let (v,p,n) = List.fold_left bfs_current (v,p,n) current_list
in
if n = [] then p
else bfs n v p []
in
bfs [u] (IntSet.singleton u) IntMap.empty [];;
I know the code is quite long, but I really do wish for some suggestions:
Is it worthy to really implement a pure functional set of graph algorithm? I do this because I am getting used to functional and hate imperative now.
Is my implementation too complicated in some parts or all?
Although I like functional, personally I think the implementation I make seems more complicated than the imperative array-everywhere version. Is my feeling correct?
Edit
Added Bipartite code
(* basically, we have two sets, one for red node and the other for black node*)
(* we keep marking color to nodes via DFS and different level of nodes go to coresponding color set*)
(* unless a node is meant to be one color but already in the set of the other color*)
type colorType = Red | Black;;
let dfs_bipartite u g =
let rec dfs current color red black block =
if block then (red, black, block)
else
let dfs_child current color (red, black, block) c =
if block then (red, black, block)
else
let c_red = IntSet.mem c red and c_black = IntSet.mem c black in
if (not c_red) && (not c_black) then
if color = Red then
dfs c Black (IntSet.add c red) black false
else
dfs c Red red (IntSet.add c black) false
else if (c_red && color = Black) || (c_black && color = Red) then (red, black, true)
else (red, black, block)
in
List.fold_left (dfs_child current color) (red, black, block) (IntMap.find current g)
in
let (r, b, block) = dfs u Black (IntSet.singleton u) IntSet.empty false
in
not block;;
Edit 2
DFS with list based path
let dfs_path u g =
let rec dfs current visited path =
let dfs_child (visited, path) c =
if not (IntSet.mem c visited) then begin
print_int c;
dfs c (IntSet.add c visited) (c::path)
end
else (visited, path)
in
List.fold_left dfs_child (visited, path) (IntMap.find current g)
in
let (v, p) = dfs u (IntSet.singleton u) [u]
in
p;;
I'm not sure what you mean by worthy. It's worthy to set yourself this task as a learning exercise. It's also worthy to use immutable data to solve actual real world graph problems. It doesn't seem to me that graph processing is an area of application where pure functional code costs more than one is generally willing to pay for the benefits.
You're representing a path as a map from each node to the next. This is nice because you can start up the path in the middle. But a list is a simpler and more natural representation of a path for a lot of applications. At any rate, yours is a pretty heavyweight representation and so it makes your code a little heavier than I would have expected. (BTW it was hard to figure this out--some comments would help.)
I don't personally think this code is more complicated than imperative could would be. I also think that arrays make a poor representation for graphs when viewed as linked structures. So I don't believe an "arrays everywhere" solution is what you want to compare against. I'd compare against a malloc()/struct based (a la C) or against an object-based solution, personally.
When representing graphs as adjacency matrices, I'd say the array representation is more competitive. If your graph changes size a lot, or if you want to access nodes by keys other than integers, maps still have many advantages.
It is worthy to do that if you cannot find good codes in open source community. Do not reinvent wheels.
There is another post has an extensive explanation on DFS algorithm by OCaml, Topological sort in OCaml
What I suggest is to try write bfs, bfs_current and bfs_child into a single function.