Skip to content

Hop Web: generic SVG canvas SPI for plugin graph editors #7873

Description

@mattcasters

Context

Hop Web already renders pipelines and workflows by generating SVG on the server (PipelineCanvasSvgRenderer / WorkflowCanvasSvgRenderer), caching a revisioned snapshot, serving it via the canvasRender service handler, and overlaying it in the browser (canvas-svg.js). Clicks stay on the RAP SWT path with server-side AreaOwner hit testing; hover uses CanvasInteractionHandler.

That stack is hard-wired to pipeline and workflow graphs:

  • CanvasSvgFacade only exposes renderPipeline / renderWorkflow
  • CanvasSvgFacadeImpl.syncAreaOwnersToGraph only knows HopGuiPipelineGraph / HopGuiWorkflowGraph
  • CanvasInteractionHandler.handleHover same hard-coding
  • CanvasFacadeImpl.setDataInternal treats any non-WorkflowMeta as PipelineMeta (ClassCastException for custom models)

Plugins that ship custom canvas editors (e.g. Data Vault / Business Vault / dimensional modelers, other graph file types) cannot reuse the existing Hop Web SVG transport without forking RAP code.

Related consumer: mattcasters/hop-data-vault#119

Goal (minimal for 2.19.0 feature freeze)

Expose a small, backward-compatible SPI so any registered graph can:

  1. Publish a pre-rendered CanvasSvgRenderResult snapshot (SVG + area owners + view/graph ports)
  2. Receive hover events and area-owner updates without being a pipeline/workflow graph
  3. Call CanvasFacade.setData with non-pipeline/workflow meta without crashing (common props only)

Pipeline/workflow behavior must remain unchanged.

Proposed API (minimal)

IWebCanvasGraph (ui module)

public interface IWebCanvasGraph {
  void replaceAreaOwners(List<AreaOwner> owners);
  void handleWebCanvasHover(int graphX, int graphY, int screenX, int screenY);
}
  • Implement on existing HopGuiPipelineGraph / HopGuiWorkflowGraph (methods already exist)
  • RAP hover + area sync use instanceof IWebCanvasGraph

CanvasSvgFacade.publishSnapshot(...)

public static void publishSnapshot(
    Canvas canvas,
    CanvasSvgRenderResult result,
    float magnification,
    DPoint offset,
    Point canvasSize);
  • Extract existing private snapshot store path used by pipeline/workflow render
  • Plugins render with their own painters + SvgGc, then publish

CanvasFacadeImpl guard

  • If meta is neither PipelineMeta nor WorkflowMeta, set common props (theme, grid, mag, offset, viewport) only; do not cast to PipelineMeta

Non-goals for this PR

  • Plugin-shipped JavaScript / custom RAP remote types
  • Rewriting modelers inside Hop core
  • Changing client canvas-svg.js interaction model

Acceptance

  • Opening a custom graph that calls CanvasFacade.setData(canvas, mag, offset, customModel) does not ClassCast under RAP
  • A graph implementing IWebCanvasGraph can registerCanvas + publishSnapshot and appear in Hop Web via existing client overlay
  • Pipeline and workflow Hop Web paint/hover/drag unchanged
  • Desktop RCP facades remain no-ops for new methods

Why 2.19.0

Needed before feature freeze so external plugins (Data Vault and others) can wire Hop Web modelers against the 2.19 line without waiting for 2.20.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions