Search code examples
konvajs

Designing a gantt view with Konva


I am trying to build a gantt control with Konva (does it make sense to use Konva for this)? I have tried to sketch the control below:

enter image description here

I was thinking of breaking down the Konvas stage as follows:

  • One stage with 4 layers: activity names, timeline, activity views, and scrollbar view.

  • The scrollbar layer would contain a "custom control" mimicking a standard scrollbar control.

At this stage I have a couple if questions:

  • What would be the best approach for synchronizing the different layers from an event handling perspective? For example if the user click's on the scrollbar's down arrow shape, I would need to "scroll" all layers one unit down.
  • How does the Konva coordinate system work? Is the drawing of shapes done relative to the containing layer?
  • What's the difference between a layer and a group? Does it make more sense to use a group instead of layers?

I realize my questions are very broad in nature, but at this point I need to get the design right.


Solution

  • I am responding here rather than as a comment because I have more to say than a comment allows.

    I have made Gantts with both HTML elements, and another canvas lib, and Konva. I used Divs with jquery first and it was viable but I felt it got quite complicated and it ran out of steam in the area of zooming the view. You can't hide from the complexity of course. Switching to HTML5 canvas I realised that a lib like Konva would accelerate production. And zooming in canvas is simple.

    As per @lavrton's comment, the text is primitive on HTML5 canvas when compared to GDI, or other, more mature tech. My answer for the labels on tasks was to use off-screen text drawing then converting to images which works very well. For popup editing, I revert to HTML divs etc. I did not use animations in the Gantt but I have elsewhere and canvas should be fine - there are plenty of bouncy-ball / particle tests around to confirm that.

    As a coding design suggestion, the data model and functionality of the Gantt is consistent whatever tech you use to draw it with. I recommend you consider proceeding with a layered approach where your interaction with drawing functions is wrapped as class methods in a drawing class so that you can switch out the drawing tech itself should you feel the need. You could insulate yourself from the choice of tech and/or library that way.

    Turning to aspects of your question:

    • layers are a useful concept. Physically each layer is an HTML5 canvas element. So multiple layers in one diagram are really multiple canvases over the same stage. The benefit here is in redrawing specific layers instead of the entire canvas where there are performance savings. But mostly you can ignore the physical and just get on and use the concept which works well.

    • groups: a group is a collection of shapes on a layer. If you have to draw things made of many shapes, grouping them is very useful because you can move the group as a whole, hide it, delete it, etc. You might, for example, consider making each taskbar, composed of at least a rectangle and text, as being a group. One consideration for groups is that the location and size of the group is that of the bounding rectangle that encloses the shapes within it. This can cause some confusion until you work out an approach. You will find yourself using layers and groups, but mostly groups for drawing controls.

    • Zooming / scaling: this is easy with a canvas. Less easy is the math for how to change the offset to keep the same view as you zoom, but again it is achievable.

    • Synchronised scrolling layers is not going to take any time to develop - just set the layer y-position for each layer.

    • Drawing the grid of rows for activity and columns for days/weeks/months/etc should not be underestimated as a task, but as you develop it you will learn the fundamentals of working with Konva.

    Final point - the docs and examples for Konva could be a bit better, but the community support here and at https://konvajs.github.io/docs/ is good, and the Konva source code is also at that site so you can delve right in to understand what is happening, though you do not need to do that at all if it is not your thing.