blob: 61f8b0bd04328dcd2374b59770d107b7c902cd28 [file] [log] [blame]
<template>
<div v-loading="isWebFontLoading" element-loading-text="字体加载中">
<div class="chart" ref="chartRef">aaa</div>
</div>
</template>
<script setup lang="ts">
import { onMounted, shallowRef, ref } from 'vue';
import * as echarts from 'echarts';
import 'echarts-wordcloud';
import Color from 'color';
// const props = defineProps({
// foo: String
// });
const chart = shallowRef<echarts.ECharts | null>(null);
const chartRef = ref<HTMLElement | null>(null);
const isWebFontLoading = ref(false);
defineExpose({
run,
setLoading
});
type Config = {
bgColor: string;
themeColors: string[];
saturation: number[];
lightness: number[];
alpha: number[];
fontFamily: string;
fontSize: number[];
rotate: number[];
width: number;
height: number;
shape: string;
shapeRatio: boolean;
};
function setLoading(isLoading: boolean) {
isWebFontLoading.value = isLoading;
}
function run(data?: [], config?: Config) {
const hues = config
? config.themeColors.map(
color =>
Color(color)
.hsl()
.object().h
)
: [];
function getHue() {
const index = Math.floor(Math.random() * hues.length);
return hues[index];
}
function getRandom(minMax: number[] | undefined) {
if (!minMax) {
return 0;
}
const max = minMax[1] == null ? 1 : minMax[1];
const min = minMax[0] == null ? 0 : minMax[0];
const range = max - min || 1;
return Math.random() * range + min;
}
function render(maskImage?: HTMLImageElement) {
chart.value!.setOption({
backgroundColor: config!.bgColor,
series: [
{
type: 'wordCloud',
data: data || [],
gridSize: 4,
sizeRange: config?.fontSize,
rotationRange: config?.rotate,
maskImage,
width: config?.width + '%',
height: config?.height + '%',
layoutAnimation: true,
keepAspect: config?.shapeRatio,
textStyle: {
color: (param: any) => {
const value = param.value;
const h = getHue();
const s = getRandom(config?.saturation);
const l = getRandom(config?.lightness);
const color = Color(`hsl(${h}, ${s}%, ${l}%)`);
return color.toString();
}
}
}
],
textStyle: {
fontFamily: config?.fontFamily
}
});
}
let maskImage: HTMLImageElement;
if (config) {
maskImage = new Image();
maskImage.src = config.shape.startsWith('blob:')
? config.shape
: config.shape + '.png';
maskImage.onload = () => {
render(maskImage);
};
maskImage.onerror = () => {
render();
};
}
else {
render();
}
}
onMounted(() => {
chart.value = echarts.init(chartRef.value!);
});
</script>
<style scoped lang="scss">
.chart {
border: 1px solid #f2eef2;
width: 800px;
height: 600px;
}
</style>