Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
8fd9fd1
feat: offscreen poc
DeltaZN Nov 18, 2023
61685fb
feat(offscreen): improve perf
DeltaZN Nov 18, 2023
eea6b9a
feat(offscreen): canvas commands optimization
DeltaZN Nov 18, 2023
f61252e
feat(offscreen): improve performance
DeltaZN Nov 18, 2023
179f02f
feat(offscreen): use shared memory for performance
DeltaZN Nov 18, 2023
1da7146
feat(offscreen): fix chart resize
DeltaZN Nov 19, 2023
3ff9f05
feat(offscreen): fix sharedArrayBuffer typing
DeltaZN Nov 19, 2023
1b2a719
chore(offscreen): Merge branch 'master' into offscreen-poc
DeltaZN Nov 19, 2023
47d8a3e
feat(offscreen): fixing bugs
DeltaZN Nov 20, 2023
5e0c288
feat(offscreen): fix render in multichart mode
DeltaZN Nov 25, 2023
52bdb3d
feat(offscreen): code style improvements + docs
DeltaZN Dec 2, 2023
5cfaecf
feat(offscreen): revert unnecessary changes
DeltaZN Dec 2, 2023
b638f74
feat(offscreen): fix typing errors
DeltaZN Dec 2, 2023
4d06f79
Merge branch 'master' into offscreen-poc
DeltaZN Dec 2, 2023
4208612
feat(offscreen): fix redrawBackground, setGradient & getImageData ope…
DeltaZN Dec 3, 2023
8d27442
feat(offscreen): fix build
DeltaZN Dec 3, 2023
3ac3354
feat(offscreen): update package.json
DeltaZN Dec 3, 2023
48d44b4
feat(offscreen): fix offscreen init types
DeltaZN Dec 3, 2023
22cd89e
feat(offscreen): disable redraw canvases immediate in offscreen mode
DeltaZN Dec 3, 2023
2220af4
feat(offscreen): adjust buffer sizes for complex scenes
DeltaZN Dec 4, 2023
e3d9522
Merge branch 'master' into offscreen-poc
DeltaZN Dec 5, 2023
e3d328e
chore(offscreen): merge with master
DeltaZN Feb 23, 2024
f6ba0ff
feat(offscreen): fix drawing gradient
DeltaZN Feb 23, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
},
"dependencies": {
"color": "^4.2.3",
"comlink": "4.4.1",
"date-fns": "^2.30.0",
"rxjs": "^7.5.7"
},
Expand Down
82 changes: 42 additions & 40 deletions src/chart/bootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ import { clearerSafe } from './utils/function.utils';
import { merge } from './utils/merge.utils';
import { DeepPartial } from './utils/object.utils';
import { HitTestComponent } from './components/hit-test/hit-test.component';
import { isOffscreenWorkerAvailable } from './canvas/offscreen/init-offscreen';

export type FitType = 'studies' | 'orders' | 'positions';

Expand Down Expand Up @@ -190,38 +191,70 @@ export default class ChartBootstrap {
this.canvasModels,
config,
);
this.chartResizeHandler = chartResizeHandler;
chartResizeHandler.subscribeResize();
this.components.push(chartResizeHandler.unsubscribeAnimationUpdate.bind(chartResizeHandler));
const drawingManager = new DrawingManager(eventBus, chartResizeHandler);
this.drawingManager = drawingManager;

const offscreenEnabled = isOffscreenWorkerAvailable && config.experimental.offscreen.enabled;

