nswamy14 / visual-heatmap

Heatmap : Open source javascript module for high performance, large scale heatmap rendering.
BSD 3-Clause "New" or "Revised" License
53 stars 10 forks source link

Shapes on canvas #28

Open diebarral opened 4 months ago

diebarral commented 4 months ago

Hi @nswamy14,

I have a situation at my current project for which I have to overlap a second canvas on top of this library to display some shapes the client wants to see (zones, more specifically). This has been proven to be quite complicated to get right, so the alignment and zoom/scale between the two canvases make sense.

It'd be great if this library supported drawing additional shapes on top of the heatmap because I avoid the problem mentioned above. Also, this is something I'm willing to do myself and create a pull request later on.

The solution I'm thinking of is providing a function to which you can pass an array of objects, where each object represents a shape. This object would be a list of points that represent the vertexes of the shape (only polygons for now).

What do you think about this? Do you think is doable? Do you see any potential issue I might run into? Any consideration I need to have?

Thanks!

nswamy14 commented 4 months ago

Hi @diebarral, Thank you for sharing your thoughts on this. I agree that adding support for overlaying shapes and text would significantly enhance the usability of this module.

In terms of the approach, we can expose additional apis for Shape and Text rendition. These APIs will overlay an additional single canvas layer(To keep the rendering simple and lightweight) on top of the Heatmap (WebGL) layer. This layer will be reactive to zoom, pan, rotations and other interactions inline with Heatmap layer.

As part of this feature, we may need to support the following feature as well:

Sample API sytax for considerations:

let HeatmapInstance = Heatmap('#containerId', { config });
     HeatmapInstance.addData();
     HeatmapInstance.renderData();

      // For time being we can support just- path, polygon ;  
      HeatmapInstance.addShape({
           el: 'polygon | path | rect | circle |...'
           attr: { points:[], id: "ShapeId" }, for  Polygon
          // attr: { d: "M"} for path.
           style: { fill: '', stroke: '' },
           sizeAttenuation :  Boolean,   // to control the size  on Zoom
           event: {
                 click: () => {},
                 mouseIn: () => {}
           }
      });

 // Similarly for Text:
 HeatmapInstance.addText({
           attr: { x: , y: , text: 'Sample text', id: "TextId" },
           style: { fill: '', stroke: '' }
      })
diebarral commented 4 months ago

Overlaying canvases is the thing that I want to avoid. I've found it's quite complicated to get it right, especially if the user can zoom in/out or drag the heatmap around.

What do you think about drawing the shapes on the same canvas as the heatmap? Is there something I don't know that makes this complicated or not possible?

nswamy14 commented 4 months ago

Rendering everything on a single existing WebGL layer may not be optimal: