2 changed files with 559 additions and 0 deletions
@ -0,0 +1,553 @@ |
|||||
|
<template> |
||||
|
<div ref="bottomRadarRef" id="bottomRadarChart"></div> |
||||
|
</template> |
||||
|
|
||||
|
<script setup> |
||||
|
import { ref } from 'vue' |
||||
|
import * as echarts from 'echarts' |
||||
|
const bottomRadarRef = ref(null) |
||||
|
function initEmotionalBottomRadar(KlineData, barAndLineData) { |
||||
|
console.log('KlineData, barAndLineData---', KlineData, barAndLineData) |
||||
|
let bottomRadarChartDom = document.getElementById('bottomRadarChart') |
||||
|
let bottomRadarChart = echarts.init(bottomRadarChartDom) |
||||
|
|
||||
|
// 日期-作为x轴 |
||||
|
let dateArray = KlineData.map(subArray => subArray[0]) |
||||
|
// k线,取前四个即可 |
||||
|
let kLineDataArray = KlineData.map(subArray => subArray.slice(1, 5)) |
||||
|
// 红线,取第二个值 |
||||
|
let redLineDataArray = barAndLineData.map(subArray => subArray[1]) |
||||
|
// 色块数据格式化 |
||||
|
let barTotalDataArray = barAndLineData.map(subArray => subArray.slice(2, 6)) |
||||
|
// 删掉 |
||||
|
// barTotalDataArray[0] = [0, 0, 0, 0] |
||||
|
// barTotalDataArray[8] = [1, 1, 1, 1] |
||||
|
// barTotalDataArray[9] = [0, 0, 1, 1] |
||||
|
// barTotalDataArray[13] = [1, 0, 1, 0] |
||||
|
// barTotalDataArray[16] = [0, 0, 1, 0] |
||||
|
// 黄色块、黄色加仓资金、紫色柱子、蓝色柱子 |
||||
|
let yellowBlockDataArray = [] |
||||
|
let yellowLineDataArray = [] |
||||
|
let purpleLineDataArray = [] |
||||
|
let blueLineDataArray = [] |
||||
|
let transparentFillingDataArray = [] |
||||
|
// 黄色块:为1 0-4显示柱体 |
||||
|
// 黄色加仓资金文字:为1 在4的位置展示文字 |
||||
|
// 紫色柱子:为1 1-80显示柱体 |
||||
|
// 蓝色柱子:为1 0-40显示柱体 |
||||
|
// 因数据要互相叠加展示,所以需要数据处理。base适用于 ECharts 4.x 及以上版本 |
||||
|
barTotalDataArray.forEach((item) => { |
||||
|
if (item[0]) { |
||||
|
yellowBlockDataArray.push(4) |
||||
|
if (item[3]) { |
||||
|
// 40-4 |
||||
|
blueLineDataArray.push(36) |
||||
|
if (item[2]) { |
||||
|
// 80-40 |
||||
|
purpleLineDataArray.push(40) |
||||
|
transparentFillingDataArray.push(0) |
||||
|
} else { |
||||
|
purpleLineDataArray.push(0) |
||||
|
transparentFillingDataArray.push(0) |
||||
|
} |
||||
|
} else { |
||||
|
blueLineDataArray.push(0) |
||||
|
if (item[2]) { |
||||
|
// 80-4 |
||||
|
purpleLineDataArray.push(76) |
||||
|
transparentFillingDataArray.push(0) |
||||
|
} else { |
||||
|
purpleLineDataArray.push(0) |
||||
|
transparentFillingDataArray.push(0) |
||||
|
} |
||||
|
} |
||||
|
} else if (!item[0]) { |
||||
|
yellowBlockDataArray.push(0) |
||||
|
if (item[3]) { |
||||
|
blueLineDataArray.push(40) |
||||
|
if (item[2]) { |
||||
|
// 80-40 |
||||
|
purpleLineDataArray.push(40) |
||||
|
transparentFillingDataArray.push(0) |
||||
|
} else { |
||||
|
purpleLineDataArray.push(0) |
||||
|
transparentFillingDataArray.push(0) |
||||
|
} |
||||
|
} else { |
||||
|
blueLineDataArray.push(0) |
||||
|
if (item[2]) { |
||||
|
// 80-1,base为1 |
||||
|
purpleLineDataArray.push(79) |
||||
|
transparentFillingDataArray.push(1) |
||||
|
} else { |
||||
|
purpleLineDataArray.push(0) |
||||
|
transparentFillingDataArray.push(0) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
// 加仓资金 |
||||
|
if (item[1]) { |
||||
|
yellowLineDataArray.push(1) |
||||
|
} else if (!item[1]) { |
||||
|
yellowLineDataArray.push(0) |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
// 配置图表选项,很多操作和展示已限制,如果需要需放开 |
||||
|
let option = { |
||||
|
// backgroundColor: '#000046', // 设置整个图表的背景色 |
||||
|
tooltip: { |
||||
|
show: false, // 不展示tip |
||||
|
// 当前echart版本十字准星独立渲染了; 4.x+才有showAxisPointer |
||||
|
trigger: 'axis', |
||||
|
axisPointer: { |
||||
|
type: 'cross', |
||||
|
crossStyle: { |
||||
|
color: '#999' |
||||
|
} |
||||
|
}, |
||||
|
backgroundColor: 'rgba(255, 255, 255, 0.8)', |
||||
|
borderColor: '#ccc', |
||||
|
borderWidth: 1, |
||||
|
padding: 10, |
||||
|
textStyle: { |
||||
|
color: '#333' |
||||
|
}, |
||||
|
formatter: function (params) { |
||||
|
let result = `<div style="font-weight: bold;">${params[0].name}</div>` |
||||
|
|
||||
|
params.forEach(param => { |
||||
|
let value = param.value |
||||
|
let color = param.color |
||||
|
|
||||
|
if (param.seriesType === 'candlestick') { |
||||
|
result += `<div style="color: ${color}"><i class="fa fa-square mr-1"></i>${param.seriesName}: 开 ${value[0]}, 收 ${value[1]}, 低 ${value[2]}, 高 ${value[3]}</div>` |
||||
|
} else { |
||||
|
result += `<div style="color: ${color}"><i class="fa fa-square mr-1"></i>${param.seriesName}: ${value}</div>` |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
return result |
||||
|
} |
||||
|
}, |
||||
|
legend: { |
||||
|
// data: ['K线', '红线', '色块'], 不要展示图例 |
||||
|
type: 'scroll', |
||||
|
pageButtonItemGap: 2, |
||||
|
pageButtonPosition: 'end', |
||||
|
textStyle: { |
||||
|
color: '#666' |
||||
|
} |
||||
|
}, |
||||
|
grid: [ |
||||
|
{ |
||||
|
left: '3%', |
||||
|
right: '3%', |
||||
|
top: '20px', |
||||
|
bottom: '50%', |
||||
|
height: '300px', |
||||
|
// containLabel: true |
||||
|
}, |
||||
|
{ |
||||
|
left: '3%', |
||||
|
right: '3%', |
||||
|
top: '320px', |
||||
|
bottom: '25%', |
||||
|
height: '300px', |
||||
|
// containLabel: true |
||||
|
}, |
||||
|
{ |
||||
|
left: '3%', |
||||
|
right: '3%', |
||||
|
top: '620px', |
||||
|
bottom: '50px', |
||||
|
height: '300px', |
||||
|
// containLabel: true |
||||
|
} |
||||
|
], |
||||
|
xAxis: [ |
||||
|
{ |
||||
|
type: 'category', |
||||
|
data: dateArray, |
||||
|
gridIndex: 0, |
||||
|
boundaryGap: true, // 保持间距,不要离y轴太近,不然重叠了 |
||||
|
axisLine: { |
||||
|
// show: false, |
||||
|
lineStyle: { |
||||
|
color: '#837b7b', // x轴线颜色 |
||||
|
} |
||||
|
}, |
||||
|
axisTick: { |
||||
|
show: false |
||||
|
}, |
||||
|
axisLabel: { |
||||
|
show: false |
||||
|
}, |
||||
|
splitLine: { |
||||
|
show: false // 不要x轴的分割线 |
||||
|
}, |
||||
|
axisPointer: { |
||||
|
link: { |
||||
|
xAxisIndex: 'all' |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
type: 'category', |
||||
|
data: dateArray, |
||||
|
gridIndex: 1, |
||||
|
boundaryGap: true, |
||||
|
axisLine: { |
||||
|
// show: false, |
||||
|
lineStyle: { |
||||
|
// color: '#008000' |
||||
|
color: '#837b7b' |
||||
|
} |
||||
|
}, |
||||
|
axisTick: { |
||||
|
show: false |
||||
|
}, |
||||
|
axisLabel: { |
||||
|
show: false |
||||
|
}, |
||||
|
splitLine: { |
||||
|
show: false |
||||
|
}, |
||||
|
axisPointer: { |
||||
|
link: { |
||||
|
xAxisIndex: 'all' |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
type: 'category', |
||||
|
data: dateArray, |
||||
|
gridIndex: 2, |
||||
|
axisLine: { |
||||
|
lineStyle: { |
||||
|
color: '#837b7b' |
||||
|
} |
||||
|
}, |
||||
|
axisTick: { |
||||
|
show: true, // 显示刻度线 |
||||
|
alignWithLabel: true, |
||||
|
lineStyle: { |
||||
|
color: '#999', // 颜色 |
||||
|
width: 1, // 宽度 |
||||
|
type: 'solid' // 线样式(solid/dashed/dotted) |
||||
|
} |
||||
|
}, |
||||
|
axisLabel: { |
||||
|
color: '#000000', |
||||
|
interval: 'auto', |
||||
|
rotate: 45 |
||||
|
}, |
||||
|
splitLine: { |
||||
|
show: false |
||||
|
}, |
||||
|
axisPointer: { |
||||
|
link: { |
||||
|
xAxisIndex: 'all' |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
], |
||||
|
yAxis: [ |
||||
|
{ |
||||
|
type: 'value', |
||||
|
gridIndex: 0, |
||||
|
splitNumber: 4, |
||||
|
axisLine: { |
||||
|
lineStyle: { |
||||
|
color: '#837b7b' // y轴坐标轴颜色 |
||||
|
} |
||||
|
}, |
||||
|
axisTick: { |
||||
|
show: true |
||||
|
}, |
||||
|
axisLabel: { |
||||
|
width: 50, // 宽度限制 |
||||
|
color: '#000000', |
||||
|
formatter: function (value, index) { |
||||
|
if (index === 0) { |
||||
|
return '0' |
||||
|
} |
||||
|
return value.toFixed(2) |
||||
|
} |
||||
|
}, |
||||
|
splitLine: { |
||||
|
show: false, |
||||
|
lineStyle: { |
||||
|
color: '#837b7b', |
||||
|
type: 'dotted' // 设置网格线类型 dotted:虚线 solid:实线 |
||||
|
} |
||||
|
}, |
||||
|
// min: 4, |
||||
|
scale: true, // 不强制包含0,不然k线图底部空余太多 |
||||
|
}, |
||||
|
{ |
||||
|
type: 'value', |
||||
|
gridIndex: 1, |
||||
|
splitNumber: 3, |
||||
|
axisLine: { |
||||
|
lineStyle: { |
||||
|
color: '#837b7b' |
||||
|
} |
||||
|
}, |
||||
|
axisTick: { |
||||
|
show: true |
||||
|
}, |
||||
|
splitNumber: 5, // 刻度数量 |
||||
|
axisLabel: { |
||||
|
width: 50, // 宽度限制 |
||||
|
color: '#000000', |
||||
|
formatter: function(value, index) { |
||||
|
// 如果没有刻度数量,其他方法获取不到y轴刻度总长 |
||||
|
if (index === 0) { |
||||
|
return '0' |
||||
|
} else if (index === 5) { |
||||
|
return '' |
||||
|
} |
||||
|
return value |
||||
|
} |
||||
|
}, |
||||
|
splitLine: { |
||||
|
show: false, |
||||
|
lineStyle: { |
||||
|
color: '#837b7b', |
||||
|
type: 'dotted' |
||||
|
} |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
type: 'value', |
||||
|
gridIndex: 2, |
||||
|
splitNumber: 2, |
||||
|
axisLine: { |
||||
|
lineStyle: { |
||||
|
color: '#837b7b' |
||||
|
} |
||||
|
}, |
||||
|
axisTick: { |
||||
|
show: true |
||||
|
}, |
||||
|
splitNumber: 5, // 刻度数量 |
||||
|
axisLabel: { |
||||
|
width: 50, // 宽度限制 |
||||
|
color: '#000000', |
||||
|
formatter: function(value, index) { |
||||
|
if (index === 5) { |
||||
|
return '' |
||||
|
} |
||||
|
return value |
||||
|
} |
||||
|
}, |
||||
|
splitLine: { |
||||
|
show: false, |
||||
|
lineStyle: { |
||||
|
color: '#837b7b', |
||||
|
type: 'dotted' // 设置网格线类型 dotted:虚线 solid:实线 |
||||
|
} |
||||
|
}, |
||||
|
splitNumber: 5, |
||||
|
min: function(value) { |
||||
|
return 0 // 最小值 |
||||
|
}, |
||||
|
max: function(value) { |
||||
|
return value.max + 10 // 比最大值高10, 避免最高点和上一个图表x轴重合 |
||||
|
} |
||||
|
} |
||||
|
], |
||||
|
dataZoom: [ |
||||
|
{ |
||||
|
type: 'slider', |
||||
|
xAxisIndex: [0, 2], |
||||
|
// start: 80, |
||||
|
// end: 100, |
||||
|
show: false |
||||
|
}, |
||||
|
{ |
||||
|
type: 'slider', |
||||
|
xAxisIndex: [0, 2], |
||||
|
// start: 80, |
||||
|
// end: 100, |
||||
|
show: false |
||||
|
}, |
||||
|
{ |
||||
|
type: 'slider', |
||||
|
xAxisIndex: [0, 2], |
||||
|
// 一次性全部 or 后20% |
||||
|
// start: 80, |
||||
|
// end: 100, |
||||
|
show: false, // 先不显示 |
||||
|
borderColor: '#CFD6E3', |
||||
|
dataBackground: { |
||||
|
// 线 |
||||
|
lineStyle: { |
||||
|
color: '#CFD6E3' |
||||
|
}, |
||||
|
// 阴影 |
||||
|
areaStyle: { |
||||
|
color: 'rgba(241,243,247,0.5)' |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
], |
||||
|
series: [ |
||||
|
{ |
||||
|
name: 'K线', |
||||
|
type: 'candlestick', |
||||
|
data: kLineDataArray, |
||||
|
xAxisIndex: 0, |
||||
|
yAxisIndex: 0, |
||||
|
itemStyle: { |
||||
|
color: '#ef232a', // 上涨颜色 (红) |
||||
|
color0: '#14b143', // 下跌颜色 (绿) |
||||
|
borderColor: '#ef232a', |
||||
|
borderColor0: '#14b143', |
||||
|
normal: { |
||||
|
color: '#ef232a', // 上涨颜色 (红) |
||||
|
color0: '#14b143', // 下跌颜色 (绿) |
||||
|
borderColor: '#ef232a', |
||||
|
borderColor0: '#14b143', |
||||
|
opacity: function(params) { |
||||
|
// 收盘价 > 开盘价时为阳线,设置边框不透明、填充透明 |
||||
|
return params.data[2] > params.data[1] ? 0 : 1 |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
name: '红线', |
||||
|
type: 'line', |
||||
|
data: redLineDataArray, |
||||
|
xAxisIndex: 1, |
||||
|
yAxisIndex: 1, |
||||
|
symbol: 'none', |
||||
|
sampling: 'average', |
||||
|
itemStyle: { |
||||
|
normal: { |
||||
|
color: '#ef232a' |
||||
|
} |
||||
|
}, |
||||
|
areaStyle: { |
||||
|
color: { |
||||
|
type: 'linear', |
||||
|
x: 0, |
||||
|
y: 0, |
||||
|
x2: 0, |
||||
|
y2: 1, |
||||
|
colorStops: [ |
||||
|
{ offset: 0, color: 'rgba(33, 150, 243, 0.4)' }, |
||||
|
{ offset: 1, color: 'rgba(33, 150, 243, 0)' } |
||||
|
] |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
name: '基础base', |
||||
|
type: 'bar', |
||||
|
stack: 'total', |
||||
|
// barGap: '-100%', // 重叠 |
||||
|
xAxisIndex: 2, |
||||
|
yAxisIndex: 2, |
||||
|
barCategoryGap: '0%', |
||||
|
itemStyle: { |
||||
|
normal: { |
||||
|
color: '#ffffff', |
||||
|
borderWidth: 0, |
||||
|
} |
||||
|
}, |
||||
|
data: transparentFillingDataArray, |
||||
|
}, |
||||
|
{ |
||||
|
name: '黄色块', |
||||
|
type: 'bar', |
||||
|
stack: 'total', |
||||
|
// barGap: '-100%', // 重叠 |
||||
|
xAxisIndex: 2, |
||||
|
yAxisIndex: 2, |
||||
|
barCategoryGap: '0%', // 类目间柱条间距为0 |
||||
|
itemStyle: { |
||||
|
normal: { |
||||
|
color: 'rgba(255, 255, 0, 1)', |
||||
|
borderWidth: 0, |
||||
|
// 加仓资金的文字显示 |
||||
|
label: { |
||||
|
show: (params) => { |
||||
|
return yellowLineDataArray[params.dataIndex] > 0 |
||||
|
}, |
||||
|
position: 'top', |
||||
|
textStyle: { |
||||
|
color: 'rgba(255, 255, 0, 1)' |
||||
|
}, |
||||
|
formatter: (params) => { |
||||
|
return yellowLineDataArray[params.dataIndex] > 0 ? '加仓资金' : '' |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
data: yellowBlockDataArray, |
||||
|
}, |
||||
|
{ |
||||
|
name: '蓝色', |
||||
|
type: 'bar', |
||||
|
stack: 'total', |
||||
|
xAxisIndex: 2, |
||||
|
yAxisIndex: 2, |
||||
|
barCategoryGap: '0%', // 类目间柱条间距为0 |
||||
|
label: { |
||||
|
show: true, |
||||
|
position: 'inside' |
||||
|
}, |
||||
|
itemStyle: { |
||||
|
normal: { |
||||
|
color: 'rgba(34, 196, 190, 1)', |
||||
|
borderWidth: 0 |
||||
|
} |
||||
|
}, |
||||
|
data: blueLineDataArray |
||||
|
}, |
||||
|
{ |
||||
|
name: '紫色', |
||||
|
type: 'bar', |
||||
|
stack: 'total', |
||||
|
xAxisIndex: 2, |
||||
|
yAxisIndex: 2, |
||||
|
barCategoryGap: '0%', // 类目间柱条间距为0 |
||||
|
label: { |
||||
|
show: true, |
||||
|
position: 'inside' |
||||
|
}, |
||||
|
itemStyle: { |
||||
|
normal: { |
||||
|
color: 'rgba(191, 87, 222, 1)', |
||||
|
borderWidth: 0 |
||||
|
} |
||||
|
}, |
||||
|
data: purpleLineDataArray |
||||
|
}, |
||||
|
] |
||||
|
} |
||||
|
|
||||
|
// 使用配置项显示图表 |
||||
|
bottomRadarChart.setOption(option) |
||||
|
|
||||
|
// 监听窗口大小变化,调整图表尺寸 |
||||
|
window.addEventListener('resize', () => { |
||||
|
bottomRadarChart.resize() |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
// 暴露给父级 |
||||
|
defineExpose({ |
||||
|
initEmotionalBottomRadar |
||||
|
}) |
||||
|
</script> |
||||
|
|
||||
|
<style> |
||||
|
#bottomRadarChart{ |
||||
|
width: 100%; |
||||
|
height: 1040px; |
||||
|
} |
||||
|
</style> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue