ECharts 基本概念
ECharts 基本概念: 系列
系列(series)是指:一组数值映射成对应的图

DETAILS

<template>
<div class="overview">
<title-two-level title="品牌概况"></title-two-level>
<div class="container">
<div v-if="chartReady" class="chart-label">
<div class="num">{{ brandList[highlightIndex].count }}</div>
<div class="name">{{ brandList[highlightIndex].band_name }}</div>
<div class="percent">{{ brandList[highlightIndex].percent }}%</div>
</div>
<sc-tf-echart
v-if="chartReady"
class="chart"
:option="option"
@getInstance='getInstance'
></sc-tf-echart>
<div class="list">
<div v-for="(item, index) in brandList" :key="index" class="item" :class="{'selected': highlightIndex === index}">
<div class="image" :style="{background: color[index] || 'rgba(0, 178, 255, 1)' }"></div>
<div class="name">{{ item.band_name }}</div>
<div class="num" :style="{background: `linear-gradient(180deg, #FFFFFF 0%, ${color[index] || 'rgba(0, 178, 255, 1)'} 100%)`, '-webkit-background-clip': 'text', '-webkit-text-fill-color': 'transparent'}">{{ item.count }}</div>
<div class="percent"><number-card :number="item.percent" suffix="%" fontSize="0.2rem" suffixSize="0.12rem"></number-card></div>
</div>
</div>
</div>
</div>
</template>
<script>
import TitleTwoLevel from './TitleTwoLevel.vue';
import NumberCard from './NumberCard.vue'
import { getBrandStatistics } from '@/api/requests'
import { mapState } from 'vuex'
import * as echarts from 'echarts'
export default {
name: 'BrandOverview',
components: {
TitleTwoLevel,
NumberCard
},
props: {
},
data() {
return {
brandList: [],
chartReady: false,
color: ['rgba(255, 153, 0, 1)', 'rgba(167, 255, 146, 1)', 'rgba(0, 255, 194, 1)', 'rgba(255, 199, 0, 1)', 'rgba(182, 148, 255, 1)', 'rgba(0, 178, 255, 1)'],
colorFade: ['rgba(255, 153, 0, 0)', 'rgba(167, 255, 146, 0)', 'rgba(0, 255, 194, 0)', 'rgba(255, 199, 0, 0)', 'rgba(182, 148, 255, 0)', 'rgba(0, 178, 255, 0)'],
highlightIndex: 0,
option: {
series: [
{
// 外面装饰的圆圈
name: 'outerCircle',
type: 'pie',
radius: ['98%', '100%'],
label:{
normal: {
show: false
}
},
labelLine: {
normal: {
show: false
}
},
emphasis: {
disable: false,
scale: false,
scaleSize: 0
},
data: [
{ name: 'outerCircle',
value: 0,
itemStyle: {
normal: {
color: 'rgba(0, 237, 252, 0.5)'
}
}
}
]
},
{
// 里面装饰的圆圈
name: 'innerCircle',
type: 'pie',
radius: ['56%', '58%'],
label:{
normal: {
show: false,
}
},
labelLine: {
normal: {
show: false
}
},
emphasis: {
disable: false,
scale: false,
scaleSize: 0
},
//emphasis: {
//label: {
//show: true,
//formatter: function(params) {
//const { name, percent, value} = params.data
//const list = [
//`{num|${value || 0}}`,
//`{name|${name}}`,
//`{percent|${percent || 0}%}`
//]
//return list.join('\n')
//},
//rich: {
//num: {
//fontFamily: 'D-DIN-PRO',
//fontWeight: 700,
//fontSize: 36,
//lineHeight: 39,
//color: 'rgb(0, 178, 255)'
//},
//name: {
//fontFamily: 'Noto Sans SC',
//fontWeight: 500,
//fontSize: 16,
//lineHeight: 23,
//color: '#fff'
//},
//percent: {
//fontFamily: 'D-DIN-PRO',
//fontWeight: 400,
//fontSize: 16,
//lineHeight: 17,
//color: 'rgb(0, 178, 255)'
//}
//}
//},
//itemStyle: {
//shadowBlur: 100,
//shadowOffsetX: 0,
//shadowColor: 'rgba(0, 0, 0, 0.5)'
//},
//},
data: [
{ name: 'innerCircle',
value: 0,
itemStyle: {
normal: {
color: 'rgba(255, 255, 255, 0.2)'
}
}
}
]
},
{
name: 'brandOverview',
type: 'pie',
radius: ['60%', '80%'],
avoidLabelOverlap: false,
label: {
show: false,
position: 'center',
},
labelLine: {
show: false
},
data: []
},
]
},
}
},
computed: {
...mapState('userInfo', [
'department',
'grade'
])
},
created() {
},
watch: {
department: {
handler(val) {
if (Array.isArray(val) && val.length > 0) {
this.getBrandStatisticsHandler()
}
},
immediate: true
}
},
methods: {
getBrandStatisticsHandler(){
getBrandStatistics({
dept_id: parseInt(this.department[this.department.length - 1]),
dept_level: this.grade
}).then(res => {
this.brandList = res
this.brandList = [{
band_name: "中控",
count: 10,
percent: "10%"
}, {
band_name: "大华",
count: 10,
percent: "10%"
}, {
band_name: "SCATS",
count: 30,
percent: "10%"
}, {
band_name: "华路德",
count: 20,
percent: "30%"
}]
if (Array.isArray(this.brandList)) {
this.brandList.forEach(item => {
item.percent = item.percent.split('%')[0]
})
}
this.setData()
})
},
setData() {
const brandList = this.brandList.map((item, index) => {
return {
name: item.band_name,
value: item.count,
itemStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: this.color[index]? this.color[index]: this.color[this.color.length - 1]
}, {
offset: 1,
color: this.colorFade[index]? this.colorFade[index]: this.colorFade[this.colorFade.length - 1]
}]),
}
}
}
})
this.option.series[2].data = brandList
this.chartReady = true
},
getInstance(chart) {
const that = this
that.chart = chart
chart.dispatchAction({
type: 'highlight',
seriesIndex: 2,
dataIndex: 0,
})
chart.on('mouseover', {}, params => {
const { seriesIndex, dataIndex } = params
if (seriesIndex === 2 && this.highlightIndex !== dataIndex) {
chart.dispatchAction({
type: 'downplay',
seriesIndex: 2,
dataIndex: this.highlightIndex
})
chart.dispatchAction({
type: 'highlight',
seriesIndex: 2,
dataIndex,
})
this.highlightIndex = dataIndex
}
})
chart.on('mouseout', {}, params => {
chart.setOption({
color: that.color
})
})
}
}
}
ECharts 4.0 新特性:dataset
ECharts 4 开始支持了 数据集(dataset)组件用于单独的数据集声明,从而数据可以单独管理,被多个组件复用,并且可以自由指定数据到视觉的映射。这一特性能将逻辑和数据分离,带来更好的复用,并易于理解。

ECharts 基本概念: 组件
ECharts 中除了绘图之外其他部分,都可抽象为 「组件」。例如,ECharts 中至少有这些组件:xAxis(直角坐标系 X 轴)、yAxis(直角坐标系 Y 轴)、grid(直角坐标系底板)、angleAxis(极坐标系角度轴)...

ECharts 基本概念:定位
大多数组件都提供了定位属性,我们可以采用类似 CSS absolute 的定位属性来控制组件的位置,下面这个案例可以通过修改 grid 组件定位来控制图表的位置

ECharts 基本概念:坐标系
很多系列,例如 line(折线图)、bar(柱状图)、scatter(散点图)、heatmap(热力图)等等,需要运行在 “坐标系” 上。坐标系用于布局这些图,以及显示数据的刻度等等。例如 ECharts 中至少支持这些坐标系:直角坐标系、极坐标系、地理坐标系(GEO)、单轴坐标系、日历坐标系 等。其他一些系列,例如 pie(饼图)、tree(树图)等等,并不依赖坐标系,能独立存在。还有一些图,例如 graph(关系图)等,既能独立存在,也能布局在坐标系中,依据用户的设定而来。
一个坐标系,可能由多个组件协作而成。我们以最常见的直角坐标系来举例。直角坐标系中,包括有 xAxis(直角坐标系 X 轴)、yAxis(直角坐标系 Y 轴)、grid(直角坐标系底板)三种组件。xAxis、yAxis 被 grid 自动引用并组织起来,共同工作。
案例:散点图
我们来看下图,这是最简单的使用直角坐标系的方式:只声明了 xAxis、yAxis 和一个 scatter(散点图系列),ECharts 会为它们创建 grid 并进行关联:

