Echarts4可视化,常用的一些功能:
折线图渐变、标示线(预警线)、浮层提示框轮播、滚动条(缩放组件)
直接上代码(看注释)
<div class="app" id="demo1"></div>
<div class="app" id="demo2"></div>
<script src="js/jquery.min.js"></script>
<script src="js/echarts.min.js"></script>
<script src="js/Chart.js"></script>
实例代码
var $chart1 = new Chart({
el: "#demo1",
legend: {
data: ['温度(℃)']
},
yAxis: {
max: function (obj) {
if (obj.max > 100) {
return obj.max;
} else {
return 100;
}
},
},
series: [{
name: '温度(℃)',
data: [],
markLine: {
data: [{
yAxis: 60,
label: {
show: 'true', position: 'end', formatter: '预警线'
},
lineStyle: {
normal: {width: 2, color: "#FF5D1D"}
}
}]
}
}],
});
var $chart2 = new Chart({
el: "#demo2",
legend: {data: ['烟雾浓度(%)']},
yAxis: {
max: function (obj) {
if (obj.max > 10) {
return obj.max;
} else {
return 10;
}
},
},
series: [{
name: '烟雾浓度(%)',
data: [],
markLine: {
data: [{
yAxis: 3,
label: {
show: 'true', position: 'end', formatter: '预警线'
},
lineStyle: {
normal: {width: 2, color: "#FF5D1D"}
}
}]
}
}]
});
function random(m, n) {
return Math.floor(Math.random() * (m - n) + n);
}
http_get_data();
// 模拟请求最新数据
// setInterval(http_get_data, 1000 * 10);
function http_get_data() {
$chart1.reset();
$chart2.reset();
var data = [
{type: 10, value: random(50, 80), happenTime: '2021-12-17'},
{type: 10, value: random(50, 80), happenTime: '2021-12-18'},
{type: 10, value: random(50, 80), happenTime: '2021-12-19'},
{type: 10, value: random(50, 80), happenTime: '2021-12-20'},
{type: 10, value: random(50, 80), happenTime: '2021-12-21'},
{type: 13, value: random(2, 7), happenTime: '2021-12-17'},
{type: 13, value: random(2, 7), happenTime: '2021-12-18'},
{type: 13, value: random(2, 7), happenTime: '2021-12-19'},
{type: 13, value: random(2, 7), happenTime: '2021-12-20'},
{type: 13, value: random(2, 7), happenTime: '2021-12-21'},
];
data.map(item => {
updateChart(item)
});
}
function updateChart(item) {
if (item.type === 10) {
$chart1.change(function (option) {
option.xAxis.data.push(item.happenTime);
option.series[0].data.push(item.value);
// 大于10条记录,显示滚动条
if (option.xAxis.data.length >= 10 && option.dataZoom.length === 0) {
$chart1.setDataZoom({start: 20, end: 100})
}
});
}
if (item.type === 13) {
$chart2.change(function (option) {
option.xAxis.data.push(item.happenTime);
option.series[0].data.push(item.value);
// 大于10条记录,显示滚动条
if (option.xAxis.data.length >= 10 && option.dataZoom.length === 0) {
$chart2.setDataZoom({start: 20, end: 100})
}
});
}
}
Chart.js代码
function Chart(options) {
try {
// echarts创建的实例
this.instance = echarts.init($(options.el).get(0));
} catch (e) {
console.info("未找到" + options.el + "的DOM");
this.instance = {
on: function () {
},
setOption: function () {
}
}
}
// 合并option
this.mergeOption(options);
// 监听x轴缩放条,下次更新时记录上次的滚动操作
this.listenZoomChange();
if (this.instance.getZr) {
// 定时器
this.timer = null;
// 循环显示浮层
this.loopTip(0);
this.instance.getZr().on('mouseover', (ev) => {
this.showTip(ev);
});
this.instance.getZr().on('mouseout', () => {
this.hideTip();
});
}
}
// 初始参数
Chart.prototype.baseOption = function () {
return {
title: {
text: "", // '电压变化情况(V)',
},
tooltip: {
trigger: 'axis',// item axis none
alwaysShowContent: true,
formatter: e => {
return e[0].name + '<br/>' + e[0].marker + e[0].value + '度';
},
textStyle: {
fontSize: 14,
},
axisPointer: {
lineStyle: {
color: "rgba(255,255,255,0.5)",
}
}
},
grid: {
top: 40,
left: '8%',
right: 50,
bottom: '5%',
containLabel: true
},
legend: {
show: true,
icon: 'stack', // stack circle emptyCircle triangle diamond rectangle
x: 'center',
y: 0,
itemWidth: 12,
itemHeight: 12,
data: [''],
textStyle: {
fontSize: 16,
color: '#EC5176'
}
},
dataZoom: [],
xAxis: {
data: [],
type: 'category',
boundaryGap: false,
axisLabel: {
// interval: 0,
// rotate: 20,
textStyle: {
color: '#333',
fontSize: 12
}
},
axisLine: {
lineStyle: {
color: '#DBDBDB'
}
}
},
yAxis: {
type: 'value',
nameGap: 35,
nameTextStyle: {
color: '#EC5176'
},
// max: 100,
axisLabel: {
textStyle: {
color: '#EC5176',
fontSize: 12
}
},
splitLine: {
lineStyle: {
color: '#DBDBDB',
type: 'dashed'
}
},
axisLine: {
show: false
},
axisTick: {
show: false
}
},
series: [
{
name: '',
type: 'line',
color: '#EC5176',
smooth: true,
symbolSize: 10,
data: [],
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0,
color: 'rgba(235, 81, 118, 0.3)'
}, {
offset: 1,
color: 'rgba(235, 81, 118,0)'
}],
globalCoord: false
}
}
}
]
}
};
// 获取最新的参数
Chart.prototype.getOption = function () {
return this.option;
};
// 合并option
Chart.prototype.mergeOption = function (options) {
const series = options.series;
delete options.series;
this.option = $.extend(this.baseOption(), options);
if (series) {
this.mergeSeries(series)
}
};
// 合并series
Chart.prototype.mergeSeries = function (newSeries) {
if (newSeries.length === 1) {
$.extend(this.option.series[0], newSeries[0]);
return;
}
this.option.series = newSeries;
};
// 监听滚动条
Chart.prototype.listenZoomChange = function () {
if (!this.instance) return;
this.instance.on('dataZoom', (event) => {
if (this.option.dataZoom.length === 0) return;
if (event.batch) {
this.option.dataZoom[0].start = event.batch[0].start;
this.option.dataZoom[0].end = event.batch[0].end;
} else {
this.option.dataZoom[0].start = event.start;
this.option.dataZoom[0].end = event.end;
}
});
};
// 更新数据
Chart.prototype.change = function (callback) {
if (!this.instance || !this.option) return;
callback(this.option);
// echarts的setOption是非常耗时的同步任务。
// 放到[宏任务]队列中等[微任务]执行完毕再执行,防止在循环调用时出现阻塞问题
setTimeout(this.render.bind(this))
};
// 重置
Chart.prototype.reset = function () {
if (!this.instance) return;
this.change(function (option) {
option.xAxis.data = [];
option.series[0].data = [];
option.dataZoom = [];
});
};
// 滚动条
Chart.prototype.setDataZoom = function (options) {
if (!this.instance) return;
this.option.dataZoom = [{
realtime: true,
type: 'slider', // 图表下方的伸缩条
start: options.start,
end: options.end
}, {
type: 'inside', // 鼠标滚轮
realtime: true
}];
};
// 渲染
Chart.prototype.render = function () {
if (!this.instance) return;
var option = this.getOption();
this.instance.setOption(option)
};
// 隐藏浮层(鼠标事件)
Chart.prototype.hideTip = function () {
if (!this.instance) return;
var option = this.getOption();
if (option.tooltip) {
option.tooltip.alwaysShowContent = false;
option.tooltip.triggerOn = "mousemove";
}
this.instance.setOption(option, true);
this.instance.dispatchAction({type: 'hideTip'});
}
// 显示浮层(鼠标事件)
Chart.prototype.showTip = function (ev) {
if (!this.instance) return;
var option = this.getOption();
if (option.tooltip) {
option.tooltip.alwaysShowContent = true;
option.tooltip.triggerOn = "none";
}
var pointInPixel = [ev.offsetX, ev.offsetY];
var pointInGrid = this.instance.convertFromPixel({seriesIndex: 0}, pointInPixel);
this.instance.setOption(option, true);
this.instance.dispatchAction({
type: 'showTip',
seriesIndex: 0,
dataIndex: pointInGrid[0]
});
}
// 显示浮层(自动循环)
Chart.prototype.loopTip = function (index = 0) {
if (!this.instance) return;
clearInterval(this.timer);
this.timer = setInterval(() => {
var option = this.getOption();
var series = option.series;
if (option.tooltip) {
option.tooltip.alwaysShowContent = true;
option.tooltip.triggerOn = "none";
} else {
clearInterval(this.timer);
}
index = index >= series[0].data.length ? 0 : index;
this.instance.setOption(option, true);
this.instance.dispatchAction({
type: 'showTip',
seriesIndex: 0,
dataIndex: index
});
index++;
}, 2000);
}