Open hallvard opened 4 years ago
Very interesting idea... Although you are enlarging our TODO list :-)
First, I think we really need a dedicated syntax here. What about using a new keyword TABLE
and using =>
separator.
This way, you could have:
table CapitalCity {
UK => London
USA => Washington
Germany => Berlin
Italy => Rome
}
table "map: Map<Integer, String>" as users {
1 => Alice
2 => Bob
3 => Charlie
}
Note that the rendering of the Table would be verticaly (rather than horizontaly in your example). Something like (but with a better result)
Then, we could use connector in the following way : CapitalCity::UK --> foo
To get something like: http://www.plantuml.com/plantuml/uml/SoWkIImgAStDuKhEIImkLYWjJYrIgERAJE7AIynDvQhbWeed9YVdb-QL0ANoIdD1mY25LbQPAGgwkdOmMIiha2INGsfU2j140000
Does it make sense to you ?
I think it is a good idea to have a dedicated syntax and the suggested one seems OK. But note that the content of a cell can be a reference, rendered as some kind of line originating from the cell itself (or a dot inside the cell). In that case there will not be any text on the cell. Since the cell cannot be a target of a link, you could include the reference into the syntax:
table "name2person: Map<String, Person>" as name2person { "hal" => --> hallvard "plantuml" => --> arnaud } object "hallvard: Person" as hallvard object "arnaud: Person" as arnaud
This would render as two objects, and a table with two columns where the second column is cells from which there are lines to the two objects, respectively. Note that both sides of the mapping can be a reference, like a Map<Object, Object>.
Ok, I better understand your point now. I need some time to think about it, it's an interesting challenge... I'll post a message here when some beta will be ready :-)
If you can implement cell-with-reference rendering, you could consider supporting it in attributes, since it will look a bit like how Java objects are illustrated in text books. Of course, this removes the abstraction that UML provides (of OO languages), but is helpful for students. E.g.
object "hallvard: Person" as hallvard { spouse = --> marit }
object "marit: Person" as marit { spouse = --> hallvard }
This could render as a "spouse" label with a link to the other object starting at a dot just to the right of the label. This shouldn't affect the layout that much, e.g. you could assume for layout purposes that the link is attached to the edge. And even support hints like -right->
We've started something with last beta http://beta.plantuml.net/plantuml.jar
It's still under work, but we can talk about it.
With this beta, you can now have :
@startuml
map CapitalCity {
UK => London
USA => Washington
Germany => Berlin
}
@enduml
We choose map
as keyword because it's more appropriate than table
that we might use in the future.
You can also have:
@startuml
object London
map CapitalCity {
UK *-> London
USA => Washington
Germany => Berlin
}
@enduml
It's not completely finished yet : we have to draw a link between the big dot and London
object.
This is really the tricky part : I'm not 100% sure that we are going to success.
What do you think about the syntax ? Any idea/feedback is welcome :-)
I haven't had a chance to look at the beta, but I would like to comment on the syntax. It does look nice, I like the "shortcut" with a general relation replaces the double array. Compared to may proposal, it omits the => arrow, i.e. "Hallvard" => -> hallvard
becomes "Hallvard" -> hallvard
if I understand your proposal correctly.
But you need also to support the general case where one object maps to another. If you first check if either side is a reference, this would work:
object hallvard
object marit
map Wife {
hallvard => marit
}
This would render as two cells with a dot and ordinary arrows. But you won't be able to customise the link to both at the same time, with this syntax. e.g. if both links are supposed to be stippled. In my proposal, each side could be a link on its own:
map Wife {
..> hallvard => ..> marit
}
or even
map Wife {
hallvard <.. => ..> marit
}
I'd say allow this syntax, combined with the shortcut where you can omit the => when there's already a link in between them.
We have published a new official release with some new features. This is still experimental.
We are getting close to GraphViz limit here : I think there is no way to impose to GraphViz to use both left and right side of a map.
Example of what you can have:
The real issue is that on complex example, you can end up with very strange result:
Note that the syntax is not final yet. Once again, it's not the syntax which is an issue here.
I let you play with last version : tell us if you succeed in having something ok.
This isn't quite what I thought of... The map needs to show both the key and value and must handle several cases, that are visualised below:
I don't think it makes sense to point to to the entry/row, since you don't navigate that way. The link(s) must come from the key and/or value slot.
I am struggling to do the following:
Basically, I would like the following code to work:
object Foo
map Bar {
abc
def
}
object Baz
Bar::abc --> Baz : Label one
Foo --> Bar::def : Label two
Is this able to handle map keys with spaces in them, or icons next to them? For example:
@startuml
!define PK <size:12><&key></size><b>
!define FK <size:12><&link-intact></size><i>
map A {
PK id => [string]
FK parent_id => [string]
foo => [string]
bar => [int]
}
'A::"FK parent_id" -> A::"PK id"
A::parent_id -> A::id
@enduml
Is there a way to get the arrow to point from parent_id to id instead of from A to A?
Hello @schindld,
For:
Is there a way to get the arrow to point from
parent_id
toid
instead of fromA
toA
?
See also a pseudo-similar request here:
Regards.
Thanks @The-Lum , that's definitely part of it.
For key/field names with spaces (maybe using the "as id" syntax?) part, should I open another issue?
Most OO languages support table-like data structures, that although they're encapsulated in objects, are better rendered as tables. E.g. a Collection is a single-row table, a List is a two row table with indices 0..size-1 in the header row and values in the other, a Map is a two row table with the keys in the first row and values in the second.
To get an effect similar to this, we currently can do something like this:
@startuml object "map: Map<Integer, String>" as map { |= 1 |= 2 |= 3 | | Hi | There | ! | } @enduml
Although the table isn't rendered correctly here, you get the idea. However, table cells cannot contain be the source of references (links), so in practice this limits us to simple values. So if syntax was added for naming a table cell and that name could be use in relation syntax and it would be rendered as a dot from which the link is drawn, then we're pretty close.
E.g. @startuml object "map: Map<Integer, Object>" as map { |= 1 |= 2 | | as cell1 | as cell2 | } object target1 object target2 cell1 --> target1 cell2 --> target2 @enduml