案例:双坐标系
再来看下图,两个 yAxis,共享了一个 xAxis。两个 series,也共享了这个 xAxis,但是分别使用不同的 yAxis,使用 yAxisIndex 来指定它自己使用的是哪个 yAxis:

案例:多坐标系
再来看下图,一个 ECharts 实例中,有多个 grid,每个 grid 分别有 xAxis、yAxis,他们使用 xAxisIndex、yAxisIndex、gridIndex 来指定引用关系:

柱状图默认选中,这个是showTip不是highlight,
这样鼠标移上去会改变showtip 如果不想变 也可以再写个坐标再写个大柱子用来高亮
tooltip 包括悬浮框也包括 鼠标放上去echart图的柱状背景或着折线图的线的样式

tooltip 包括悬浮框也包括 鼠标放上去echart图的柱状背景或着折线图的线的样式
tooltip: {
show: "true",
trigger: "axis",
axisPointer: {
// 坐标轴指示器,坐标轴触发有效
type: "shadow", // 默认为直线,可选为:'line' | 'shadow'
shadowStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
// x:为1 从左往右
// y:为1 从上往下
// x2:为1 从右往左
// y2: 为1 从下往上
{
offset: 0, // 从上往下0 -> 1
color: "rgba(255,252,255,0.1)",
},
{
offset: 0.99,
color: "rgba(255,255,255,0.1)",
},
{
offset: 0.99,
color: "rgba(255,255,255,1)",
},
{
offset: 1,
color: "rgba(255,255,255,1)",
},
]),
width: "auto",
},
},
},
this.flexibleChart.dispatchAction({
type: 'showTip',
seriesIndex: 0,
dataIndex: currentIndex
});
<sc-tf-echart :data="flowData" :option="flowChartOption" @getInstance="getChart"></sc-tf-echart>
组件库中的data:[{
name: '东-直行',
value: '100'
},{
name: '西-直行',
value: '20'
},{
name: '南-直行',
value: '50'
},{
name: '北-直行',
value: '80'
}]
是把 xAxis: {data: ["企业", "农专", "个体"]
和 series: [
{data: [100, 50, 20]}
]
整合到一起
// 白色细线 dot细线的样式和 浮框的样式
axisPointer: {
label: {
show: false,
margin: 10,
backgroundColor: '#0b1f56',
color: '#fff',
fontSize: 14,
fontFamily: 'Noto Sans SC'
},
lineStyle: {
width: 1
}
},
data 横坐标
1、如果xAxis是 category
如果横坐标在在 xAxis中 data要和series中的data一一对应,否则数据会断掉或者渲染不出来
如果横坐标在series中 series的data是二维数组 markArea和markLine中的坐标要在data中 否则渲染不出来
2、如果xAxis是time,data可以随意
markArea和markLine中的坐标可以不在data中 也能渲染出来
在series里写 在饼图中间展示 在series同级写展示在饼图上下左右边上, 如果中间的label样式太丰富不好写 写div
// label: {
// show: true,
// formatter: '{b}\n{c}个\n{d}%', // 标签显示:名称+数量+百分比
// fontSize: 12,
// lineHeight: 20
// },
label: {
show: false,
color: '#7FB4D6',
position: 'center',
formatter: function (params) {
return params.value.name+ '\n' + params.value.undefined+ ' \n' + params.percent + '%'
}
},