Mar 3, 2012

Graphiti PlatformGraphicsAlgorithms

Graphiti's PlatformGraphicsAlgorithms allow the user to implement custom rendering for some shapes in a diagram. They are created just like any other GraphicsAlgorithm with the GaCreateService. When displayed, however, the diagram type provider is asked for a IGraphicsAlgorithmRendererFactory which in turn will be asked to create a IGraphicsAlgorithmRenderer for the specific PlatformGraphicsAlgorithm. The renderer interface is just a marker. The returned value can (or maybe even must) be a Draw2D object.

Example

Some code!
In the add feature where we want to create such a shape we will have something like:
import org.eclipse.graphiti.features.*;
import org.eclipse.graphiti.mm.pictograms.*;
import org.eclipse.graphiti.services.*;

public class SomeAddFeature extends AbstractAddFeature {
  // ... usual stuff (contructor, canAdd, etc)

  @Override
  public PictogramElement add(IAddContext context) {
    IPeCreateService peCreateService = Graphiti.getPeCreateService();
    Shape shape = peCreateService.createShape(context.getTargetContainer(), true);
    IGaCreateService gaCreateService = Graphiti.getGaCreateService();
    gaCreateService.createPlatformGraphicsAlgorithm(shape, "SOME_ID");

    link(shape, context.getNewObject());
    layoutPictogramElement(shape);
    return shape;
  }
}
As explained above we will also need an implementation of IGraphicsAlgorithmRendererFactory
import org.eclipse.graphiti.platform.ga.*;

public class GraphicsAlgorithmRendererFactory implements IGraphicsAlgorithmRendererFactory {

  @Override
  public IGraphicsAlgorithmRenderer createGraphicsAlgorithmRenderer(IRendererContext rendererContext) {
    String id = rendererContext.getPlatformGraphicsAlgorithm().getId();
    if ("SOME_ID".equals(id)) {
      return new SomeIdGARenderer();
    }
    return null;
  }
}
A new instance of this class has to be returned by the DiagramTypeProvider class upon calls to the getGraphicsAlgorithmRendererFactory method.

We still missing the implementation of the actual renderer.


import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.Shape;
import org.eclipse.graphiti.platform.ga.IGraphicsAlgorithmRenderer;

public class SomeIdGARenderer extends Shape implements IGraphicsAlgorithmRenderer {

  @Override
  protected void fillShape(Graphics graphics) {
    // your code here
  }

  @Override
  protected void outlineShape(Graphics graphics) {
    // draw outline here
  }
}

More

  • The example shows a GA used as the whole elements visual. PlatformGraphicsAlgorithms can obviously be used also in a PictogramElement composition.
  • Since the renderer is a Figure, we can add children and use layouts.
  • The minimum/maximum and preferred size of the renderer are not used to limit or initialize the bounds of the PictogramElement. Since PE are EObjects we could register an adapter and, at each change of location or size, query the renderer for the limits. (Never really tried this)

4 comments:

Quang Vinh Pham said...

Hi,
I make some research about Graphiti, more in deep. I am really interested on what you write about Graphiti. I need some more research about the Rendering part of Graphiti Framework and more precisely about the impact of the rendering engine of Graphiti on the performance (when we have a Diagram with really alot of element such like 2000 Eclass).
Have you got some research stuff that can help me please.
Also thanks alot for what you write.

David Huber said...

Hi, I'm glad you like the posts.
I never really looked into the performance of the Rendering of graphiti. I started to notice some slow downs with not event that many objects around, however I never searched for the actual cause. It should not be that hard to put together a small application with that ammound of objects.

Regards, David

Kamran Zubairi said...

Hi David. I am trying to implement a Grid Layout to a shape my Graphiti pictogram and am running into problems. I have followed the way you describe in this post but my shape refuses to show up in the pictogram. I can drag and drop it, but there's nothing to see. Could you help me out?

David Huber said...

Hi Kumran, it's quite a while since I last used them, but I'll see what I can find out. Can you share some of your code so I can have a look.