theia-ide / sprotty

A next-gen web-based graphics framework
Apache License 2.0
138 stars 23 forks source link

moving nodes that have a negative scale transform applied works unintuitively #228

Closed dvc94ch closed 6 years ago

dvc94ch commented 6 years ago

When there is a negative scale transform applied, dragging a node moves the node opposite to drag direction.

I'm currently using mirroring to get labels to look good with multiple orientations. A 180deg rotation is implemented by mirroring the node, mirroring all text elements and changing text-anchor=start to text-anchor=end. Maybe there is a better way of doing it, but it works well enough for now.

JanKoehnlein commented 6 years ago

Why not use an extra group with the negative scale? The move transform is applied to the root group of a view.

dvc94ch commented 6 years ago

The symbol itself doesn't know anything about it's orientation, but it's what's being dragged.

export class CellNodeView extends OrientationAware implements IView {
    render(cell: Readonly<CellNode>, context: RenderingContext): VNode {
        return this.renderContainer(cell.orient, context.renderChildren(cell))
    }
}
JanKoehnlein commented 6 years ago

I mean

export class CellNodeView extends OrientationAware implements IView {
    render(cell: Readonly<CellNode>, context: RenderingContext): VNode {
        return <g> this.renderContainer(cell.orient, context.renderChildren(cell)) </g>
    }
}
dvc94ch commented 6 years ago

I don't think there is a trivial solution. If I apply the transform to the child that is being moved instead of to the container I get issues with nested orientations and the order of css rules applied.

if I change

.orient180 {
    /* mirror */
    transform: scaleX(-1);
}

to

.orient180 .group {
    /* mirror */
    transform: scaleX(-1);
}

and containers are nested, the nested container only gets the right transform if the angle is larger than it's parents, because the rules are written in that order in the stylesheet.

Anyway I guess this issue can be closed.

Another question though: Have you done any performance tests on culling methods? Some options that I can think of are:

  1. give a hidden property in the model and don't render the hidden parts in the view
  2. give a hidden property in the model and set the opacity to 0 in the view
  3. have multiple SGraph's and replace the entire graph
JanKoehnlein commented 6 years ago

I lack a lot of the context in order to be able to properly reply to the first part, sorry (neither orient180 nor group appear as classes in your example). It's just that the move transform for dragging nodes is applied to the root node in the SVG subtree for a view. So if you have further transforms on child nodes down the hierarchy, they shouldn't be affected once you have an additional parent node. You can apply whatever CSS class to any subnode.

For the second question, it sounds like you might want to look into thunk-views (1). Apart from that, what kind of culling do you mean? Can you elaborate?

dvc94ch commented 6 years ago

Yes, I don't think it's an issue with sprotty, it's obviously an issue with how I'm using sprotty.

thunk-views looks like it will help, thanks.

Apart from that, what kind of culling do you mean? Can you elaborate?

for every module or part of the graph I either show an abstract symbol representing it's interface or a schematic showing it's innards. while currently there is only one schematic visible at any time, the correct term for what I'm doing is maybe level of detail.

JanKoehnlein commented 6 years ago

Look at ChannelView in the multicore example