👽 How do you do a dynamic "list of lists" or otherwise solve the following problem

(Fruitfulapproach) #1

Here is my beautiful code:

    def addArrow(self, arrow):
        cql = """
        MATCH (s),(t)
        WHERE id(s)=$srcid AND id(t)=$tarid 
        CREATE (s)-[r:Morphism {labels:$labels, labelposx:$labelposx, labelposy:$labelposy, 
        tailstyle:$tailstyle, headcount:$headcount, pendash:$pendash, penwidth:$penwidth, pencol:$pencol, 
        pos0:$pos0, pos1:$pos1, pos2:$pos2, pos3:$pos3, pos:$pos}]->(t) 
        RETURN id(r)
        """
        points = arrow.controlPoints()
        try:
            with self._driver.session() as session:
                id = session.run(cql, parameters={
                                     'labels': [label.text() for label in arrow.labels()],
                                     'labelposx': [label.pos().x() for label in arrow.labels()],
                                     'labelposy': [label.pos().y() for label in arrow.labels()],
                                     'srcid': arrow.sourceNode().databaseID(),
                                     'tarid': arrow.targetNode().databaseID(),
                                     'tailstyle': arrow.tailStyle(),
                                     'headcount': arrow.numberOfHeads(),
                                     'pendash': arrow.pen().style(),
                                     'penwidth': arrow.pen().widthF(),
                                     'pencol': colorToList(arrow.pen().color()),
                                     'pos0': pointToList(points[0].pos()),
                                     'pos1': pointToList(points[1].pos()),
                                     'pos2': pointToList(points[2].pos()),
                                     'pos3': pointToList(points[3].pos()),
                                     'pos': pointToList(arrow.pos()),
                                     }).single().value()
            arrow.setDatabaseID(id)
        except Exception as e:
            Error(str(e)).exec_()
            if __debug__:
                raise e
                                 'labels': [label.text() for label in arrow.labels()],
                                 'labelposx': [label.pos().x() for label in arrow.labels()],
                                 'labelposy': [label.pos().y() for label in arrow.labels()],

The problem is: each arrow has a list of labels, but each label has a position which is a list of floats. So as you can see I've broken it up into labelposx / labelposy so that these label lists can be dynamically updated. Is there a better way to do this such that the positions are contained with a "Label" structure? The problem now becomes worse if I want an independent color per label. Then I need labelcolorred... labelcoloralpha, which is four more lists.

Just wondering, I'm happy with the above if that's what we're limited to.

Thank you!

:banana::joy_cat:

0 Likes

(Michael Hunger) #2

I don't fully understand your question, it's probably also not a "newbie" one :slight_smile:

Also you're putting an awful lot on a relationship, are you sure that Morphism is not an important entity of your domain that is actually a node?

0 Likes

(Fruitfulapproach) #3

Nope, I'm wanting the Neo4j browser to reflect these "commutative diagrams in math" 1-1, so that:

  1. Easy to debug
  2. People can see that its working
  3. It would be weirder to diverge from this since a diagram is already a graph.
0 Likes

(Fruitfulapproach) #4

That's not stuff I'm doing search by although a user might want to say "All diagrams with a red node" and if I offer custom cypher queries they can do that.

The default search is going to be an exact one based on label subset or just purely structural (treated as unlabeld graphs).

0 Likes

(Fruitfulapproach) #5

Can we do something like this is what I mean:

"labels": [
{ "pos:" : [0.5, 1.0],
"color": [255, 0, 0, 255],
},
{ ... }
]

0 Likes

(Michael Hunger) #6

you can create that in cypher, sure

with literal maps {a:10} and lists [1,2,3]
and you can nest them either with collect: {a: collect({b:n.prop})}

or you can use map projections with pattern coprehensions

node { .prop, .*, foo:42, bar:[(node)-->(other) | other.prop]}

0 Likes