在 Vue 中使用
在 Vue 中使用 VGrammar 的时候,主要需要关心一下几点:
- 新建可视化实例的时机:在浏览器中使用时,VGrammar 是基于 Canvas 实现的图形绘制,所以最基础的 一点就是需要等待容器 dom 元素渲染完成,挂载到 dom 树上后,再去创建可视化实例;
- 及时卸载可视化实例:当组件被卸载之前,需要卸载 VGrammar 创建的实例,防止造成内存泄露
选项式 API 封装
使用选项式(Options) API 封装 VGrammar 的时候,可以参考下列核心代码:
<script lang="ts">
import { defineComponent } from 'vue';
import { View, IView, IElement, IScale } from '@visactor/vgrammar';
import type { PropType } from 'vue';
interface BarChartProps {
colors?: string[];
data?: any[];
}
export default defineComponent({
props: {
colors: Object as PropType<BarChartProps['colors']>,
data: Object as PropType<BarChartProps['data']>
},
setup() {
let view: IView | null = null;
const parseSpec = (chartProps: BarChartProps) => {
return {
// this is a spec
};
};
const createOrUpdateChart = (chartProps: BarChartProps) => {
const container = document.getElementById('barchart-container');
if (container && !view) {
view = new View({
autoFit: true,
container: container,
hover: true
});
view.parseSpec(parseSpec(chartProps) as any);
view.run();
return true;
} else if (view) {
view.updateSpec(parseSpec(chartProps) as any);
view.run();
return true;
}
return false;
};
const releaseView = () => {
if (view) {
view.release();
view = null;
}
};
return {
createOrUpdateChart,
releaseView
};
},
mounted() {
this.createOrUpdateChart({ colors: this.colors, data: this.data });
},
updated() {
this.createOrUpdateChart({ colors: this.colors, data: this.data });
},
beforeUnmount() {
this.releaseView();
}
});
</script>
<template>
<h1>this is a demo of barchart</h1>
<div class="barchart-container" id="barchart-container"></div>
</template>
<style scoped>
.barchart-container {
width: 100%;
height: 400px;
}
</style>
组合式 API 封装
使用组合式 API 封装 VGrammar 的时候,可以参考下列核心代码:
<script setup lang="ts">
import { onMounted, onBeforeUnmount, onUpdated } from 'vue';
import { View, IView, IElement, registerBasicTransforms } from '@visactor/vgrammar';
import { registerTreemapTransforms } from '@visactor/vgrammar-hierarchy';
import { getTreemapData } from '../data/treemap-data';
interface TreemapProps {
colors?: string[];
}
const props = defineProps<TreemapProps>();
let view: IView;
function parseSpec(chartProps: TreemapProps) {
return {
//
};
}
function createOrUpdateChart(chartProps: TreemapProps) {
const container = document.getElementById('treemap-container');
if (container && !view) {
view = new View({
autoFit: true,
container: container,
hover: true
});
view.parseSpec(parseSpec(chartProps) as any);
view.run();
return true;
} else if (view) {
view.updateSpec(parseSpec(chartProps) as any);
view.run();
return true;
}
return false;
}
onMounted(() => {
registerTreemapTransforms();
registerBasicTransforms();
createOrUpdateChart(props);
});
onUpdated(() => {
createOrUpdateChart(props);
});
onBeforeUnmount(() => {
if (view) {
view.release();
}
});
</script>
<template>
<h1>this is a demo of treemap</h1>
<div class="treemap-container" id="treemap-container"></div>
</template>
<style scoped>
.treemap-container {
width: 100%;
height: 400px;
}
</style>