本文的源码直接戳文章最后,关注公众号,戳同样标题的文章,可获得下载链接。
先来看一下成品图:
gif 使用的生成工具,地址戳这里https://dongci.kawo.com/?iao.su
这个图表的应用场景,我个人会偏向用于:事件总集的时候,以月份划分,可以用在移动端或者PC端,也可以加入 时间表盘 的概念。
进入正题
这个小太阳图是一个 极坐标bar图 + 旭日图 的合成图。
既然我们能拆成这两种图表类型,那就可以直接开始做,先分别来实现一个旭日图和极坐标bar图。
接下来先进行前期的安装及挂载准备
npm install echarts
npm install vue-echarts
// main.js引入挂载:
import { createApp } from "vue";
import App from "./App.vue";
import ECharts from 'vue-echarts'
import { use } from "echarts/core";
// 手动引入 ECharts 各模块来减小打包体积
import {
CanvasRenderer
} from 'echarts/renderers'
import {
TooltipComponent,
} from 'echarts/components'
use([
CanvasRenderer,
TooltipComponent,
])
const app = createApp(App)
app.mount("#app");
// 全局注册组件(也可以使用局部注册)
app.component('v-chart', ECharts)
旭日图配置:
option: {
backgroundColor:"rgba(255,255,255,0)",
toolbox: {
feature: {
saveAsImage: {},
},
},
series: {
type: "sunburst",
data: data, // 数据此处省略,可以关注公众号获取本文源码
radius: [0, "95%"],
sort: undefined,
emphasis: {
focus: "ancestor",
},
levels: [
{},
{
r0: "15%",
r: "35%",
itemStyle: {
borderWidth: 2,
},
label: {
rotate: "tangential",
},
},
{
r0: "35%",
r: "70%",
label: {
align: "right",
},
},
],
},
},
极坐标bar图配置:
option: {
toolbox: {
feature: {
saveAsImage: {},
},
},
grid: {
show: false,
top: 100,
},
angleAxis: {
show: false,
type: "category",
data: cities,
},
tooltip: {
show: true,
formatter: function (params) {
const id = params.dataIndex;
return (
cities[id] + "<br>Lowest:" + data[id][0] + "<br>Highest:" + data[id][1]
);
},
},
radiusAxis: {
// show: false,
},
polar: {},
series: [
{
type: "bar",
itemStyle: {
color: "transparent",
},
data: data.map(function (d) {
return d[0];
}),
coordinateSystem: "polar",
stack: "Min Max",
silent: true,
},
{
type: "bar",
data: data.map(function (d) {
return d[1] - d[0];
}),
coordinateSystem: "polar",
name: "Range",
stack: "Min Max",
},
{
type: "bar",
itemStyle: {
color: "transparent",
},
data: data.map(function (d) {
return d[2] - barHeight;
}),
coordinateSystem: "polar",
stack: "Average",
silent: true,
z: 10,
},
],
},
两种图表结合后的绘制如下:
<v-chart
class="chart"
autoresize
:ref="refName"
@mouseover="handlerMouseover"
@mouseout="handlerMounseout"
@click="handlerClick"
/>
-------------JS-----------
option: {
toolbox: {
feature: {
saveAsImage: {},
},
},
grid: {
top: 100,
},
angleAxis: {
show: false,
type: "category",
data: lodash.uniq(lodash.map(new_data, "name")),
},
tooltip: {
show: true,
formatter: function (params) {
const id = params.dataIndex;
return `${params.name}:${new_data[id].value}`;
},
},
radiusAxis: {
show: false,
},
polar: {},
series: [
{
type: "sunburst",
data: sunburst_data,
radius: [0, "95%"],
sort: undefined,
nodeClick: false,
emphasis: {
focus: "ancestor",
},
levels: [
{},
{
r0: "10%",
r: "20%",
itemStyle: {
borderWidth: 2,
},
label: {
rotate: "tangential",
},
},
],
},
{
type: "bar",
itemStyle: {
color: "transparent",
},
data: lodash.map(new_data, "start"),
coordinateSystem: "polar",
stack: "Min Max",
silent: true,
},
{
type: "bar",
data: new_data,
coordinateSystem: "polar",
name: "Range",
stack: "Min Max",
},
],
},
大家可以主要到 gif 动图中,鼠标悬浮在一级菜单时,是有交互的,这个交互需要用 JS来写,不能直接通过 echarts 的属性来进行操作配置。逻辑代码如下:
const handlerMouseover = (e) => {
if (e.seriesType === "sunburst") {
handlerMounseout();
lodash.map(
lodash.filter(new_data, function (o) {
return o.type !== e.name;
}),
function (d) {
d.itemStyle.opacity = 0.5;
}
);
dom.setOption(addData.option, true);
}
};
const handlerMounseout = (e) => {
lodash.map(new_data, function (a) {
a.itemStyle.opacity = 1;
});
dom.setOption(addData.option, true);
};
---------------说点题外话-----
echarts 是比较容易上手的做图表可视化的工具,很多日常常用的图表都可以满足,当然需要创造性地图表的话,可以用 D3 来做。
公众号放在下面啦,欢迎多多关注呀~