const backgroundCanvasModel = createCanvasModel(
eventBus,
elements.backgroundCanvas,
config,
this.canvasModels,
elements.chartResizer,
{
offscreen: offscreenEnabled,
offscreenBufferSize: config.experimental.offscreen.bufferSizes.backgroundCanvas,
},
);
this.backgroundCanvasModel = backgroundCanvasModel;
const mainCanvasModel = createMainCanvasModel(
eventBus,
elements.mainCanvas,
elements.chartResizer,
this.config.components.chart.type,
this.config,
drawingManager,
config,
this.canvasModels,
{ offscreen: offscreenEnabled, offscreenBufferSize: config.experimental.offscreen.bufferSizes.mainCanvas },
);
this.mainCanvasModel = mainCanvasModel;
this.dynamicObjectsCanvasModel = createCanvasModel(
eventBus,
elements.dynamicObjectsCanvas,
config,
drawingManager,
this.canvasModels,
elements.chartResizer,
{ offscreen: offscreenEnabled, offscreenBufferSize: config.experimental.offscreen.bufferSizes.dynamicObjectsCanvas },
);
const crossToolCanvasModel = createCanvasModel(
eventBus,
elements.crossToolCanvas,
config,
this.canvasModels,
elements.chartResizer,
{ offscreen: offscreenEnabled, offscreenBufferSize: config.experimental.offscreen.bufferSizes.crossToolCanvas },
);
const snapshotCanvasModel = createCanvasModel(
eventBus,
elements.snapshotCanvas,
config,
this.canvasModels,
elements.chartResizer,
{ offscreen: offscreenEnabled, offscreenBufferSize: config.experimental.offscreen.bufferSizes.snapshotCanvas },
);
this.chartResizeHandler = chartResizeHandler;
chartResizeHandler.subscribeResize();
this.components.push(chartResizeHandler.unsubscribeAnimationUpdate.bind(chartResizeHandler));
const drawingManager = new DrawingManager(config, eventBus, chartResizeHandler, this.canvasModels);
this.drawingManager = drawingManager;

