Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"changes": [
{
"comment": "feat: support resize zoom chart plugin\n\n",
"type": "none",
"packageName": "@visactor/vchart"
}
],
"packageName": "@visactor/vchart",
"email": "lixuef1313@163.com"
}
2 changes: 1 addition & 1 deletion packages/vchart/src/component/geo/geo-coordinate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ export class GeoCoordinate extends BaseComponent<IGeoRegionSpec> implements IGeo
const result = super._compareSpec(spec, prevSpec);
if (!result.reMake) {
result.reMake = ['roam', 'longitudeField', 'latitudeField', 'projection', 'zoomLimit'].some(k => {
return !isEqual(prevSpec?.[k], spec[k]);
return !isEqual(prevSpec?.[k as keyof IGeoRegionSpec], spec[k as keyof IGeoRegionSpec]);
});
}

Expand Down
1 change: 1 addition & 0 deletions packages/vchart/src/core/vchart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -745,6 +745,7 @@ export class VChart implements IVChart {
if (!this._chart || !this._compiler) {
return false;
}
this._chartPluginApply('onAfterInitChart', this._spec, actionSource);

// compile
this._option.performanceHook?.beforeCompileToVGrammar?.(this);
Expand Down
1 change: 1 addition & 0 deletions packages/vchart/src/plugin/chart/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export * from './media-query';
export * from './formatter';
export * from './register';
export * from './interface';
export * from './resize-zoom';
2 changes: 2 additions & 0 deletions packages/vchart/src/plugin/chart/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export interface IChartPlugin<T extends IChartPluginService = any> extends IBase
actionSource: VChartRenderActionSource
) => MaybePromise<void>;
onBeforeInitChart?: (service: T, chartSpec: any, actionSource: VChartRenderActionSource) => MaybePromise<void>;
onAfterInitChart?: (service: T, chartSpec: any, actionSource: VChartRenderActionSource) => MaybePromise<void>;
}

export interface IChartPluginConstructor {
Expand All @@ -38,4 +39,5 @@ export interface IChartPluginService<T extends IChartPlugin = any> extends IBase
actionSource: VChartRenderActionSource
) => MaybePromise<void>;
onBeforeInitChart?: (chartSpec: any, actionSource: VChartRenderActionSource) => MaybePromise<void>;
onAfterInitChart?: (chartSpec: any, actionSource: VChartRenderActionSource) => MaybePromise<void>;
}
6 changes: 6 additions & 0 deletions packages/vchart/src/plugin/chart/plugin-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ export class ChartPluginService<T extends IChartPlugin = IChartPlugin>
});
}

onAfterInitChart(chartSpec: any, actionSource: VChartRenderActionSource) {
this._plugins.forEach(plugin => {
plugin.onAfterInitChart && plugin.onAfterInitChart(this, chartSpec, actionSource);
});
}

releaseAll(): void {
super.releaseAll();
this.globalInstance = null;
Expand Down
1 change: 1 addition & 0 deletions packages/vchart/src/plugin/chart/resize-zoom/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './zoom';
102 changes: 102 additions & 0 deletions packages/vchart/src/plugin/chart/resize-zoom/zoom.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import type { IChartPlugin, IChartPluginService } from '../interface';
import { BasePlugin } from '../../base/base-plugin';
import { registerChartPlugin } from '../register';
import type { IPoint } from '../../../typings';
import { getDefaultTriggerEventByMode } from '../../../component/common/trigger/config';

const MIN_ZOOM = 0.1;
const MAX_ZOOM = 10;

export class ChartResizeZoomPlugin extends BasePlugin<IChartPluginService> implements IChartPlugin {
Comment thread
xuefei1313 marked this conversation as resolved.
static readonly pluginType: 'chart';
static readonly specKey = 'resizeZoom';
static readonly type: string = 'ChartResizeZoomPlugin';
readonly type: string = 'ChartResizeZoomPlugin';

protected _container?: HTMLElement;
protected _triggerEvent?: string;
protected _minZoom?: number;
protected _maxZoom?: number;
protected _zoom: number = 1;
protected _rate?: number;

constructor() {
super(ChartResizeZoomPlugin.type);
}

onAfterInitChart(service: IChartPluginService, chartSpec: any) {
const chart = service.globalInstance;
const spec = chart.getSpec()?.[ChartResizeZoomPlugin.specKey] ?? { enabled: false };
if (spec.enabled !== true) {
return;
}
this._minZoom = spec.min ?? MIN_ZOOM;
this._maxZoom = spec.max ?? MAX_ZOOM;
this._rate = spec.rate ?? 0.1;
this._container = chart.getContainer();
this._triggerEvent = getDefaultTriggerEventByMode(service.globalInstance.getChart().getOption().mode).zoom;
if (this._container && this._triggerEvent) {
this._container.addEventListener(this._triggerEvent as keyof HTMLElementEventMap, this._onWheel as EventListener);
}
}

protected _onWheel = (e: WheelEvent) => {
e.preventDefault();
e.stopImmediatePropagation();

const zoom = Math.pow(1.005, -e.deltaY * Math.pow(16, e.deltaMode) * 0.2 * this._rate);
const center = { x: e.offsetX, y: e.offsetY };
this.zoom(zoom, center);
};

/**
* 缩放图表
* @param zoom 缩放比例
* @param pointerPos 缩放中心,即鼠标位置
*/
zoom(zoom: number, pointerPos?: IPoint) {
const vchart = this.service.globalInstance;
if (!vchart) {
return;
}
const oldZoom = this._zoom;
let tempZoom = this._zoom * zoom;
if ((tempZoom <= this._minZoom && zoom < 1) || (tempZoom >= this._maxZoom && zoom > 1)) {
if (tempZoom <= this._minZoom && this._zoom > this._minZoom) {
tempZoom = this._minZoom;
} else if (tempZoom >= this._maxZoom && this._zoom < this._maxZoom) {
tempZoom = this._maxZoom;
} else {
return;
}
}

if (tempZoom === oldZoom) {
return;
}

const actualZoomRatio = tempZoom / oldZoom;
this._zoom = tempZoom;

vchart.resize(vchart.getCurrentSize().width * this._zoom, vchart.getCurrentSize().height * this._zoom);
// 滚动容器滚动, 保持当前鼠标位置在缩放后不变
if (pointerPos && this._container) {
const { scrollLeft, scrollTop } = this._container;
this._container.scrollLeft = scrollLeft + pointerPos.x * (actualZoomRatio - 1);
this._container.scrollTop = scrollTop + pointerPos.y * (actualZoomRatio - 1);
}
}

release(): void {
if (this._container && this._triggerEvent) {
this._container.removeEventListener(
this._triggerEvent as keyof HTMLElementEventMap,
this._onWheel as EventListener
);
}
}
}

export const registerChartResizeZoomPlugin = () => {
registerChartPlugin(ChartResizeZoomPlugin);
};
Loading