# Zoom grading for massive number of canvas elements
The purpose of the following algorithm is to keep cost of rendering a large number of elements on canvas below a threshold limit.
### Primary algorithm
1. Detect total number of elements to be rendered.
2. Detect element types. Assign a rendering cost to each type. If type not mentioned, assign a default score.
3. Calculate total Cost of rendering (Cra). Compare it with a threshold cost (Crt). Crt can also be computed dynamically based on user's CPU power.
4. If Cra < Crt, no zoom grading is applied and the map will be rendered as is with all the elements in it.
5. If Cra > Crt, detect current visible viewport (described below).
6. Spawn a worker thread to detect number of nodes (exclude edges, spots, regions) Nn within the current viewport. Also calculate cost of rendering these nodes (Crn).
7. Render Nn * max(Cn/Crt,1) nodes to keep the total cost of rendering Cra < Crt.
8. On each zoom/pan, recalculate current viewport (step 6). This will update rendering cost Crt. Update screen based on 4,5,7.
### Viewport detection
1. Detect dimensions of the canvas Dc (Dcx, Dcy). This will generally be propotional to the size of monitor or browser window.
2. Detect dimensions Dm and position Pm of the map.
3. Using Dc, Dm and Pm, the current view port CV can be calculated as:
CV = [
{x: max(0,Pmx), y: min(Dcy, Pmx)},
{x: min(Dcx, Pmx + Dmx), y: max(0,Pmy-Dmy)}
]
This calculation assumes that the origin is at bottom left corner of the canvas.
### Drawbacks
1. If element density on the map is highly variable, the user may need to adjust zoom level to view additional elements.
### Also worth reading
https://konvajs.org/docs/sandbox/Canvas_Scrolling.html