思路:
将股票列表存入js文件,反复加载也不会重新请求,数据以json变量形式存储。
将股票代码和股票名称分为不同的key存储在json中。
通过判断输入的是不是数字,确定输入的是名称还是代码,使用json 对象的 filter函数进行模糊匹配,并返回匹配到的集合。
少量数据:
var gplist = [{"dm":"688322","mc":"N奥比-UW","jys":"sh"},{"dm":"301208","mc":"N中亦","jys":"sz"},{"dm":"688700","mc":"东威科技","jys":"sh"},{"dm":"300260","mc":"新莱应材","jys":"sz"},{"dm":"688071","mc":"华依科技","jys":"sh"}]
核心代码
//验证字符串是否是数字
function checkNumber(theObj) {
var reg = /^[0-9]+.?[0-9]*$/;
if (reg.test(theObj)) {
return true;
}
return false;
}
// 过滤数据
function filt(value){
var res = [];
if (checkNumber(value)) {
res = gplist.filter((param) => { return param.dm.match(new RegExp(value))})
}else{
res = gplist.filter((param) => { return param.mc.match(new RegExp(value))})
}
return res;
}
// 显示搜索下拉
function slt(value){
var selectcode = document.getElementById("selectcode");
selectcode.innerHTML = "";
// 替换空字符
value = value.replace(/\s+/g, "");
// 判断是否为空
if (value == "") {
return;
}
// 添加选项
filt(value).forEach(function(item){
var option = document.createElement("option");
option.value = item.jys+item.dm;
option.innerHTML = item.dm+"-"+item.mc;
selectcode.appendChild(option);
});
// 更新code
code = selectcode.value;
}
思路 :
设置好grid 参数,两张表 就是两个json对象,放到一个数组里面。
xAxis,yAxis,series,都有两个json对象,注意在 xAxis,yAxis第二组参数里面要加上gridIndex: 1
,
series第二组参数里面要加上 xAxisIndex: 1, yAxisIndex: 1
,下标从0开始,1表示第二张图表的参数,第一组可以省略。
关键代码:
option = {
backgroundColor: '#232C37',
//上半折线图下半柱状图
grid: [{
left: '7%',
right: '7%',
height: '60%',
bottom: '38%'
},
{
left: '7%',
right: '7%',
bottom: '15%',
height: '20%'
}
],
xAxis: [{
show:false,
type: 'category',
data: ["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",]
},{
show:false,
gridIndex: 1,
type: 'category',
data: ["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",]
}],
yAxis: [{
symbol: "none",
type: 'value',
},{
show:false,
gridIndex: 1,
splitNumber: 2,
}],
series: [
{
data: values,
type: 'line',
//省略。。。
},
{
name: '成交量',
type: 'bar',
xAxisIndex: 1,
yAxisIndex: 1,
data: cjl
},
]
};
return option;
思路:
在yAxis中添加一组数据,会自动添加到另一边y轴。
在axisLabel 里面设置textStyle的color,通过函数的形式,判读数据大小返回对应的颜色值,实现同轴不同色。
通过 axisLabel下面的formatter: '{value}%'
可以实现对值进行修饰,添加符号。
通过设置interval: 100000, showMinLabel: true,showMaxLabel: true
,分块的间隔值非常大之后,就只能分为一块了,再开启最大最小值的显示,就只会显示两个值。
核心代码:
yAxis: [{
symbol: "none",
type: 'value',
interval: 100000,
showMinLabel: true,
showMaxLabel: true,
min: (sp-df).toFixed(2),
max: Math.abs(-sp-df).toFixed(2),
splitLine:{
show:false //去掉网格线
},
axisLabel: {
textStyle: {
color: function (data) {
if (data >sp) {
return '#FF4A4A';
} else {
return '#3CC864';
}
}
}
},
},{
symbol: "none",
type: 'value',
interval: 100000,
showMinLabel: true,
showMaxLabel: true,
min: (df/sp*100).toFixed(2),
max: -(df/sp*100).toFixed(2),
axisLabel: {
show: true,
formatter: '{value}%' ,
textStyle: {
color: function (data) {
if (data >0) {
return '#FF4A4A';
} else {
return '#3CC864';
}
}
},
},
splitLine:{
show:false //去掉网格线
}
}
思路:
通过配置visualMap
达到不同颜色的效果。
首先对数据进行处理,通过对数据求差获得每分钟的涨幅数据,在通过对每分钟股价进行对比,获得涨跌标志。
数据格式:
cjl = [[0,123,1],[1,333,-1]]
数据处理核心代码:
var constres = [];
cjl.reduce((prev,next)=>{
if (constres.length==0) {
constres[constres.length] = Number(prev);
}
constres[constres.length]=Number(next)-Number(prev);
return next
});
cjl = constres.map(function (item,index,values) {
return [+index,+item, +((index==0? 0:values[index-1])<values[index] ? 1 : -1)];
});
visualMap说明:
seriesIndex
指定数据的id,这里是拼接柱状图,为第二组数据,下标从0开始所以为1.
dimension
标志位下标为2,对应数据中的1或者-1.
pieces
对应值的颜色
option = {
backgroundColor: '#232C37',//上半折线图下半柱状图
visualMap: {
show: false,
seriesIndex: 1,
dimension: 2,
pieces: [{
value: 1,
color: "#FF4A4A"
}, {
value: -1,
color: "#3CC864"
}]
},
}
思路:
在series对应的数据配置里面,配置markLine
参数,设置type 表示根据原有数据自适应均值线,最大最小值线。设置yAxis,表示自定义固定值。
核心代码:
series: [
{
data: values,
type: 'line',
symbol: "none",
itemStyle: {
color: "#fff",
},
markLine:{
/*以下设置一行后,平均线就没有开始和结束标记了(即看不见箭头了)*/
symbol:"none",
label:{
position:"start" //将警示值放在哪个位置,三个值“start”,"middle","end" 开始 中点 结束
},
data: [
{
name: '平均线',
// 支持 'average', 'min', 'max'
//type='average'
yAxis: sp,
lineStyle:{
normal:{
color:"#ffeb3b",
width:1,
type:"dotted",
}
}
},
]
},
},]
思路:
在series对应的数据配置里面,配置markPoint
参数,type设置为max,min,对应数据中的最大最小值。symbol为svg矢量路径形成的svg图标。
核心代码:
markPoint:{
data: [
{
type: 'max',
name: '最大值',
label: {
normal: {
position: 'top',
fontSize: 12,
distance: 7,
color: '#3ae70fed',
}
},
symbolOffset: ['0%', '-120%'],
symbol: 'path://M512 938.666667L262.4 640h499.2z M426.666667 128h170.666666v576h-170.666666z',
symbolSize: [15, 15],
itemStyle: {
normal: {
color: '#3ae70fed'
}
}
},
{
type: 'min',
name: '最小值',
label: {
normal: {
position: 'bottom',
fontSize: 12,
distance: 7,
color: '#f71a0adb',
}
},
symbolOffset: ['0%', '120%'],
symbol: 'path://M512 85.333333l249.6 298.666667H262.4z M426.666667 320h170.666666v576h-170.666666z',
symbolSize: [15, 15],
itemStyle: {
normal: {
color: '#f71a0adb'
}
}
},
]
}
通过设置tooltip
实现悬浮数据显示,通过设置axisPointer
实现多图合并同时显示悬浮数据。
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross'
},
backgroundColor: 'rgba(0, 0, 0,0.7)',
borderWidth: 1,
borderColor: '#000',
padding: 10,
textStyle: {
color: '#fff',
fontSize: 12,
}
},
axisPointer: {
link: {
xAxisIndex: 'all'
},
label: {
backgroundColor: '#777',
fontSize: 12,
}
},
通过设置tooltip中的formatter
,实现对显示样式的自定义。
核心代码:
...
formatter: function(param) {
// console.log(param)
let param2 = []
let barid = 0
let candlestickid = 0
for (var i = 0; i < param.length; i++) {
if (param[i].componentSubType == 'bar') {
barid = i
}
if (param[i].componentSubType == 'candlestick') {
candlestickid = i
}
}
param2 = param[barid];
param = param[candlestickid];
let zde = '';
let zdf = '';
// param = param[0];
if (param.dataIndex > 0 && oldParam.data) {
let oldspj = data.values[param.dataIndex - 1][1]
zde = parseFloat(param.data[2] - oldspj).toFixed(2)
// console.log(oldspj)
zdf = ((zde / oldspj) * 100).toFixed(2) + '%';
}
if (param.dataIndex < 1) {
param.dataIndex = 1
}
oldParam = { ...param
}
function priNum(n) {
if (n > 100000000) {
return (n / 100000000).toFixed(2) + '亿'
} else if (n > 10000) {
return (n / 10000).toFixed(2) + '万'
}else{
return n
}
}
return [
'日期: ' + param.name + '
',
'开盘:+ ((param.data[1] > data.values[param.dataIndex - 1][1]) ? '#FF4A4A' :
'#3CC864') + '">' + parseFloat(param.data[1]).toFixed(2) + '
',
'收盘: + ((param.data[2] > data.values[param.dataIndex - 1][2]) ? '#FF4A4A' :
'#3CC864') + '">' + parseFloat(param.data[2]).toFixed(2) + '
',
'最低: ' + parseFloat(param.data[3]).toFixed(2) + '
',
'最高: ' + parseFloat(param.data[4]).toFixed(2) + '
',
'成交量: + ((zde > 0) ? '#FF4A4A' : '#3CC864') + '">' + priNum(param2.data[1]) + '手
',
'涨跌额: + ((zde > 0) ? '#FF4A4A' : '#3CC864') + '">' + zde + '
',
'涨跌幅: + ((zde > 0) ? '#FF4A4A' : '#3CC864') + '">' + zdf + '
',
'换手率: ' + data.volumes[param.dataIndex][3] + '%
',
].join('');
}