|
为 Echarts 创建一个具备高宽的DOM容器
- <div :id="'myChart' + idkey " :style="{width: '300px', height: '200px'}"></div>
复制代码
id必须唯一,这样设置由于项目中有多个图表 单一的图表可以自己随便设置
准备好初始化的内容 设置 Echarts 样式
- option: {
- // 直角坐标系 grid 中的 x 轴,一般情况下单个 grid 组件最多只能放上下两个 x 轴,多于两个 x 轴需要通过配置 offset 属性防止同个位置多个 x 轴的重叠。
- xAxis: {
- data: this.charttimes,// 类目数据
- show: false,// 是否显示 x 轴
- // 坐标轴刻度标签的相关设置
- axisLabel: {
- // 刻度标签的内容格式器,支持字符串模板和回调函数两种形式
- formatter: function (value, idx) {// 函数参数分别为刻度数值(类目),刻度的索引
- let newDate = new Date(Number(value))
- return [newDate.getMonth() + 1, newDate.getDate()].join('/')
- },
- interval: 500// 坐标轴刻度标签的显示间隔,在类目轴中有效 设置为 1,表示『隔一个标签显示一个标签』,如果值为 2,表示隔两个标签显示一个标签,以此类推
- },
- boundaryGap: ['10%', '10%']// 坐标轴两边留白策略,类目轴和非类目轴的设置和表现不一样
- },
- // 类似xAxis
- yAxis: {
- show: false,
- boundaryGap: ['30%', '30%']
- },
- series: {
- showSymbol: false,// 是否显示 symbol, 如果 false 则只有在 tooltip hover 的时候显示
- hoverAnimation: false,// 是否开启 hover 在拐点标志上的提示动画效果
- data: this.chartusages,// 系列中的数据内容数组。数组项通常为具体的数据项
- type: 'line',// 图表类型
- lineStyle: {
- color: '#8C8C8C',
- width: 1
- }
- },
- // 提示框组件
- tooltip: {
- trigger: 'axis',// 触发类型 坐标轴触发
- formatter: function (datas) {// 提示框浮层内容格式器,支持字符串模板和回调函数两种形式
- let newDate = new Date(Number(datas[0].name))
- let dateFormatter = date2str(newDate, 'YYYY-MM-DD HH:mm:ss')
- return dateFormatter + '</br>' + datas[0].value + '%'
- },
- // 坐标轴指示器配置项
- axisPointer: {
- lineStyle: {
- color: '#3752ff'
- },
- shadowStyle: {
- color: '#3752ff'
- }
- }
- }
- }
复制代码
一些项目中用到的配置都在上面 也有一些详细的解释 这里再提一下 提示框是指当鼠标移到数据部分会有一个框详细展示该点的信息 那么指示器就是一条线 上面配置就是一个颜色差不多深蓝色 平行于y轴的直线 随着鼠标的移动跟着动
画图
- drawEChart () {
- 获取DOM容器
- let myChart = echarts.init(document.getElementById(`myChart${this.idkey}`))
- this.option.xAxis.data = this.charttimes// 设置x轴数据 也就是说x轴应该显示啥 这就写啥
- this.option.series.data = this.chartusages // 设置图的数据 没数据拿啥画?
- myChart.setOption(this.option)// 画图
- }
复制代码
案例二
创建容器
....这个代码就不写了
准备配置
- // 组件封装 数据传过来的 遍历一下 懒得改 凑合看
- let series = this.ydata.map((data, idx) => ({
- name: this.names[idx],//系列名称
- data: data,//数据
- type: 'line',
- symbol: 'circle',
- showSymbol: false,
- /** 控制某点变色点时候不要直接设置颜色 */
- lineStyle: this.visualMap ? {} : {
- color: this.colors[idx]
- },
- itemStyle: {
- color: this.colors[idx],
- borderColor: this.colors[idx]
- },
- ...(this.area ? { areaStyle: typeof this.area === 'object' ? this.area : {
- color: new LinearGradient(0, 0, 0, 1, [{
- offset: 0,
- color: '#65BDF6'
- }, {
- offset: 1,
- color: this.colors[idx]
- }])
- }} : {})
- }))
- let that = this
- /** 控制某些点变颜色 */
- // visualMap 是视觉映射组件,用于进行『视觉编码』,也就是将数据映射到视觉元素(视觉通道)
- let visualMap = {
- type: 'piecewise',// 定义为分段型
- show: false,
- dimension: 0,
- pieces: this.pieces
- }
- Object.assign(this, {
- line: {
- title: {
- text: this.title
- },
- visualMap: that.visualMap ? visualMap : { show: false },
- tooltip: {
- trigger: 'axis',
- // textStyle: {
- // color: '#0068FF'
- // },
- formatter: function (param) {
- return `${msec2str(Number(param[0].name), 'YYYY-MM-DD HH:mm:ss')}<br/>${param[0].value}`
- }
- },
- legend: {
- data: this.names
- },
- // 直角坐标系内绘图网格,单个 grid 内最多可以放置上下两个 X 轴,左右两个 Y 轴
- grid: {
- top: 40,
- bottom: 10,
- right: 25,
- left: 10,
- containLabel: true
- },
- xAxis: {
- data: this.xdata,
- type: 'category',
- axisTick: {
- alignWithLabel: true
- },
- axisLabel: {
- interval: that.xinterval || 59,
- showMaxLabel: true,
- formatter: function (value, idx) {
- // return idx === 0 ? msec2str(Number(value), 'YYYY-MM-DD') : msec2str(Number(value), 'MM-DD HH:mm')
- return msec2str(Number(value), that.xformatter || 'HH:00')
- }
- }
- },
- yAxis: {
- type: 'value'
- },
- series: series
- }
- })
- return {}
复制代码
画图也就不用我多说 (其实是我懒)
Dygraph
创建一个DOM容器(代码跟前面的基本类似)
- <div class="chart"></div>
复制代码
准备好配置文件
- plot () {
- // 有图就先删掉
- if (this.chart) {
- this.chart.destroy()
- this.chart = null
- }
- // 就是我们上面准备的容器
- this.chartEl.innerHTML = ''
- // 获取数据
- let data = await getData()
- if (data.values.length === 0) {
- this.chartEl.innerHTML = '<div class="chart-no-data">没有数据</div>'
- return
- }
- // 数据格式转换(不好意思 后端返的数据没法直接用 我先转换一下 各位看官可以跳过)
- let values = data.values.map(el => {
- let [a, b, c, , ...rest] = el
- return [a, b, c, ...rest]
- })
- let scoreValues = data.values.map(el => {
- // eslint-disable-next-line
- let [a, , , b, ...rest] = el
- return [a, b]
- })
- this.scoreValues = scoreValues
- // 上界和下界
- let lowers = []
- let uppers = []
- for (let v of values) {
- lowers.push([v[0], v[3]])
- uppers.push([v[0], v[4]])
- v[0] = msec2date(v[0])
- v[2] = v[2] ? v[1] : null
- }
- // tolerance update
- if (Object.keys(this.statistic).length > 0) {
- this.trimThreshold('upper', values, 4)
- this.trimThreshold('lower', values, 3)
- this.trimThreshold('upper', uppers, 1)
- this.trimThreshold('lower', lowers, 1)
- }
- // 样式指定
- let majorColor = '#136DFB'
- let minorColor = '#CCCCCC'
- let boundColor = '#408BFF'
- let anomalyColor = '#FF0000'
- let basebandColor = '#DCE9FE'
- let dylabels = [ 'x', '值', '异常' ]
- let series = {// 定义每系列选项。其键与y轴标签名称匹配,值是字典本身,包含特定于该系列的选项。
- '值': {
- color: majorColor,
- strokeWidth: 1,
- drawPoints: false
- },
- '异常': {
- color: anomalyColor,
- strokeWidth: 2,
- drawPoints: true,
- pointSize: 2,
- highlightCircleSize: 4
- },
- '分数': {
- color: majorColor,
- strokeWidth: 0,
- drawPoints: false,
- pointSize: 0,
- highlightCircleSize: 0
- }
- }
- dylabels = dylabels.concat([ '下界', '上界' ])
- series['上界'] = {
- color: boundColor,
- strokeWidth: 0,
- drawPoints: false,
- pointSize: 0,
- highlightCircleSize: 0
- }
- series['下界'] = {
- color: boundColor,
- strokeWidth: 0,
- drawPoints: false,
- pointSize: 0,
- highlightCircleSize: 0
- }
- // 是否填充
- if (this.filling) {
- let st = this.timerange.start
- if (dateLater(values[0][0], st)) {
- values.unshift([st, ...Array(values[0].length - 1).fill(null)])
- }
- let ed = this.timerange.end
- if (dateLater(ed, values[values.length - 1][0])) {
- values.push([ed, ...Array(values[0].length - 1).fill(null)])
- }
- }
- // 初始化dygraph
- this.chart = new Dygraph(this.chartEl, values, {
- labels: dylabels,//每个数据系列的名称,包括独立(X)系列
- connectSeparatedPoints: false,
- digitsAfterDecimal: 4,
- legend: 'follow',//何时显示图例。默认情况下,它仅在用户将鼠标悬停在图表上时显示
- interactionModel: Dygraph.defaultInteractionModel,
- labelsKMB: true,// 在y轴上显示千/千万/千亿的K / M / B.
- showRangeSelector: true,
- rangeSelectorHeight: 30,//范围选择器小部件的高度
- rangeSelectorPlotStrokeColor: majorColor,
- rangeSelectorPlotFillColor: minorColor,
- rangeSelectorPlotLineWidth: 1,
- rangeSelectorForegroundStrokeColor: minorColor,
- rangeSelectorForegroundLineWidth: 1,
- rangeSelectorBackgroundStrokeColor: minorColor,
- rangeSelectorBackgroundLineWidth: 1,
- axisLineColor: minorColor,
- gridLineColor: minorColor,
- series: series,
- axes: {//定义每轴选项
- x: {
- axisLabelFormatter: this.axisLabelFormatter
- },
- y: {
- axisLabelWidth: 35
- }
- },
- //设置后,每次用户通过鼠标悬停在图表外停止突出显示任何点时,都会调用此回调
- underlayCallback: (canvas, area, g) => {
- canvas.strokeStyle = basebandColor
- canvas.fillStyle = basebandColor
- let lowPoints = []
- let highPoints = []
- let drawBasebandBackgroundColor = () => {
- // 绘制基带 图中红色那一块
- // lowPoints对应下基带, hightPoints对应上基带
- // 至少有一边多于1个点才画: 才能画出线/区域
- if (lowPoints.length > 1 || highPoints.length > 1) {
- canvas.save()
- canvas.beginPath()
- if (lowPoints.length > 1) {
- canvas.moveTo(...lowPoints[0])
- // 从左到右
- for (let i = 1; i < lowPoints.length; i++) {
- canvas.lineTo(...lowPoints[i])
- }
- }
- if (highPoints.length > 1) {
- if (lowPoints.length > 1) {
- canvas.lineTo(...highPoints[highPoints.length - 1])
- } else {
- canvas.moveTo(...highPoints[highPoints.length - 1])
- }
- // 从右到左
- for (let i = highPoints.length - 2; i >= 0; i--) {
- canvas.lineTo(...highPoints[i])
- }
- if (lowPoints.length > 1) {
- canvas.lineTo(...lowPoints[0])
- }
- }
- // 如果可以形成区域, 就填充
- if (lowPoints.length > 1 && highPoints.length > 1) {
- canvas.closePath()
- canvas.fill()
- }
- canvas.stroke()
- canvas.restore()
- lowPoints = []
- highPoints = []
- }
- }
- for (let j = 0; j < uppers.length; j++) {
- // 基带数据发生以下情况的变化, 就画出当前待绘制的这一段
- if (
- (lowPoints.length === highPoints.length && lowPoints.length > 0 && (lowers[j][1] === null || uppers[j][1] === null)) || // 2 -> 1/0
- (lowPoints.length > 0 && highPoints.length === 0 && lowers[j][1] === null) || // 1 -> 0
- (lowPoints.length === 0 && highPoints.length > 0 && uppers[j][1] === null) || // 1 -> 0
- (lowPoints.length > 0 && highPoints.length === 0 && lowers[j][1] !== null && uppers[j][1] !== null) || // 1 -> 2
- (lowPoints.length === 0 && highPoints.length > 0 && lowers[j][1] !== null && uppers[j][1] !== null) // 1 -> 2
- ) {
- drawBasebandBackgroundColor()
- }
- let xx = 0
- if (lowers[j][1] !== null) {
- let x = g.toDomXCoord(lowers[j][0])
- let y = g.toDomYCoord(lowers[j][1])
- lowPoints.push([x, y])
- xx = x
- }
- if (uppers[j][1] !== null) {
- let x = g.toDomXCoord(uppers[j][0])
- let y = g.toDomYCoord(uppers[j][1])
- highPoints.push([x, y])
- xx = x
- }
- if (xx >= area.x + area.w) {
- break
- }
- }
- drawBasebandBackgroundColor()
- }
- })
- }
复制代码
开始画图
- this.chartEl = this.$el.getElementsByClassName('chart')[0]
- this.plot()
复制代码 |
|