const dataSeriesCanvasClearDrawer = new ClearCanvasDrawer(this.dynamicObjectsCanvasModel);
drawingManager.addDrawer(dataSeriesCanvasClearDrawer, 'SERIES_CLEAR');
const yAxisLabelsCanvasModel = createCanvasModel(
eventBus,
elements.yAxisLabelsCanvas,
config,
drawingManager,
this.canvasModels,
elements.chartResizer,
{ offscreen: offscreenEnabled, offscreenBufferSize: config.experimental.offscreen.bufferSizes.yAxisLabelsCanvas },
);
const canvasBoundsContainer = new CanvasBoundsContainer(
config,
Expand All @@ -246,7 +279,6 @@ export default class ChartBootstrap {
elements.hitTestCanvas,
canvasInputListener,
canvasBoundsContainer,
drawingManager,
config,
this.canvasModels,
elements.chartResizer,
Expand All @@ -266,20 +298,6 @@ export default class ChartBootstrap {
this.scaleModel = scaleModel;
//#endregion

const backgroundCanvasModel = createCanvasModel(
eventBus,
elements.backgroundCanvas,
config,
drawingManager,
this.canvasModels,
elements.chartResizer,
{
// can be read frequently, see {redrawBackgroundArea} function
willReadFrequently: true,
},
);
this.backgroundCanvasModel = backgroundCanvasModel;

this.cursorHandler = new CursorHandler(
elements.canvasArea,
canvasInputListener,
Expand Down Expand Up @@ -409,14 +427,6 @@ export default class ChartBootstrap {
drawingManager,
);
this.chartComponents.push(this.watermarkComponent);
const crossToolCanvasModel = createCanvasModel(
eventBus,
elements.crossToolCanvas,
config,
drawingManager,
this.canvasModels,
elements.chartResizer,
);
this.highlightsComponent = new HighlightsComponent(
eventBus,
config,
Expand Down Expand Up @@ -521,14 +531,6 @@ export default class ChartBootstrap {

this.chartComponents.push(this.crossToolComponent);
// Snapshot component
const snapshotCanvasModel = createCanvasModel(
eventBus,
elements.snapshotCanvas,
config,
drawingManager,
this.canvasModels,
elements.chartResizer,
);
const snapshotComponent = new SnapshotComponent(this.elements, snapshotCanvasModel);
this.snapshotComponent = snapshotComponent;
this.chartComponents.push(snapshotComponent);
Expand Down
4 changes: 2 additions & 2 deletions src/chart/canvas/canvas-bounds-container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ export class CanvasBoundsContainer {
this.updateCanvasOnPageLocation(calculatedBCR);
this.recalculateBounds();
});
this.yAxisBoundsContainer = new YAxisBoundsContainer(this.config, this.canvasModel);
this.yAxisBoundsContainer = new YAxisBoundsContainer(this.config);
}

public updateYAxisWidths() {
Expand Down Expand Up @@ -438,7 +438,7 @@ export class CanvasBoundsContainer {
getXAxisHeight() {
if (!this.xAxisHeight) {
const font = this.config.components.xAxis.fontSize + 'px ' + this.config.components.xAxis.fontFamily;
const fontHeight = calculateSymbolHeight(font, this.canvasModel.ctx);
const fontHeight = calculateSymbolHeight(font);
this.xAxisHeight =
fontHeight +
(this.config.components.xAxis.padding.top ?? 0) +
Expand Down
4 changes: 2 additions & 2 deletions src/chart/canvas/cursor.handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ export class CursorHandler extends ChartBaseElement {
this.canvasInputListener
.observeMouseMoveNoDrag()
.pipe(throttleTime(100, animationFrameScheduler, { trailing: true }))
.subscribe(point => {
const cursorFromHT = this.hitTestCanvasModel.resolveCursor(point);
.subscribe(async point => {
const cursorFromHT = await this.hitTestCanvasModel.resolveCursor(point);
if (cursorFromHT !== undefined) {
this.updateCursor(cursorFromHT);
return;
Expand Down
90 changes: 90 additions & 0 deletions src/chart/canvas/offscreen/canvas-ctx.mapper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// #region canvas commands encodings - see commands mappings to methods below
export const FONT = 0;
export const WIDTH = 1;
export const HEIGHT = 2;
export const FILL_STYLE = 3;
export const STROKE_STYLE = 4;
export const LINE_WIDTH = 5;
export const LINE_CAP = 6;
export const SAVE = 7;
export const RESTORE = 8;
export const MEASURE_TEXT = 9;
export const CLEAR_RECT = 10;
export const FILL_RECT = 11;
export const STROKE_TEXT = 12;
export const SET_LINE_DASH = 13;
export const FILL_TEXT = 14;
export const RECT = 15;
export const CLIP = 16;
export const QUADRATIC_CURVE_TO = 17;
export const BEZIER_CURVE_TO = 18;
export const BEGIN_PATH = 19;
export const MOVE_TO = 20;
export const LINE_TO = 21;
export const STROKE = 22;
export const FILL = 23;
export const CLOSE_PATH = 24;
export const STROKE_RECT = 25;
export const SCALE = 26;
export const NOP = 27;
export const ARC = 28;
// custom method
export const SET_LINE_DASH_FLAT = 29;
// custom method
export const SET_GRADIENT_FILL_STYLE = 30;
// custom method
export const REDRAW_BACKGROUND_AREA = 31;
export const TRANSLATE = 32;
export const TEXT_BASELINE = 33;
export const TEXT_ALIGN = 34;
export const ROTATE = 35;
export const LINE_JOIN = 36;
export const DIRECTION = 37;
export const FONT_KERNING = 38;

// Special command which indicates the end of canvas commands inside the buffer
export const END_OF_FILE = 0xdead;
// #endregion

// Map from command number to canvas context method name
export const num2Ctx = [
'font',
'width',
'height',
'fillStyle',
'strokeStyle',
'lineWidth',
'lineCap',
'save',
'restore',
'measureText',
'clearRect',
'fillRect',
'strokeText',
'setLineDash',
'fillText',
'rect',
'clip',
'quadraticCurveTo',
'bezierCurveTo',
'beginPath',
'moveTo',
'lineTo',
'stroke',
'fill',
'closePath',
'strokeRect',
'scale',
'nop',
'arc',
'setLineDashFlat',
'setGradientFillStyle',
'redrawBackgroundArea',
'translate',
'textBaseline',
'textAlign',
'rotate',
'lineJoin',
'direction',
'fontKerning',
];
Loading