此处利用bootstrap+echarts画布配置参数实现响应式,并且利用socket实时通信实现数据的实时更新
(一)介绍
- ECharts (Enterprise Charts 商业产品图表库)
- ECharts开源来自百度商业前端数据可视化团队,基于html5 Canvas,是一个纯Javascript
图表库,提供直观,生动,可交互,可个性化定制的数据可视化图表。创新的拖拽重计算、数据视图、值域漫游等特性大大增强了用户体验,赋予了用户对数据进行挖掘、整合的能力。 提供商业产品常用图表,底层基于ZRender - (一个全新的轻量级canvas类库),创建了坐标系,图例,提示,工具箱等基础组件,并在此上构建出折线图(区域图)、柱状图(条状图)、散点图(气泡图)、饼图(环形图)、K
线图、地图、力导向布局图以及和弦图, - 同时支持任意维度的堆积和多图表混合展现。 优势:拖拽重计算,大规模数据模式直角系图表(折、柱、散点、K线)
- 20万数据秒级出图,拥有值域漫游的功能,让你可以轻松进行数值筛选。
(二)使用
一、插件的下载(echarts+bootstrap)
-
echarts
地址:http://echarts.baidu.com/download.html
或者使用npm拉取:npm install echarts --save
详情查看官网手册:http://echarts.baidu.com/tutorial.html#%E5%9C%A8%20webpack%20%E4%B8%AD%E4%BD%BF%E7%94%A8%20ECharts
bootstrap
地址:http://v3.bootcss.com/getting-started/#download
二、引入echarts+bootstrap+socket.io
-
echarts
只需要像普通的 JavaScript 库一样用 script 标签引入。
代码如下:
-
bootstrap
我这里设置的啦ravel路径,根据自己情况,自行设置
socket.io
三、绘制一个简单的图表
-
在绘图前我们需要为 ECharts 准备一个具备高宽的 DOM 容器。
body里设置一个div放置画布使用
代码如下:
-
通过 echarts.init 方法初始化一个 echarts 实例并通过 setOption 方法生成一个简单的图
官网完整简单实例代码。
ECharts 我的初始化
> 因为使用了模板继承,将html头部和画布的div初始化到了一个模板中,代码如下
文件名:'zoushi.blade.com'
Starter Template for Bootstrap
< 一下代码均在js中实现
1. K线图(需要的数据有:开盘价,闭盘价,最高价,最低价,时间)
1. 获取dom节点初始化
var dom = document.getElementById("container");
var myChart = echarts.init(dom);
var app = {};
option = null;
app.title = '2015 年上证指数';
var limit=50;
function calculateMA(dayCount, data) {
var result = [];
for (var i = 0, len = data.length; i < len; i++) {
if (i < dayCount) {
result.push('-');
continue;
}
var sum = 0;
for (var j = 0; j < dayCount; j++) {
sum += data[i - j][1];
}
result.push(sum / dayCount);
}
return result;
}
var data=[['4654','6485','5456','6684']];
var dates=['122/12/4'];
require.config({
paths: {
echarts: 'http://echarts.baidu.com/build/dist'
}
});
2. 设置K线图的画布配置参数//详情见代码注释
require(
[
'echarts',
'echarts/chart/bar',// 使用柱状图就加载bar模块,按需加载
'echarts/chart/line',
'echarts/chart/k',
],
function (ec) {
// 基于准备好的dom,初始化echarts图表
var option = {
backgroundColor: '#21202D',
legend: {
data: ['日K', 'MA5', 'MA10', 'MA20', 'MA30'],
inactiveColor: '#777',
textStyle: {
color: '#fff'
}
},
tooltip: {
trigger: 'axis',
axisPointer: {
animation: false,
lineStyle: {
color: '#376df4',
width: 2,
opacity: 1
}
}
},
toolbox: {
show: true,
feature: {
dataZoom: {
yAxisIndex: 'none'
},
dataView: {readOnly: false},
magicType: {type: ['line', 'bar']},
restore: {},
saveAsImage: {}
}
},
xAxis: {
type: 'category',
data: dates,
axisLine: { lineStyle: { color: '#8392A5' } }
},
yAxis: {
min:'100%',
scale: true,
axisLine: { lineStyle: { color: '#8392A5' } },
splitLine: { show: false }
},
dataZoom: [{
textStyle: {
color: '#8392A5'
},
handleIcon: 'M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4v1.3h1.3v-1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7V23h6.6V24.4z M13.3,19.6H6.7v-1.4h6.6V19.6z',
handleSize: '80%',
dataBackground: {
areaStyle: {
color: '#8392A5'
},
lineStyle: {
opacity: 0.8,
color: '#8392A5'
}
},
handleStyle: {
color: '#fff',
shadowBlur: 3,
shadowColor: 'rgba(0, 0, 0, 0.6)',
shadowOffsetX: 2,
shadowOffsetY: 2
}
}, {
type: 'inside'
}],
animation: false,
series: [
{
type: 'candlestick',
name: '日K',
data: data,
markLine: {
symbol: ['none', 'none'],
symbolOffset:[0, '50%'],
data : [
[
{name: '标线2起点', value: data[data.length-1][1], x: '100%', yAxis: data[data.length-1][1]},
{name: '标线2终点', x: '10%', yAxis: data[data.length-1][1]}
]
]
},
itemStyle: {
normal: {
color: '#FD1050',
color0: '#0CF49B',
borderColor: '#FD1050',
borderColor0: '#0CF49B'
}
}
},
{
name: 'MA5',
type: 'line',
data: calculateMA(5, data),
smooth: true,
showSymbol: false,
lineStyle: {
normal: {
width: 1
}
}
},
{
name: 'MA10',
type: 'line',
data: calculateMA(10, data),
smooth: true,
showSymbol: false,
lineStyle: {
normal: {
width: 1
}
}
},
{
name: 'MA20',
type: 'line',
data: calculateMA(20, data),
smooth: true,
showSymbol: false,
lineStyle: {
normal: {
width: 1
}
}
},
{
name: 'MA30',
type: 'line',
data: calculateMA(30, data),
smooth: true,
showSymbol: false,
lineStyle: {
normal: {
width: 1
}
}
}
]
};
// 为echarts对象加载数据
myChart.setOption(option);
}
);
3. 写实时刷新需要改变的参数,封装为刷新函数//详情见代码注释
function refreshData(){
if(!myChart){
return;
}
//更新数据
var option = myChart.getOption();
option.series[0].data = data;
option.xAxis[0].dates = dates;
option.series[0].markLine.data[0][0].value=data[data.length-1][1];
option.series[0].markLine.data[0][0].yAxis=data[data.length-1][1];
option.series[0].markLine.data[0][1].value=data[data.length-1][1];
option.series[0].markLine.data[0][1].yAxis=data[data.length-1][1];
option.series[1].data=calculateMA(5, data);
option.series[2].data=calculateMA(10, data);
option.series[3].data=calculateMA(20, data);
option.series[4].data=calculateMA(30, data);
myChart.setOption(option);
console.log(data[data.length-1])
}
4. 利用socket通信,实时监听数据的到来
var socket = io('http://192.168.100.121:6002');
socket.on('connection', function (data) {
console.log(data);
});
socket.on('zxz:App\\Events\\Push', function(message){
window.onresize = myChart.resize;
if(message.open==data[data.length-1][0])
{
data[data.length-1][1]=message.close;
data[data.length-1][2]=message.max;
data[data.length-1][3]=message.min;
refreshData();
}else{
data.push([message.open,message.close,message.max,message.min]);
dates.push(message.time);
console.log(data.length+"----"+dates.length);
if(data.length==limit)
{
data.shift();
dates.shift();
refreshData();
}else{
refreshData();
}
}
});
2. 折线图(需要的数据有:闭盘价,时间)
1. 获取dom节点初始化
var dom = document.getElementById("container");
var myChart = echarts.init(dom);
var app = {};
option = null;
app.title = '2015 年上证指数';
var limit = 50;
function calculateMA(dayCount, data) {
var result = [];
for (var i = 0, len = data.length; i < len; i++) {
if (i < dayCount) {
result.push('-');
continue;
}
var sum = 0;
for (var j = 0; j < dayCount; j++) {
sum += data[i - j];
}
result.push(sum / dayCount);
}
return result;
}
var data = ['4654'];
var dates = ['122/12/4'];
require.config({
paths: {
echarts: 'http://echarts.baidu.com/build/dist'
}
});
2. 设置折线图的画布配置参数+画布响应式//详情见代码注释
require(
[
'echarts',
'echarts/chart/line'
],
function (ec) {
// 基于准备好的dom,初始化echarts图表
var option = {
baseOption:{
backgroundColor: '#21202D',
legend: {
data: ['折线', 'MA5', 'MA10', 'MA20', 'MA30'],
inactiveColor: '#777',
textStyle: {
color: '#fff'
}
},
tooltip: {
trigger: 'axis',
axisPointer: {
animation: false,
lineStyle: {
color: '#376df4',
width: 2,
opacity: 1
}
}
},
toolbox: {
show: true,
feature: {
dataZoom: {
yAxisIndex: 'none'
},
dataView: {readOnly: false},
magicType: {type: ['line', 'bar']},
restore: {},
saveAsImage: {}
}
},
xAxis: {
type: 'category',
data: dates,
axisLine: {lineStyle: {color: '#8392A5'}}
},
yAxis: {
position:'right',
scale: true,
axisLine: {lineStyle: {color: '#8392A5'}},
splitLine: {show: false}
},
dataZoom: [{
textStyle: {
color: '#8392A5'
},
handleIcon: 'M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4v1.3h1.3v-1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7V23h6.6V24.4z M13.3,19.6H6.7v-1.4h6.6V19.6z',
handleSize: '80%',
dataBackground: {
areaStyle: {
color: '#8392A5'
},
lineStyle: {
opacity: 0.8,
color: '#8392A5'
}
},
handleStyle: {
color: '#fff',
shadowBlur: 3,
shadowColor: 'rgba(0, 0, 0, 0.6)',
shadowOffsetX: 2,
shadowOffsetY: 2
}
}, {
type: 'inside',
show: false
}],
animation: false,
series: [
{
type: 'line',
name: '日K',
data: data,
showSymbol: false,
hoverAnimation: false,
data: data,
markLine: {
symbol: ['none', 'none'],
symbolOffset:[0, '50%'],
data : [
[
{name: '标线2起点', value: data[data.length-1], x: 100, yAxis: data[data.length-1]},
{name: '标线2终点', x: '90%', yAxis: data[data.length-1]}
]
]
}
},
{
name: 'MA5',
type: 'line',
data: calculateMA(5, data),
smooth: true,
showSymbol: false,
lineStyle: {
normal: {
width: 1
}
}
},
{
name: 'MA10',
type: 'line',
data: calculateMA(10, data),
smooth: true,
showSymbol: false,
lineStyle: {
normal: {
width: 1
}
}
},
{
name: 'MA20',
type: 'line',
data: calculateMA(20, data),
smooth: true,
showSymbol: false,
lineStyle: {
normal: {
width: 1
}
}
},
{
name: 'MA30',
type: 'line',
data: calculateMA(30, data),
smooth: true,
showSymbol: false,
lineStyle: {
normal: {
width: 1
}
}
}
]
},
media:[{
query:{
maxWidth:500
},
option:{
legend: {
data: ['日K'],
inactiveColor: '#777',
textStyle: {
color: '#fff'
}
},
toolbox: {
show: false
},
series: [
{
name: 'MA5',
showSymbol: false,
hoverAnimation: false,
data: data
},
{
name: 'MA10',
showSymbol: false,
hoverAnimation: false,
data: data
},
{
name: 'MA20',
showSymbol: false,
hoverAnimation: false,
data: data
},
{
name: 'MA30',
showSymbol: false,
hoverAnimation: false,
data: data
}
],
dataZoom: [{show:false}]
}
}
]
};
// 为echarts对象加载数据
window.onresize = myChart.resize;
myChart.setOption(option);
}
);
3. 写实时刷新需要改变的参数,封装为刷新函数//详情见代码注释
function refreshData() {
if (!myChart) {
return;
}
//更新数据
var option = myChart.getOption();
option.series[0].data = data;
option.xAxis[0].dates = dates;
option.series[1].data = calculateMA(5, data);
option.series[2].data = calculateMA(10, data);
option.series[3].data = calculateMA(20, data);
option.series[4].data = calculateMA(30, data);
option.series[0].markLine.data[0][0].value=data[data.length-1];
option.series[0].markLine.data[0][0].yAxis=data[data.length-1];
option.series[0].markLine.data[0][1].value=data[data.length-1];
option.series[0].markLine.data[0][1].yAxis=data[data.length-1];
myChart.setOption(option);
}
4. 利用socket通信,实时监听数据的到来
var socket = io('http://192.168.100.121:6002');
socket.on('connection', function (data) {
console.log(data);
});
socket.on('zxz:App\\Events\\Push', function (message) {
window.onresize = myChart.resize;
if (message.open == open) {
} else {
data.push(message.open);
dates.push(message.time);
open = message.open;
console.log(data.length);
if (data.length == limit) {
data.shift();
dates.shift();
refreshData();
} else {
refreshData();
}
}
});