@visactor/vchart
Version:
charts lib based @visactor/VGrammar
127 lines (116 loc) • 6.16 kB
JavaScript
import { checkMediaQuery } from "./util";
import { executeMediaQueryAction } from "./util/action";
import { array } from "../../../util";
import { BasePlugin } from "../../base/base-plugin";
import { registerChartPlugin } from "../register";
import { cloneDeepSpec } from "@visactor/vutils-extension";
export class MediaQuery extends BasePlugin {
constructor() {
super(MediaQuery.type), this.type = "MediaQueryPlugin", this._currentMediaInfo = {},
this.currentActiveItems = new Set, this._initialized = !1;
}
onInit(service, chartSpec) {
if (!(null == chartSpec ? void 0 : chartSpec[MediaQuery.specKey])) return;
const {globalInstance: globalInstance} = service;
this._option = {
globalInstance: service.globalInstance,
updateSpec: (spec, compile, render) => {
render ? globalInstance.updateSpecSync(spec) : compile ? globalInstance.updateSpecAndRecompile(spec, !1, {
transformSpec: !0
}) : globalInstance.setRuntimeSpec(spec);
}
}, this._spec = chartSpec[MediaQuery.specKey], this._initialized = !0;
}
onBeforeResize(service, width, height) {
this._initialized && this._changeSize(width, height, !0, !1);
}
onAfterChartSpecTransform(service, chartSpec, actionSource) {
this._initialized && "setCurrentTheme" === actionSource && this._reInit(!1, !1);
}
onAfterModelSpecTransform(service, chartSpec, chartInfo, actionSource) {
this._initialized && "updateSpec" === actionSource && this.onBeforeInitChart(service, chartSpec, "setCurrentTheme");
}
onBeforeInitChart(service, chartSpec, actionSource) {
if (!this._initialized) return;
let resetMediaQuery, checkMediaQuery;
switch (actionSource) {
case "render":
case "updateModelSpec":
resetMediaQuery = !1, checkMediaQuery = !0;
break;
case "setCurrentTheme":
resetMediaQuery = !0, checkMediaQuery = !1;
break;
case "updateSpecAndRecompile":
resetMediaQuery = !1, checkMediaQuery = !1;
}
if (resetMediaQuery && this.release(), this._initialized || this.onInit(service, chartSpec),
resetMediaQuery || checkMediaQuery) {
const {width: width, height: height} = this._option.globalInstance.getCurrentSize();
this._changeSize(width, height, !1, !1);
}
}
_changeSize(width, height, compile, render) {
return (this._currentMediaInfo.width !== width || this._currentMediaInfo.height !== height) && (this._currentMediaInfo.width = width,
this._currentMediaInfo.height = height, this._applyQueries(compile, render));
}
_applyQueries(compile, render) {
const changeToActive = [], changeToInactive = [];
if (this._spec.forEach((item => {
const {hasChanged: hasChanged, isActive: isActive} = this._check(item);
hasChanged && (isActive ? changeToActive.push(item) : changeToInactive.push(item));
})), !changeToActive.length && !changeToInactive.length) return !1;
let chartSpec, chartSpecInfo;
this._baseChartSpec || (this._baseChartSpec = cloneDeepSpec(this._option.globalInstance.getSpec(), [ "data", MediaQuery.specKey ]),
this._baseChartSpecInfo = this._option.globalInstance.getSpecInfo());
let hasChanged = !1;
return changeToInactive.length > 0 ? (chartSpec = cloneDeepSpec(this._baseChartSpec, [ "data", MediaQuery.specKey ]),
chartSpecInfo = this._baseChartSpecInfo, Array.from(this.currentActiveItems).forEach((item => {
if (changeToInactive.includes(item)) return void this.currentActiveItems.delete(item);
const result = this._apply(item, chartSpec, chartSpecInfo);
chartSpec = result.chartSpec;
})), hasChanged = !0) : (chartSpec = this._option.globalInstance.getSpec(), chartSpecInfo = this._option.globalInstance.getSpecInfo()),
changeToActive.forEach((item => {
this.currentActiveItems.add(item);
const result = this._apply(item, chartSpec, chartSpecInfo);
chartSpec = result.chartSpec, hasChanged || (hasChanged = result.hasChanged);
})), hasChanged && this._option.updateSpec(chartSpec, compile, render), !0;
}
_check(item) {
const {globalInstance: globalInstance} = this._option, isActive = checkMediaQuery(item.query, this._currentMediaInfo, globalInstance);
return {
isActive: isActive,
hasChanged: isActive !== this.currentActiveItems.has(item)
};
}
_apply(item, chartSpec, chartSpecInfo) {
const {query: query, action: action} = item;
let hasChanged = !1;
return array(action).forEach((actionItem => {
const result = executeMediaQueryAction(actionItem, query, chartSpec, chartSpecInfo);
chartSpec = result.chartSpec, hasChanged || (hasChanged = result.hasChanged);
})), {
chartSpec: chartSpec,
hasChanged: hasChanged
};
}
_reInit(compile, render) {
let chartSpec = this._option.globalInstance.getSpec();
this._baseChartSpec = cloneDeepSpec(chartSpec, [ "data", MediaQuery.specKey ]),
this._baseChartSpecInfo = this._option.globalInstance.getSpecInfo();
let hasChanged = !1;
this.currentActiveItems.forEach((item => {
const result = this._apply(item, chartSpec, this._baseChartSpecInfo);
chartSpec = result.chartSpec, hasChanged || (hasChanged = result.hasChanged);
})), hasChanged && this._option.updateSpec(chartSpec, compile, render);
}
release() {
super.release(), this._initialized = !1, this._spec = [], this._option = void 0,
this._currentMediaInfo = {}, this.currentActiveItems.clear();
}
}
MediaQuery.pluginType = "chart", MediaQuery.specKey = "media", MediaQuery.type = "MediaQueryPlugin";
export const registerMediaQuery = () => {
registerChartPlugin(MediaQuery);
};
//# sourceMappingURL=media-query.js.map