This commit is contained in:
xlmessage 2024-12-11 09:52:47 +08:00
commit 0e619d8698
39 changed files with 10743 additions and 0 deletions

30
.gitignore vendored Normal file

@ -0,0 +1,30 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
.DS_Store
dist
dist-ssr
coverage
*.local
/cypress/videos/
/cypress/screenshots/
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
*.tsbuildinfo

3
.vscode/extensions.json vendored Normal file

@ -0,0 +1,3 @@
{
"recommendations": ["Vue.volar"]
}

86
MACD.html Normal file

@ -0,0 +1,86 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF - 8">
<title>MACD in Echarts</title>
<!-- 引入Echarts库 -->
<script src="/echarts.min.js"></script>
<style>
#id{
color: rgb(38, 224, 233);
}
</style>
</head>
<body>
<!-- 为Echarts图表准备一个DOM容器 -->
<div id="macdChart" style="width: 600px; height: 400px;"></div>
<script>
// 初始化Echarts实例
var myChart = echarts.init(document.getElementById('macdChart'));
// 模拟的MACD数据
var data = {
"dates": ["2024 - 01 - 01", "2024 - 01 - 02", "2024 - 01 - 03", "2024 - 01 - 04", "2024 - 01 - 05"],
"macd": [0.5, 0.3, - 0.1, - 0.3, 0.2],
"signal": [0.4, 0.35, - 0.05, - 0.25, 0.15],
"histogram": [0.1, - 0.05, - 0.05, - 0.05, 0.05]
};
var option = {
title: {
text: 'MACD Chart'
},
tooltip: {
trigger: 'axis'
},
xAxis: {
type: 'category',
data: data.dates,
alignTicks: true
},
yAxis: {
type: 'value'
},
series: [
{
name: 'MACD',
type: 'line',
data: data.macd,
itemStyle: {
normal: {
color: 'rgb(38, 224, 233)'
}
}
},
{
name: 'Signal Line',
type: 'line',
data: data.signal,
itemStyle: {
normal: {
color: 'Orange'
}
}
},
{
name: 'Histogram',
type: 'bar',
data: data.histogram,
itemStyle: {
normal: {
color: function (params) {
return params.value < 0? 'green' :'red';
}
}
}
}
]
};
myChart.setOption(option);
</script>
</body>
</html>

29
README.md Normal file

@ -0,0 +1,29 @@
# webview
This template should help get you started developing with Vue 3 in Vite.
## Recommended IDE Setup
[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur).
## Customize configuration
See [Vite Configuration Reference](https://vite.dev/config/).
## Project Setup
```sh
npm install
```
### Compile and Hot-Reload for Development
```sh
npm run dev
```
### Compile and Minify for Production
```sh
npm run build
```

111
demo.html Normal file

@ -0,0 +1,111 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="./echarts.min.js"></script>
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.box {
width: 800px;
height: 100vh;
margin: 0 auto;
display: grid;
grid-template-rows: repeat(10, 10vh);
/* 定义10行每行10vh尽管只用一行 */
grid-template-columns: 1fr;
/* 定义一个列,占满整个宽度 */
}
.echarts {
grid-row: 1 / 6;
grid-column: 1 / -1;
}
.newecharts {
grid-row: 1 / 4;
grid-column: 1 / -1;
}
#change {
cursor: pointer;
}
</style>
</head>
<body>
<div id="change">点我改变图形大小</div>
<div class="box">
<div id="echarts" class="echarts"></div>
</div>
<script>
// 基于准备好的dom初始化echarts实例
var myChart = echarts.init(document.getElementById('echarts'))
// 指定图表的配置项和数据
var option = {
title: {
text: 'ECharts 入门示例',
},
tooltip: {},
legend: {
data: ['销量'],
},
xAxis: {
data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子'],
},
yAxis: {},
series: [
{
name: '销量',
type: 'bar',
data: [5, 20, 36, 10, 10, 20],
},
],
}
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option)
document.getElementById('change').addEventListener('click', function () {
console.log("点击了");
// 切换类名以改变图表大小
var echartsDom = document.getElementById('echarts');
echartsDom.classList.toggle('newecharts');
echartsDom.classList.toggle('echarts');
// 让ECharts响应容器大小的变化
myChart.resize();
// 如果需要,你可以在这里更新图表的数据或配置项
// 例如myChart.setOption(newOption);
});
// 根据页面大小自动响应图表大小
window.addEventListener('resize', function () {
myChart.resize()
})
// let OneHeight = chartsInfo.value.offsetHeight * ( heightList.value.length * 0.1)
// heightList.value.push(OneHeight)
// // 第其它图的高度
// let OtherHeight = chartsInfo.value.offsetHeight * 0.1
// heightList.value.push(OtherHeight)
for (let index = 1; index <= 2; index++) {
console.log("index", index);
}
</script>
</body>
</html>

45
echarts.min.js vendored Normal file

File diff suppressed because one or more lines are too long

22
index.html Normal file

@ -0,0 +1,22 @@
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vite App</title>
<style>
*{
margin: 0;
padding: 0;
}
::-webkit-scrollbar{
width: 0;
}
</style>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>

51
jquery.html Normal file

@ -0,0 +1,51 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>JQuery Mobile</title>
<!-- 引入 jQuery Mobile 样式 -->
<link rel="stylesheet" href="http://apps.bdimg.com/libs/jquerymobile/1.4.5/jquery.mobile-1.4.5.min.css">
<!-- 引入 jQuery 库 -->
<script src="http://apps.bdimg.com/libs/jquery/1.10.2/jquery.min.js"></script>
<!-- 引入 jQuery Mobile 库 -->
<script src="http://apps.bdimg.com/libs/jquerymobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
</head>
<body>
<div data-role="page" id="pageone">
<div data-role="header">
<h1>欢迎来到我的主页</h1>
</div>
<div data-role="main" class="ui-content">
<p>欢迎! 点击以下链接跳转到第二个页面。 </p>
<a href="#pagetwo">跳转到第二个页面</a>
</div>
<div data-role="footer">
<h1>底部文本</h1>
</div>
</div>
<div data-role="page" id="pagetwo">
<div data-role="header">
<h1>欢迎来到我的主页</h1>
</div>
<div data-role="main" class="ui-content">
<p>这是第二个页面。点击以下链接跳转到第一个页面。</p>
<a href="#pageone">跳转到第一个页面</a>
</div>
<div data-role="footer">
<h1>底部文本</h1>
</div>
</div>
</body>
</html>

13
jsconfig.json Normal file

@ -0,0 +1,13 @@
{
"compilerOptions": {
"paths": {
"@/*": [
"./src/*"
]
}
},
"exclude": [
"node_modules",
"dist"
]
}

3310
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

24
package.json Normal file

@ -0,0 +1,24 @@
{
"name": "webview",
"version": "0.0.0",
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"axios": "^1.7.9",
"echarts": "^5.5.1",
"pinia": "^2.2.6",
"vue": "^3.5.12",
"vue-router": "^4.4.5"
},
"devDependencies": {
"@vitejs/plugin-vue": "^5.1.4",
"sass": "^1.81.0",
"vite": "^5.4.10",
"vite-plugin-vue-devtools": "^7.5.4"
}
}

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width: 32px  |  Height: 32px  |  Size: 4.2 KiB

11
src/App.vue Normal file

@ -0,0 +1,11 @@
<script setup>
import { RouterView } from 'vue-router'
import * as echarts from "echarts";
import { provide } from "vue";//使provide/injectechartsecharts,App.vue
provide("echarts", echarts);
</script>
<template>
<RouterView />
</template>

86
src/assets/base.css Normal file

@ -0,0 +1,86 @@
/* color palette from <https://github.com/vuejs/theme> */
:root {
--vt-c-white: #ffffff;
--vt-c-white-soft: #f8f8f8;
--vt-c-white-mute: #f2f2f2;
--vt-c-black: #181818;
--vt-c-black-soft: #222222;
--vt-c-black-mute: #282828;
--vt-c-indigo: #2c3e50;
--vt-c-divider-light-1: rgba(60, 60, 60, 0.29);
--vt-c-divider-light-2: rgba(60, 60, 60, 0.12);
--vt-c-divider-dark-1: rgba(84, 84, 84, 0.65);
--vt-c-divider-dark-2: rgba(84, 84, 84, 0.48);
--vt-c-text-light-1: var(--vt-c-indigo);
--vt-c-text-light-2: rgba(60, 60, 60, 0.66);
--vt-c-text-dark-1: var(--vt-c-white);
--vt-c-text-dark-2: rgba(235, 235, 235, 0.64);
}
/* semantic color variables for this project */
:root {
--color-background: var(--vt-c-white);
--color-background-soft: var(--vt-c-white-soft);
--color-background-mute: var(--vt-c-white-mute);
--color-border: var(--vt-c-divider-light-2);
--color-border-hover: var(--vt-c-divider-light-1);
--color-heading: var(--vt-c-text-light-1);
--color-text: var(--vt-c-text-light-1);
--section-gap: 160px;
}
@media (prefers-color-scheme: dark) {
:root {
--color-background: var(--vt-c-black);
--color-background-soft: var(--vt-c-black-soft);
--color-background-mute: var(--vt-c-black-mute);
--color-border: var(--vt-c-divider-dark-2);
--color-border-hover: var(--vt-c-divider-dark-1);
--color-heading: var(--vt-c-text-dark-1);
--color-text: var(--vt-c-text-dark-2);
}
}
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
font-weight: normal;
}
body {
min-height: 100vh;
color: var(--color-text);
background: var(--color-background);
transition:
color 0.5s,
background-color 0.5s;
line-height: 1.6;
font-family:
Inter,
-apple-system,
BlinkMacSystemFont,
'Segoe UI',
Roboto,
Oxygen,
Ubuntu,
Cantarell,
'Fira Sans',
'Droid Sans',
'Helvetica Neue',
sans-serif;
font-size: 15px;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

1
src/assets/logo.svg Normal file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 261.76 226.69"><path d="M161.096.001l-30.225 52.351L100.647.001H-.005l130.877 226.688L261.749.001z" fill="#41b883"/><path d="M161.096.001l-30.225 52.351L100.647.001H52.346l78.526 136.01L209.398.001z" fill="#34495e"/></svg>

After

(image error) Size: 276 B

35
src/assets/main.css Normal file

@ -0,0 +1,35 @@
@import './base.css';
#app {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
font-weight: normal;
}
a,
.green {
text-decoration: none;
color: hsla(160, 100%, 37%, 1);
transition: 0.4s;
padding: 3px;
}
@media (hover: hover) {
a:hover {
background-color: hsla(160, 100%, 37%, 0.2);
}
}
@media (min-width: 1024px) {
body {
display: flex;
place-items: center;
}
#app {
display: grid;
grid-template-columns: 1fr 1fr;
padding: 0 2rem;
}
}

@ -0,0 +1,88 @@
<template>
<div>
<div ref="parentChart" style="width: 600px; height: 400px;"></div>
<ChildComponent ref="childComponent" />
<ChildComponent ref="childComponent" />
</div>
</template>
<script>
import { ref, onMounted, onBeforeUnmount } from 'vue';
import * as echarts from 'echarts';
import ChildComponent from './NewSon.vue';
export default {
components: {
ChildComponent,
},
setup() {
const parentChart = ref(null);
const childComponent = ref(null);
let parentChartInstance = null;
let childChartInstance = null;
const initCharts = () => {
parentChartInstance = echarts.init(parentChart.value);
const option = {
title: {
text: 'Parent Chart',
},
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
},
dataZoom: [
{
type: 'inside',
},
],
yAxis: {
type: 'value',
},
series: [
{
data: [120, 200, 150, 80, 70, 110, 130],
type: 'bar',
},
],
};
parentChartInstance.setOption(option);
// ChildComponent
childChartInstance = childComponent.value.getChartInstance();
// Connect the charts
if (parentChartInstance && childChartInstance) {
echarts.connect([parentChartInstance, childChartInstance]);
}
};
const destroyCharts = () => {
if (parentChartInstance) {
parentChartInstance.dispose();
}
if (childChartInstance) {
//
//
}
};
onMounted(() => {
initCharts();
});
onBeforeUnmount(() => {
destroyCharts();
});
return {
parentChart,
childComponent,
};
},
};
</script>
<style scoped>
/* Add your styles here */
</style>

72
src/components/NewSon.vue Normal file

@ -0,0 +1,72 @@
<template>
<div ref="childChart" style="width: 600px; height: 400px;"></div>
</template>
<script>
import { ref, onMounted, onBeforeUnmount } from 'vue';
import * as echarts from 'echarts';
export default {
name: 'ChildComponent',
setup() {
const childChart = ref(null);
let childChartInstance = null;
const initChart = () => {
childChartInstance = echarts.init(childChart.value);
const option = {
title: {
text: 'Child Chart',
},
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
},
dataZoom: [
{
type: 'inside',
},
],
yAxis: {
type: 'value',
},
series: [
{
data: [220, 182, 191, 234, 290, 330, 310],
type: 'line',
},
],
};
childChartInstance.setOption(option);
};
const destroyChart = () => {
if (childChartInstance) {
childChartInstance.dispose();
}
};
onMounted(() => {
initChart();
});
onBeforeUnmount(() => {
destroyChart();
});
// Expose a method to get the chart instance
const getChartInstance = () => {
return childChartInstance;
};
return {
childChart,
getChartInstance,
};
},
};
</script>
<style scoped>
/* Add your styles here */
</style>

96
src/components/Test.vue Normal file

@ -0,0 +1,96 @@
<template>
<div>
<div ref="parentChart" style="width: 600px; height: 400px"></div>
<!-- 假设我们有一个名为childComponentsData的数组用于存储每个子组件的数据 -->
<ChildComponent
v-for="(data, index) in childComponentsData"
:key="index"
:data="data"
ref="el => childComponents[index] = el"
/>
<!-- <div
v-if="state1"
id="charts1"
ref="charts1"
:style="{ height: `${heightList[1]}px` }"
></div>
<div
v-if="state2"
id="charts2"
ref="charts2"
:style="{ height: `${heightList[1]}px` }"
></div> -->
</div>
</template>
<script>
import { ref, onMounted, onBeforeUnmount, reactive } from 'vue'
import * as echarts from 'echarts'
import ChildComponent from './NewSon.vue'
export default {
components: {
ChildComponent,
},
setup() {
const parentChart = ref(null)
const childComponents = reactive([]) // 使reactive
let parentChartInstance = null
let childChartInstances = [] //
//
const childComponentsData = [
{
/* 数据1 */
},
{
/* 数据2 */
},
// ...
]
const initCharts = () => {
parentChartInstance = echarts.init(parentChart.value)
// ...
//
childComponentsData.forEach((_, index) => {
if (childComponents[index]) {
// ChildComponent
const childChartInstance = childComponents[index].getChartInstance()
if (childChartInstance) {
childChartInstances.push(childChartInstance)
//
if (parentChartInstance) {
echarts.connect([parentChartInstance, childChartInstance])
}
}
}
})
}
const destroyCharts = () => {
// ...
}
onMounted(() => {
initCharts()
})
onBeforeUnmount(() => {
destroyCharts()
})
return {
parentChart,
// childComponents
// v-forref访
}
},
}
</script>
<style scoped>
/* 添加您的样式 */
</style>

71
src/components/Test2.vue Normal file

@ -0,0 +1,71 @@
<template>
</template>
<script setup>
let resizeListenerAdded = false; // resize
//
const initChart = (containerId, options = {}) => {
const chart = echarts.init(document.getElementById(containerId));
const defaultOption = {
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
},
yAxis: {
type: 'value',
},
grid: {
top: '10%',
left: '3%',
right: '3%',
bottom: '20%',
},
dataZoom: [{
type: 'inside',
}],
series: [{
data: [820, 932, 901, 934, 1290, 1330, 1320],
type: 'line',
smooth: true,
}],
};
chart.setOption(Object.assign({}, defaultOption, options));
chart.group = 'group1'; //
return chart;
};
//
const createAndConnectCharts = (chartsConfig = []) => {
const charts = chartsConfig.map(({ containerId, options }) => initChart(containerId, options));
//
if (charts.length > 0) {
echarts.connect('group1');
// resize
if (!resizeListenerAdded) {
window.addEventListener('resize', function () {
charts.forEach(chart => chart.resize());
});
resizeListenerAdded = true; //
}
}
return charts; // 便使
};
// 使
const chartsConfig = [
{ containerId: 'charts1', options: { /* 可选的自定义选项 */ } },
{ containerId: 'charts2', options: { /* 可选的自定义选项 */ } },
// ...
];
const charts = createAndConnectCharts(chartsConfig);
//
// removeEventListener
// 使 chart.dispose()
</script>

@ -0,0 +1,651 @@
<script setup>
import { onMounted, inject, ref, watch, nextTick, reactive } from 'vue' //
import { storeToRefs } from 'pinia'
import useEcharts from '@/store/useechartstore'
const echartsState = useEcharts()
echartsState.optionConfigData()
const { gridList, addedCharts } = storeToRefs(echartsState)
// console.log(option.value.grid)
let echarts = inject('echarts') //
//
let chartstype = ref([])
const chartsInfo = ref(null) // 访 .chartsinfo
const mKline = ref(null)
//
let heightList = ref()
//
const dynamicsHeight = () => {
heightList = chartsInfo.value.offsetHeight
mKline.value.style.height = `${heightList}px`
}
onMounted(() => {
dynamicsHeight()
configecharts()
})
//
const chartConfigs = [
{
name: 'MA',
options: {
tooltip: {
trigger: 'axis', //
axisPointer: {
//
type: 'cross', //
label: {
backgroundColor: '#6a7985', //
},
},
},
title: {
text: 'K线图',
left: 0,
},
dataZoom: [
{
show: true,
xAxisIndex: [0, 1],
type: 'slider',
},
],
xAxis: {
type: 'category',
gridIndex: 1,
boundaryGap: false,
data: echartsState.times,
axisLabel: { show: false },
},
yAxis: {
type: 'value',
scale: true /*按比例显示*/,
gridIndex: 1,
splitNumber: 3,
},
series: [
{
name: 'Highest',
type: 'line',
xAxisIndex: 1,
yAxisIndex: 1,
smooth: true,
lineStyle: {
color: 'red',
},
data: [
10, 11, 13, 11, 12, 12, 9, 10, 11, 13, 11, 12, 12, 9, 10, 11, 13,
11, 12, 12, 9, 10, 11, 13, 11, 12, 12, 9, 10, 11, 13, 11, 12, 12, 9,
10, 11, 13, 11, 12, 12, 9, 10, 11, 13, 11, 12, 12, 9, 10, 11, 13,
11, 12, 12, 9,
],
},
{
name: 'Lowest',
type: 'bar',
xAxisIndex: 1,
yAxisIndex: 1,
itemStyle: {
normal: {
color: 'red',
},
},
data: [
1, -2, 2, 5, 3, 2, -3, 1, -2, 2, 5, 3, 2, -3, 1, -2, 2, 5, 3, 2, -3,
1, -2, 2, 5, 3, 2, -3, 1, -2, 2, 5, 3, 2, -3, 1, -2, 2, 5, 3, 2, -3,
1, -2, 2, 5, 3, 2, -3, 1, -2, 2, 5, 3, 2, -3,
],
},
{
name: 'rant',
type: 'line',
xAxisIndex: 1,
yAxisIndex: 1,
itemStyle: {
normal: {
//
color: 'green',
},
},
data: [
-5, 1, 7, 3, -1, 2, 0, -5, 1, 7, 3, -1, 2, 0, -5, 1, 7, 3, -1, 2, 0,
-5, 1, 7, 3, -1, 2, 0, -5, 1, 7, 3, -1, 2, 0, -5, 1, 7, 3, -1, 2, 0,
-5, 1, 7, 3, -1, 2, 0,
],
},
],
},
},
{
name: 'BOLL',
options: {
tooltip: {
trigger: 'axis', //
axisPointer: {
//
type: 'cross', //
label: {
backgroundColor: '#6a7985', //
},
},
},
title: {
text: 'K线图',
left: 0,
},
dataZoom: [
{
type: 'inside',
},
],
xAxis: {
type: 'category',
gridIndex: 2,
boundaryGap: false,
data: echartsState.times,
axisLabel: { show: false },
},
yAxis: {
type: 'value',
scale: true /*按比例显示*/,
gridIndex: 2,
splitNumber: 3,
// axisLine: { onZero: false },
// axisTick: { show: false },
// splitLine: { show: false },
// axisLabel: { show: true },
},
series: [
{
name: 'Highest',
type: 'line',
xAxisIndex: 2,
yAxisIndex: 2,
smooth: true,
lineStyle: {
color: 'red',
},
data: [
10, 11, 13, 11, 12, 12, 9, 10, 11, 13, 11, 12, 12, 9, 10, 11, 13,
11, 12, 12, 9, 10, 11, 13, 11, 12, 12, 9, 10, 11, 13, 11, 12, 12, 9,
10, 11, 13, 11, 12, 12, 9, 10, 11, 13, 11, 12, 12, 9, 10, 11, 13,
11, 12, 12, 9,
],
markPoint: {
data: [
{ type: 'max', name: 'Max' },
{ type: 'min', name: 'Min' },
],
},
markLine: {
data: [{ type: 'average', name: 'Avg' }],
},
},
],
},
},
]
//
// const addedCharts = ref([])
//
const addChart = (chartConfig) => {
console.log(chartConfig)
//
let exists = echartsState.addedCharts.some(
(item) => item === chartConfig.name
)
if (exists) {
//
echartsState.addedCharts = echartsState.addedCharts.filter(
(item) => item !== chartConfig.name
)
} else {
//
if (echartsState.addedCharts.length > 4) {
// 51
echartsState.addedCharts.splice(1, 1)
}
console.log('执行了')
console.log(echartsState.addedCharts);
for (const key in chartConfig.options) {
if (Object.prototype.hasOwnProperty.call(chartConfig.options, key)) {
if(key == 'xAxis'){
console.log(chartConfig.options[key].gridIndex);
chartConfig.options[key].gridIndex = echartsState.addedCharts.length + 1
console.log(chartConfig.options[key].gridIndex);
}
if(key == 'yAxis'){
chartConfig.options[key].gridIndex = echartsState.addedCharts.length + 1
}
if(key == 'series'){
chartConfig.options[key].forEach(element => {
element.xAxisIndex = echartsState.addedCharts.length + 1
element.yAxisIndex = echartsState.addedCharts.length + 1
});
}
}
}
//
echartsState.addedCharts.push(chartConfig.options)
}
console.log(echartsState.addedCharts)
chartstype.value.push(chartConfig.name)
// console.log(chartstype.value)
dynamicsHeight()
//
let d = newOption(chartConfig.options)
console.log(d)
echartsState.option.grid = echartsState.gridList[echartsState.addedCharts.length]
console.log(echartsState.option.grid)
//
configecharts(d)
}
// option
let newOption = (newoption) => {
console.log([...echartsState.option.series, ...newoption.series]);
return {
xAxis: [...echartsState.option.xAxis, newoption.xAxis],
yAxis: [...echartsState.option.yAxis, newoption.yAxis],
dataZoom: [...echartsState.option.dataZoom, newoption.dataZoom],
series: [...echartsState.option.series, ...newoption.series],
}
}
// Echarts
const configecharts = (options = {}) => {
document.getElementById('main').removeAttribute('_echarts_instance_')
const chartBox = echarts.init(document.getElementById('main')) //
const option = echartsState.option
chartBox.setOption(option)
console.log(options)
// //
chartBox.setOption(options)
//
window.addEventListener('resize', function () {
chartBox.resize()
})
}
let newoption = {
grid: [
{
left: '3%',
right: '3%',
top: '6%',
height: '48%',
},
{
left: '3%',
right: '3%',
top: '59%',
height: '10%',
},
{
left: '3%',
right: '3%',
top: '72%',
height: '10%',
},
{
left: '3%',
right: '3%',
top: '85%',
height: '10%',
},
// {
// left: '3%',
// right: '3%',
// top: '71%',
// height: '10%',
// },
// {
// left: '3%',
// right: '3%',
// top: '84%',
// height: '10%',
// },
// 2
// {
// left: '3%',
// right: '3%',
// top:'6%',
// height: '75%',
// },
// {
// left: '3%',
// right: '3%',
// top: '85%',
// height: '10%',
// },
],
xAxis: [
...echartsState.option.xAxis,
{
type: 'category',
gridIndex: 1,
data: echartsState.times,
axisLabel: { show: false },
},
{
type: 'category',
gridIndex: 2,
data: echartsState.times,
axisLabel: { show: false },
},
{
type: 'category',
gridIndex: 3,
data: echartsState.times,
axisLabel: { show: false },
},
// {
// type: 'category',
// gridIndex: 4,
// data: echartsState.times,
// axisLabel: { show: false },
// },
// {
// type: 'category',
// gridIndex: 5,
// data: echartsState.times,
// axisLabel: { show: false },
// },
],
yAxis: [
...echartsState.option.yAxis,
{
type: 'value',
scale: true /*按比例显示*/,
gridIndex: 1,
splitNumber: 3,
axisLine: { onZero: false },
axisTick: { show: false },
splitLine: { show: false },
axisLabel: { show: true },
},
{
gridIndex: 2,
splitNumber: 3,
axisLine: { onZero: false },
axisTick: { show: false },
splitLine: { show: false },
axisLabel: { show: true },
},
{
gridIndex: 3,
splitNumber: 3,
axisLine: { onZero: false },
axisTick: { show: false },
splitLine: { show: false },
axisLabel: { show: true },
},
// {
// gridIndex: 4,
// splitNumber: 3,
// axisLine: { onZero: false },
// axisTick: { show: false },
// splitLine: { show: false },
// axisLabel: { show: true },
// },
// {
// gridIndex: 5,
// splitNumber: 3,
// axisLine: { onZero: false },
// axisTick: { show: false },
// splitLine: { show: false },
// axisLabel: { show: true },
// },
],
dataZoom: [
...echartsState.option.dataZoom,
{
show: true,
xAxisIndex: [0, 1],
type: 'inside',
top: '97%',
start: 20,
end: 100,
// show: false
},
{
show: true,
xAxisIndex: [1, 2],
type: 'inside',
top: '97%',
start: 20,
end: 100,
// show: false
},
{
show: true,
xAxisIndex: [2, 3],
type: 'inside',
top: '97%',
start: 20,
end: 100,
// show: false
},
// {
// show: true,
// xAxisIndex: [3, 4],
// type: 'inside',
// top: '97%',
// start: 20,
// end: 100,
// // show: false
// },
// {
// show: true,
// xAxisIndex: [4, 5],
// type: 'inside',
// top: '97%',
// start: 20,
// end: 100,
// // show: false
// },
],
series: [
...echartsState.option.series,
{
name: 'Volumn',
type: 'bar',
xAxisIndex: 1,
yAxisIndex: 1,
data: echartsState.vols,
itemStyle: {
normal: {
color: function (params) {
var colorList
if (
echartsState.datas[params.dataIndex][1] >
echartsState.datas[params.dataIndex][0]
) {
colorList = '#ef232a'
} else {
colorList = '#14b143'
}
return colorList
},
},
},
},
{
name: 'ls',
type: 'bar',
xAxisIndex: 2,
yAxisIndex: 2,
data: echartsState.vols,
itemStyle: {
normal: {
color: function (params) {
var colorList
if (
echartsState.datas[params.dataIndex][1] >
echartsState.datas[params.dataIndex][0]
) {
colorList = '#ef232a'
} else {
colorList = '#14b143'
}
return colorList
},
},
},
},
{
name: 'lu',
type: 'bar',
xAxisIndex: 3,
yAxisIndex: 3,
data: echartsState.vols,
itemStyle: {
normal: {
color: function (params) {
var colorList
if (
echartsState.datas[params.dataIndex][1] >
echartsState.datas[params.dataIndex][0]
) {
colorList = '#ef232a'
} else {
colorList = '#14b143'
}
return colorList
},
},
},
},
// {
// name: 'lum',
// type: 'bar',
// xAxisIndex: 4,
// yAxisIndex: 4,
// data: echartsState.vols,
// itemStyle: {
// normal: {
// color: function (params) {
// var colorList
// if (
// echartsState.datas[params.dataIndex][1] >
// echartsState.datas[params.dataIndex][0]
// ) {
// colorList = '#ef232a'
// } else {
// colorList = '#14b143'
// }
// return colorList
// },
// },
// },
// },
// {
// name: 'lumn',
// type: 'bar',
// xAxisIndex: 5,
// yAxisIndex: 5,
// data: echartsState.vols,
// itemStyle: {
// normal: {
// color: function (params) {
// var colorList
// if (
// echartsState.datas[params.dataIndex][1] >
// echartsState.datas[params.dataIndex][0]
// ) {
// colorList = '#ef232a'
// } else {
// colorList = '#14b143'
// }
// return colorList
// },
// },
// },
// },
],
}
</script>
<template>
<div class="box">
<div class="chartsinfo" ref="chartsInfo">
<!-- K线图 -->
<div
id="main"
ref="mKline"
class="flex-item"
:style="{ height: `${heightList}px` }"
></div>
</div>
<ul class="typelist">
<li
v-for="(chartConfig, index) in chartConfigs"
:key="index"
@click="addChart(chartConfig)"
>
{{ chartConfig.name }}
</li>
</ul>
<!-- {{ option }} -->
</div>
</template>
<style lang="scss" scoped>
.box {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
.chartsinfo {
height: calc(100vh - 20px);
}
.typelist {
margin-top: auto; // 使 margin-top: auto .typelist
position: relative;
z-index: 99999999;
background-color: #191919;
width: 100%;
color: #afb3b4;
font-size: 12px;
display: flex;
list-style: none;
padding: 0; // padding
}
.typelist > li {
padding: 2px 8px;
cursor: pointer;
}
.active {
color: #2d98b9;
}
</style>

@ -0,0 +1,231 @@
<!-- ChartComponent.vue -->
<template>
<div :style="{ width: '100%', height: '100%' }">
<div ref="chartRef" :style="{ width: '100%', height: '100%' }"></div>
</div>
</template>
<script setup>
import { ref, onMounted, inject, nextTick } from 'vue'
let echarts = inject('echarts') //
const props = defineProps({
chartData: Object,
area: {
type: String,
defalut: '1',
},
})
const chartRef = ref(null)
onMounted(() => {
const myChart = echarts.init(chartRef.value)
const option = {
title: {
text: props.chartData.title, // 使
},
tooltip: {
trigger: 'axis', //
axisPointer: {
//
type: 'cross', //
label: {
backgroundColor: '#6a7985', //
},
},
},
grid: {
top: '5%',
left: '2%',
right: '3%',
bottom: '3%',
},
legend: {},
dataZoom: [
{
type: 'inside', //
start: 10, // 10%
end: 60, // 60%
},
],
xAxis: {
type: 'category',
boundaryGap: false,
data: [
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun',
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun',
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun',
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun',
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun',
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun',
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun',
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun',
],
},
yAxis: {
type: 'value',
axisLabel: {
// formatter: '{value} °%',
formatter: '{value}',
},
},
series: [
{
name: 'Highest',
type: 'line',
smooth: true,
lineStyle: {
color: 'red',
},
data: [
10, 11, 13, 11, 12, 12, 9, 10, 11, 13, 11, 12, 12, 9, 10, 11, 13, 11,
12, 12, 9, 10, 11, 13, 11, 12, 12, 9, 10, 11, 13, 11, 12, 12, 9, 10,
11, 13, 11, 12, 12, 9, 10, 11, 13, 11, 12, 12, 9, 10, 11, 13, 11, 12,
12, 9,
],
markPoint: {
data: [
{ type: 'max', name: 'Max' },
{ type: 'min', name: 'Min' },
],
},
markLine: {
data: [{ type: 'average', name: 'Avg' }],
},
},
{
name: 'Lowest',
type: 'bar',
itemStyle: {
normal: {
color: 'red',
},
},
data: [
1, -2, 2, 5, 3, 2, -3, 1, -2, 2, 5, 3, 2, -3, 1, -2, 2, 5, 3, 2, -3,
1, -2, 2, 5, 3, 2, -3, 1, -2, 2, 5, 3, 2, -3, 1, -2, 2, 5, 3, 2, -3,
1, -2, 2, 5, 3, 2, -3, 1, -2, 2, 5, 3, 2, -3,
],
markPoint: {
data: [{ name: '周最低', value: -2, xAxis: 1, yAxis: -1.5 }],
},
markLine: {
data: [
{ type: 'average', name: 'Avg' },
[
{
symbol: 'none',
x: '90%',
yAxis: 'max',
},
{
symbol: 'circle',
label: {
position: 'start',
formatter: 'Max',
},
type: 'max',
name: '最高点',
},
],
],
},
},
{
name: 'rant',
type: 'bar',
itemStyle: {
normal: {
//
color: 'green',
},
},
data: [
-5, 1, 7, 3, -1, 2, 0, -5, 1, 7, 3, -1, 2, 0, -5, 1, 7, 3, -1, 2, 0,
-5, 1, 7, 3, -1, 2, 0, -5, 1, 7, 3, -1, 2, 0, -5, 1, 7, 3, -1, 2, 0,
-5, 1, 7, 3, -1, 2, 0,
],
markPoint: {
data: [{ name: '周最低', value: -2, xAxis: 1, yAxis: -1.5 }],
},
markLine: {
data: [
{ type: 'average', name: 'Avg' },
[
{
symbol: 'none',
x: '90%',
yAxis: 'max',
},
{
symbol: 'circle',
label: {
position: 'start',
formatter: 'Max',
},
type: 'max',
name: '最高点',
},
],
],
},
},
],
}
myChart.setOption(option)
window.addEventListener('resize', function () {
myChart.resize()
})
})
</script>

@ -0,0 +1,29 @@
<template>
<div ref="chartContainer" :style="{ width: '100%', height: '100%' }"></div>
</template>
<script setup>
import { onMounted, onBeforeUnmount, ref } from 'vue';
import * as echarts from 'echarts';
const props = defineProps({
options: {
type: Object,
required: true
}
});
const chartContainer = ref(null);
let chartInstance = null;
onMounted(() => {
chartInstance = echarts.init(chartContainer.value);
chartInstance.setOption(props.options);
});
onBeforeUnmount(() => {
if (chartInstance) {
chartInstance.dispose();
}
});
</script>

1844
src/echarts/KechartsView.vue Normal file

File diff suppressed because it is too large Load Diff

164
src/echarts/Topcharts.vue Normal file

@ -0,0 +1,164 @@
<!-- ChartComponent.vue -->
<template>
<div :style="{ width: '100%', height: '100%' }">
<div ref="chartRef" :style="{ width: '100%', height: '100%' }"></div>
</div>
</template>
<script setup>
import { ref, onMounted, inject, nextTick } from 'vue'
let echarts = inject('echarts') //
const props = defineProps({
chartData: Object,
area: {
type: String,
defalut: '1',
},
})
const chartRef = ref(null)
onMounted(() => {
const myChart = echarts.init(chartRef.value)
const option = {
title: {
text: '', // 使
},
tooltip: {
trigger: 'axis', //
axisPointer: {
//
type: 'cross', //
label: {
backgroundColor: '#6a7985', //
},
},
},
grid: {
top: '3%',
left: '5%',
right: '3%',
bottom: '3%',
},
legend: {},
dataZoom: [
{
type: 'inside', //
start: 10, // 10%
end: 60, // 60%
},
],
xAxis: {
type: 'category',
boundaryGap: false,
data: [
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun',
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun',
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun',
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun',
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun',
],
},
yAxis: {
type: 'value',
axisLabel: {
formatter: '{value} °%',
},
},
series: [
{
name: 'Highest',
type: 'line',
lineStyle: {
color: 'red',
},
data: [
10, 11, 13, 11, 12, 12, 9, 10, 11, 13, 11, 12, 12, 9, 10, 11, 13, 11,
12, 12, 9, 10, 11, 13, 11, 12, 12, 9, 10, 11, 13, 11, 12, 12, 9,
],
markPoint: {
data: [
{ type: 'max', name: 'Max' },
{ type: 'min', name: 'Min' },
],
},
markLine: {
data: [{ type: 'average', name: 'Avg' }],
},
},
{
name: 'Lowest',
type: 'line',
lineStyle: {
color: 'green',
},
data: [
1, -2, 2, 5, 3, 2, 0, 1, -2, 2, 5, 3, 2, 0, 1, -2, 2, 5, 3, 2, 0, 1,
-2, 2, 5, 3, 2, 0, 1, -2, 2, 5, 3, 2, 0,
],
markPoint: {
data: [{ name: '周最低', value: -2, xAxis: 1, yAxis: -1.5 }],
},
markLine: {
data: [
{ type: 'average', name: 'Avg' },
[
{
symbol: 'none',
x: '90%',
yAxis: 'max',
},
{
symbol: 'circle',
label: {
position: 'start',
formatter: 'Max',
},
type: 'max',
name: '最高点',
},
],
],
},
},
],
}
myChart.setOption(option)
window.addEventListener('resize', function () {
myChart.resize()
})
})
</script>

841
src/end/DayDesign.vue Normal file

@ -0,0 +1,841 @@
<script setup>
import { onMounted, inject, ref, nextTick, onUnmounted, onBeforeUnmount } from 'vue'
// pinia
import useEcharts from '@/store/useechartstore'
const echartsState = useEcharts()
echartsState.optionConfigData()
//echarts
let echarts = inject('echarts')
//
const chartsInfo = ref(null)
// K线
const mKline = ref(null)
//
let heightList = ref([])
//
const dynamicsHeight = () => {
//
let domHeightList = chartsInfo.value.offsetHeight
//
if (clicklist.value.length) {
//
heightList.value = []
//
heightList.value.push(domHeightList * (1 - clicklist.value.length * 0.15))
// K线
mKline.value.style.height = `${heightList.value[0]}px`
//
heightList.value.push(domHeightList * 0.15)
console.log(heightList.value)
} else {
//
heightList.value = []
// K线
mKline.value.style.height = `${domHeightList}px`
}
}
//
let chartConfigs = ref([
{
id: 1,
name: 'MAVOL',
attId: 'charts1',
status: false,
options: {
tooltip: {
trigger: 'axis', //
axisPointer: {
//
type: 'cross', //
label: {
backgroundColor: '#6a7985', //
},
},
},
dataZoom: [
{
type: 'inside',
xAxisIndex: [0, 0],
start: 20,
end: 100,
},
],
xAxis: {
type: 'category',
boundaryGap: false,
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
},
yAxis: {
type: 'value',
},
series: [
{
name: 'Email',
type: 'line',
stack: 'Total',
data: [120, 132, 101, 134, 90, 230, 210],
},
{
name: 'Union Ads',
type: 'line',
stack: 'Total',
data: [220, 182, 191, 234, 290, 330, 310],
},
{
name: 'Video Ads',
type: 'line',
stack: 'Total',
data: [150, 232, 201, 154, 190, 330, 410],
},
{
name: 'Direct',
type: 'line',
stack: 'Total',
data: [320, 332, 301, 334, 390, 330, 320],
},
{
name: 'Search Engine',
type: 'line',
stack: 'Total',
data: [820, 932, 901, 934, 1290, 1330, 1320],
},
],
},
},
{
id: 2,
name: 'VOL',
attId: 'charts2',
status: false,
options: {
// title: {
// text: 'Stacked Area Chart',
// },
// tooltip: {
// trigger: 'axis',
// axisPointer: {
// type: 'cross',
// label: {
// backgroundColor: '#6a7985',
// },
// },
// },
// legend: {
// data: ['Email', 'Union Ads', 'Video Ads', 'Direct', 'Search Engine'],
// },
// toolbox: {
// feature: {
// saveAsImage: {},
// },
// },
// grid: {
// left: '3%',
// right: '4%',
// bottom: '3%',
// containLabel: true,
// },
dataZoom: [
{
type: 'inside',
xAxisIndex: [0, 0],
start: 20,
end: 100,
},
],
xAxis: [
{
type: 'category',
boundaryGap: false,
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
},
],
yAxis: [
{
type: 'value',
},
],
series: [
{
name: 'Email',
type: 'line',
stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series',
},
data: [120, 132, 101, 134, 90, 230, 210],
},
{
name: 'Union Ads',
type: 'line',
stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series',
},
data: [220, 182, 191, 234, 290, 330, 310],
},
{
name: 'Video Ads',
type: 'line',
stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series',
},
data: [150, 232, 201, 154, 190, 330, 410],
},
{
name: 'Direct',
type: 'line',
stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series',
},
data: [320, 332, 301, 334, 390, 330, 320],
},
{
name: 'Search Engine',
type: 'line',
stack: 'Total',
label: {
show: true,
position: 'top',
},
areaStyle: {},
emphasis: {
focus: 'series',
},
data: [820, 932, 901, 934, 1290, 1330, 1320],
},
],
},
},
{
id: 3,
name: 'MACD',
attId: 'charts3',
status: false,
options:{
dataZoom: [
{
type: 'inside',
xAxisIndex: [0, 0],
start: 20,
end: 100,
},
],
}
},
{
id: 4,
name: 'KDJ',
attId: 'charts4',
status: false,
options:{
dataZoom: [
{
type: 'inside',
xAxisIndex: [0, 0],
start: 20,
end: 100,
},
],
}
},
{
id: 5,
name: 'RSI',
attId: 'charts5',
status: false,
options:{
dataZoom: [
{
type: 'inside',
xAxisIndex: [0, 0],
start: 20,
end: 100,
},
],
}
},
])
//
const clicklist = ref([])
//
const addChart = (item) => {
//
if (clicklist.value.includes(item.name)) {
//
echarts.dispose(item.name)
//
clicklist.value = clicklist.value.filter((content) => content !== item.name)
// false
chartConfigs.value.forEach((element) => {
if (element.name == item.name) {
element.status = false
}
})
//
dynamicsHeight()
//
nextTick(() => {
chartConfigs.value.forEach((element) => {
if (element.name == item.name) {
element.status = false
// configecharts
configecharts()
}
})
})
} else {
//
clicklist.value.push(item.name)
// true
chartConfigs.value.forEach((element) => {
if (element.name == item.name) {
element.status = true
}
})
//
dynamicsHeight()
//
nextTick(() => {
chartConfigs.value.forEach((element) => {
if (element.name == item.name) {
element.status = true
// configecharts
configecharts()
// commonecharts
commonecharts(item.attId, item.options)
}
})
})
}
}
const upColor = '#ec0000';
const upBorderColor = '#8A0000';
const downColor = '#00da3c';
const downBorderColor = '#008F28';
// Each item: opencloselowesthighest
const data0 = splitData([
['2013/1/24', 2320.26, 2320.26, 2287.3, 2362.94],
['2013/1/25', 2300, 2291.3, 2288.26, 2308.38],
['2013/1/28', 2295.35, 2346.5, 2295.35, 2346.92],
['2013/1/29', 2347.22, 2358.98, 2337.35, 2363.8],
['2013/1/30', 2360.75, 2382.48, 2347.89, 2383.76],
['2013/1/31', 2383.43, 2385.42, 2371.23, 2391.82],
['2013/2/1', 2377.41, 2419.02, 2369.57, 2421.15],
['2013/2/4', 2425.92, 2428.15, 2417.58, 2440.38],
['2013/2/5', 2411, 2433.13, 2403.3, 2437.42],
['2013/2/6', 2432.68, 2434.48, 2427.7, 2441.73],
['2013/2/7', 2430.69, 2418.53, 2394.22, 2433.89],
['2013/2/8', 2416.62, 2432.4, 2414.4, 2443.03],
['2013/2/18', 2441.91, 2421.56, 2415.43, 2444.8],
['2013/2/19', 2420.26, 2382.91, 2373.53, 2427.07],
['2013/2/20', 2383.49, 2397.18, 2370.61, 2397.94],
['2013/2/21', 2378.82, 2325.95, 2309.17, 2378.82],
['2013/2/22', 2322.94, 2314.16, 2308.76, 2330.88],
['2013/2/25', 2320.62, 2325.82, 2315.01, 2338.78],
['2013/2/26', 2313.74, 2293.34, 2289.89, 2340.71],
['2013/2/27', 2297.77, 2313.22, 2292.03, 2324.63],
['2013/2/28', 2322.32, 2365.59, 2308.92, 2366.16],
['2013/3/1', 2364.54, 2359.51, 2330.86, 2369.65],
['2013/3/4', 2332.08, 2273.4, 2259.25, 2333.54],
['2013/3/5', 2274.81, 2326.31, 2270.1, 2328.14],
['2013/3/6', 2333.61, 2347.18, 2321.6, 2351.44],
['2013/3/7', 2340.44, 2324.29, 2304.27, 2352.02],
['2013/3/8', 2326.42, 2318.61, 2314.59, 2333.67],
['2013/3/11', 2314.68, 2310.59, 2296.58, 2320.96],
['2013/3/12', 2309.16, 2286.6, 2264.83, 2333.29],
['2013/3/13', 2282.17, 2263.97, 2253.25, 2286.33],
['2013/3/14', 2255.77, 2270.28, 2253.31, 2276.22],
['2013/3/15', 2269.31, 2278.4, 2250, 2312.08],
['2013/3/18', 2267.29, 2240.02, 2239.21, 2276.05],
['2013/3/19', 2244.26, 2257.43, 2232.02, 2261.31],
['2013/3/20', 2257.74, 2317.37, 2257.42, 2317.86],
['2013/3/21', 2318.21, 2324.24, 2311.6, 2330.81],
['2013/3/22', 2321.4, 2328.28, 2314.97, 2332],
['2013/3/25', 2334.74, 2326.72, 2319.91, 2344.89],
['2013/3/26', 2318.58, 2297.67, 2281.12, 2319.99],
['2013/3/27', 2299.38, 2301.26, 2289, 2323.48],
['2013/3/28', 2273.55, 2236.3, 2232.91, 2273.55],
['2013/3/29', 2238.49, 2236.62, 2228.81, 2246.87],
['2013/4/1', 2229.46, 2234.4, 2227.31, 2243.95],
['2013/4/2', 2234.9, 2227.74, 2220.44, 2253.42],
['2013/4/3', 2232.69, 2225.29, 2217.25, 2241.34],
['2013/4/8', 2196.24, 2211.59, 2180.67, 2212.59],
['2013/4/9', 2215.47, 2225.77, 2215.47, 2234.73],
['2013/4/10', 2224.93, 2226.13, 2212.56, 2233.04],
['2013/4/11', 2236.98, 2219.55, 2217.26, 2242.48],
['2013/4/12', 2218.09, 2206.78, 2204.44, 2226.26],
['2013/4/15', 2199.91, 2181.94, 2177.39, 2204.99],
['2013/4/16', 2169.63, 2194.85, 2165.78, 2196.43],
['2013/4/17', 2195.03, 2193.8, 2178.47, 2197.51],
['2013/4/18', 2181.82, 2197.6, 2175.44, 2206.03],
['2013/4/19', 2201.12, 2244.64, 2200.58, 2250.11],
['2013/4/22', 2236.4, 2242.17, 2232.26, 2245.12],
['2013/4/23', 2242.62, 2184.54, 2182.81, 2242.62],
['2013/4/24', 2187.35, 2218.32, 2184.11, 2226.12],
['2013/4/25', 2213.19, 2199.31, 2191.85, 2224.63],
['2013/4/26', 2203.89, 2177.91, 2173.86, 2210.58],
['2013/5/2', 2170.78, 2174.12, 2161.14, 2179.65],
['2013/5/3', 2179.05, 2205.5, 2179.05, 2222.81],
['2013/5/6', 2212.5, 2231.17, 2212.5, 2236.07],
['2013/5/7', 2227.86, 2235.57, 2219.44, 2240.26],
['2013/5/8', 2242.39, 2246.3, 2235.42, 2255.21],
['2013/5/9', 2246.96, 2232.97, 2221.38, 2247.86],
['2013/5/10', 2228.82, 2246.83, 2225.81, 2247.67],
['2013/5/13', 2247.68, 2241.92, 2231.36, 2250.85],
['2013/5/14', 2238.9, 2217.01, 2205.87, 2239.93],
['2013/5/15', 2217.09, 2224.8, 2213.58, 2225.19],
['2013/5/16', 2221.34, 2251.81, 2210.77, 2252.87],
['2013/5/17', 2249.81, 2282.87, 2248.41, 2288.09],
['2013/5/20', 2286.33, 2299.99, 2281.9, 2309.39],
['2013/5/21', 2297.11, 2305.11, 2290.12, 2305.3],
['2013/5/22', 2303.75, 2302.4, 2292.43, 2314.18],
['2013/5/23', 2293.81, 2275.67, 2274.1, 2304.95],
['2013/5/24', 2281.45, 2288.53, 2270.25, 2292.59],
['2013/5/27', 2286.66, 2293.08, 2283.94, 2301.7],
['2013/5/28', 2293.4, 2321.32, 2281.47, 2322.1],
['2013/5/29', 2323.54, 2324.02, 2321.17, 2334.33],
['2013/5/30', 2316.25, 2317.75, 2310.49, 2325.72],
['2013/5/31', 2320.74, 2300.59, 2299.37, 2325.53],
['2013/6/3', 2300.21, 2299.25, 2294.11, 2313.43],
['2013/6/4', 2297.1, 2272.42, 2264.76, 2297.1],
['2013/6/5', 2270.71, 2270.93, 2260.87, 2276.86],
['2013/6/6', 2264.43, 2242.11, 2240.07, 2266.69],
['2013/6/7', 2242.26, 2210.9, 2205.07, 2250.63],
['2013/6/13', 2190.1, 2148.35, 2126.22, 2190.1]
]);
function splitData(rawData) {
const categoryData = [];
const values = [];
for (var i = 0; i < rawData.length; i++) {
categoryData.push(rawData[i].splice(0, 1)[0]);
values.push(rawData[i]);
}
return {
categoryData: categoryData,
values: values
};
}
function calculateMA(dayCount) {
var result = [];
for (var i = 0, len = data0.values.length; i < len; i++) {
if (i < dayCount) {
result.push('-');
continue;
}
var sum = 0;
for (var j = 0; j < dayCount; j++) {
sum += +data0.values[i - j][1];
}
result.push(sum / dayCount);
}
return result;
}
// Echarts便使echarts.connect()
const configecharts = (options = {}) => {
// _echarts_instance_
document.getElementById('main').removeAttribute('_echarts_instance_')
// k线
let chartBox = echarts.init(document.getElementById('main'))
// 使piniaoption
const option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross'
}
},
legend: {
data: ['日K', 'MA5', 'MA10', 'MA20', 'MA30']
},
grid: [{
left: '3%',
right: '3%',
bottom: '5%',
}],
xAxis: {
type: 'category',
data: data0.categoryData,
boundaryGap: false,
axisLine: { onZero: false },
splitLine: { show: false },
min: 'dataMin',
max: 'dataMax'
},
yAxis: {
scale: true,
splitArea: {
show: true
}
},
dataZoom: [
{
type: 'inside',
start: 50,
end: 100
},
{
show: true,
type: 'slider',
top: '90%',
start: 50,
end: 100
}
],
series: [
{
name: '日K',
type: 'candlestick',
data: data0.values,
itemStyle: {
color: upColor,
color0: downColor,
borderColor: upBorderColor,
borderColor0: downBorderColor
},
markPoint: {
label: {
formatter: function (param) {
return param != null ? Math.round(param.value) + '' : '';
}
},
data: [
{
name: 'Mark',
coord: ['2013/5/31', 2300],
value: 2300,
itemStyle: {
color: 'rgb(41,60,85)'
}
},
{
name: 'highest value',
type: 'max',
valueDim: 'highest'
},
{
name: 'lowest value',
type: 'min',
valueDim: 'lowest'
},
{
name: 'average value on close',
type: 'average',
valueDim: 'close'
}
],
tooltip: {
formatter: function (param) {
return param.name + '<br>' + (param.data.coord || '');
}
}
},
markLine: {
symbol: ['none', 'none'],
data: [
[
{
name: 'from lowest to highest',
type: 'min',
valueDim: 'lowest',
symbol: 'circle',
symbolSize: 10,
label: {
show: false
},
emphasis: {
label: {
show: false
}
}
},
{
type: 'max',
valueDim: 'highest',
symbol: 'circle',
symbolSize: 10,
label: {
show: false
},
emphasis: {
label: {
show: false
}
}
}
],
{
name: 'min line on close',
type: 'min',
valueDim: 'close'
},
{
name: 'max line on close',
type: 'max',
valueDim: 'close'
}
]
}
},
{
name: 'MA5',
type: 'line',
data: calculateMA(5),
smooth: true,
lineStyle: {
opacity: 0.5
}
},
{
name: 'MA10',
type: 'line',
data: calculateMA(10),
smooth: true,
lineStyle: {
opacity: 0.5
}
},
{
name: 'MA20',
type: 'line',
data: calculateMA(20),
smooth: true,
lineStyle: {
opacity: 0.5
}
},
{
name: 'MA30',
type: 'line',
data: calculateMA(30),
smooth: true,
lineStyle: {
opacity: 0.5
}
}
]
};
//
chartBox.setOption(option)
// mergeOptions
// ?
chartBox.setOption(options)
//
chartBox.group = 'group1'
//
window.addEventListener('resize', function () {
chartBox.resize()
})
return chartBox
}
//Echarts便使echarts.connect()
const commonecharts = (containerId, options = {}) => {
// _echarts_instance_
document.getElementById(containerId).removeAttribute('_echarts_instance_')
//
const chart = echarts.init(document.getElementById(containerId))
//
const option = {
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
},
yAxis: {
type: 'value',
},
grid: {
top: '10%',
left: '3%',
right: '3%',
bottom: '20%',
},
dataZoom: [
{
type: 'inside',
},
],
series: [
{
data: [820, 932, 901, 934, 1290, 1330, 1320],
type: 'line',
smooth: true,
},
],
}
//
chart.setOption(option)
// mergeOptions
chart.setOption(options)
//
chart.group = 'group1'
//
window.addEventListener('resize', function () {
chartBox2.resize()
})
return chart
}
//
echarts.connect('group1')
onMounted(() => {
dynamicsHeight()
configecharts()
})
onBeforeUnmount(()=>{
echarts.disconnect()
})
</script>
<template>
<div class="box">
<div class="chartsinfo" ref="chartsInfo">
<!-- K线图 -->
<div
id="main"
ref="mKline"
class="flex-item"
:style="{ height: `${heightList[0]}px` }"
></div>
<div
v-if="chartConfigs[0].status"
id="charts1"
ref="charts1"
:style="{ height: `${heightList[1]}px` }"
></div>
<div
v-if="chartConfigs[1].status"
id="charts2"
ref="charts2"
:style="{ height: `${heightList[1]}px` }"
></div>
<div
v-if="chartConfigs[2].status"
id="charts3"
ref="charts3"
:style="{ height: `${heightList[1]}px` }"
></div>
<div
v-if="chartConfigs[3].status"
id="charts4"
ref="charts4"
:style="{ height: `${heightList[1]}px` }"
></div>
<div
v-if="chartConfigs[4].status"
id="charts5"
ref="charts5"
:style="{ height: `${heightList[1]}px` }"
></div>
</div>
<!-- 底部的各个图表选项信息 -->
<ul class="typelist">
<li
v-for="(item, index) in chartConfigs"
:key="index"
@click="addChart(item)"
>
{{ item.name }}
</li>
</ul>
</div>
</template>
<style lang="scss" scoped>
.box {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
.chartsinfo {
height: calc(100vh - 20px);
}
.typelist {
margin-top: auto; // 使 margin-top: auto .typelist
position: relative;
z-index: 99999999;
background-color: #191919;
width: 100%;
color: #afb3b4;
font-size: 12px;
display: flex;
list-style: none;
padding: 0; // padding
}
.typelist > li {
padding: 2px 8px;
cursor: pointer;
}
.active {
color: #2d98b9;
}
</style>

784
src/end/EndDesign.vue Normal file

@ -0,0 +1,784 @@
<script setup>
import { onMounted, inject, ref, nextTick, onUnmounted, onBeforeUnmount, watch } from 'vue'
// pinia
import useEcharts from '@/store/useechartstore'
const echartsState = useEcharts()
echartsState.optionConfigData()
let _options = echartsState.option
//
let szdata = ref([])
let kdata = ref([])
let xdata = ref([])
import request from '@/utils/request'
let baseURL = "http://127.0.0.1:8015"
const redata = () => {
try {
request({
url: baseURL + '/stock',
method: 'get',
params: {
symbol: 'sz000001',
start_date: '2022-01-01',
end_date: '2022-12-31'
}
}).then(res => {
console.log(res);
console.log(typeof res.date);
// szdata.value = res;
xdata.value = Object.values(res.date)
let { open, close, low, high } = res
for (let i = 0; i < Object.keys(open).length; i++) {
kdata.value.push([
open[i],
close[i],
low[i],
high[i],
])
}
// console.log(xdata.value);
// console.log(Object.keys(open).length);
// console.log([open[0],close[0],low[0],high[0]]);
dynamicsHeight()
configecharts()
})
} catch (err) {
console.error('请求失败:', err);
}
};
// const xAxisdata = () => {
// let { date } = szdata.value
// return date
// }
// const fixszdata = () => {
// let array = []
// let { open,close,low,high} = szdata.value
// console.log(szdata.value);
// for (let i = 0; i < open.length; i++) {
// array.push([
// open[i],
// close[i],
// low[i],
// high[i],
// ])
// }
// return array
// }
//echarts
let echarts = inject('echarts')
function generateRandomArray(length, min, max) {
const array = [];
for (let i = 0; i < length; i++) {
const randomNum = Math.floor(Math.random() * (max - min + 1)) + min;
array.push(randomNum);
}
return array;
}
// 使300200280
let randomArray = ref(null)
randomArray.value = generateRandomArray(300, 200, 280);
//
const chartsInfo = ref(null)
// K线
const mKline = ref(null)
//
let heightList = ref([])
//
const dynamicsHeight = () => {
//
let domHeightList = chartsInfo.value.offsetHeight
//
if (clicklist.value.length) {
//
heightList.value = []
//
heightList.value.push(domHeightList * (1 - clicklist.value.length * 0.15))
// K线
mKline.value.style.height = `${heightList.value[0]}px`
//
heightList.value.push(domHeightList * 0.15)
console.log(heightList.value)
} else {
//
heightList.value = []
// K线
mKline.value.style.height = `${domHeightList}px`
}
}
//
let chartConfigs = ref([
{
id: 1,
name: 'MAVOL',
attId: 'charts1',
status: false,
options: {
tooltip: {
trigger: 'axis', //
axisPointer: {
//
type: 'cross', //
label: {
backgroundColor: '#6a7985', //
},
},
},
dataZoom: [
{
type: 'inside',
// xAxisIndex: [0, 0],
// start: 20,
// end: 100,
},
{
type:'slider',
show:false
}
],
xAxis: {
type: 'category',
boundaryGap: false,
data: echartsState.times,
},
yAxis: {
type: 'value',
},
series: [
{
name: 'Email',
type: 'bar',
stack: 'Total',
data: randomArray.value,
}
],
},
},
{
id: 2,
name: 'VOL',
attId: 'charts2',
status: false,
options: {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#6a7985',
},
},
},
dataZoom: [
{
type: 'inside',
// xAxisIndex: [0, 0],
// start: 20,
// end: 100,
},
{
type:'slider',
show:false
}
],
xAxis: [
{
type: 'category',
boundaryGap: false,
data: echartsState.times,
},
],
yAxis: [
{
type: 'value',
},
],
series: [
{
name: 'VOL',
type: 'line',
stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series',
},
data: randomArray.value,
},
// {
// name: 'Union Ads',
// type: 'line',
// stack: 'Total',
// areaStyle: {},
// emphasis: {
// focus: 'series',
// },
// data: [220, 182, 191, 234, 290, 330, 310],
// },
// {
// name: 'Video Ads',
// type: 'line',
// stack: 'Total',
// areaStyle: {},
// emphasis: {
// focus: 'series',
// },
// data: [150, 232, 201, 154, 190, 330, 410],
// },
// {
// name: 'Direct',
// type: 'line',
// stack: 'Total',
// areaStyle: {},
// emphasis: {
// focus: 'series',
// },
// data: [320, 332, 301, 334, 390, 330, 320],
// },
// {
// name: 'Search Engine',
// type: 'line',
// stack: 'Total',
// label: {
// show: true,
// position: 'top',
// },
// areaStyle: {},
// emphasis: {
// focus: 'series',
// },
// data: [820, 932, 901, 934, 1290, 1330, 1320],
// },
],
},
},
{
id: 3,
name: 'MACD',
attId: 'charts3',
status: false,
options:{
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#6a7985',
},
},
},
dataZoom: [
{
type: 'inside',
xAxisIndex: [0, 0],
start: 20,
end: 100,
},
{
type:'slider',
show:false
}
],
xAxis: [
{
type: 'category',
boundaryGap: false,
data: echartsState.times,
},
],
yAxis: [
{
type: 'value',
},
],
series: [
{
name: 'VOL',
type: 'line',
stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series',
},
data: randomArray.value,
},
{
name: 'Union Ads',
type: 'line',
stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series',
},
data: [220, 182, 191, 234, 290, 330, 310],
},
{
name: 'Video Ads',
type: 'line',
stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series',
},
data: [150, 232, 201, 154, 190, 330, 410],
},
{
name: 'Direct',
type: 'line',
stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series',
},
data: [320, 332, 301, 334, 390, 330, 320],
},
{
name: 'Search Engine',
type: 'line',
stack: 'Total',
label: {
show: true,
position: 'top',
},
areaStyle: {},
emphasis: {
focus: 'series',
},
data: [820, 932, 901, 934, 1290, 1330, 1320],
},
],
},
},
{
id: 4,
name: 'KDJ',
attId: 'charts4',
status: false,
options:{
dataZoom: [
{
type: 'inside',
xAxisIndex: [0, 0],
start: 20,
end: 100,
},
{
type:'slider',
show:false
}
],
}
},
{
id: 5,
name: 'RSI',
attId: 'charts5',
status: false,
options:{
dataZoom: [
{
type: 'inside',
xAxisIndex: [0, 0],
start: 20,
end: 100,
},
{
type:'slider',
show:false
}
],
}
},
])
//
const clicklist = ref([])
//
const addChart = (item) => {
//
if (clicklist.value.includes(item.name)) {
//
clicklist.value = clicklist.value.filter((content) => content !== item.name)
// false
chartConfigs.value.forEach((element) => {
if (element.name == item.name) {
element.status = false
}
})
//
dynamicsHeight()
//
nextTick(() => {
chartConfigs.value.forEach((element) => {
if (element.name == item.name) {
element.status = false
// configecharts
configecharts()
}
})
})
} else {
//
clicklist.value.push(item.name)
// true
chartConfigs.value.forEach((element) => {
if (element.name == item.name) {
element.status = true
}
})
//
dynamicsHeight()
//
nextTick(() => {
chartConfigs.value.forEach((element) => {
if (element.name == item.name) {
element.status = true
// configecharts
configecharts()
// commonecharts
commonecharts(item.attId, item.options)
}
})
})
}
}
// Echarts便使echarts.connect()
const configecharts = (options = {}) => {
// _echarts_instance_
document.getElementById('main').removeAttribute('_echarts_instance_')
// k线
let chartBox = echarts.init(document.getElementById('main'))
// 使piniaoption
const option = {
animation: false,
tooltip: {
trigger: 'axis', //
axisPointer: {
//
type: 'cross', //
label: {
backgroundColor: '#6a7985', //
},
animation:false,
},
formatter: (params)=> {
let str = '<div style="padding: 3px 12px;width: 161px;background: #FFFFFF;border: 1px solid #DCDFE6;box-shadow:none; opacity: 1;border-radius: 4px;"><span style="color:#606062;font-size: 12px;">' + params[0].axisValue + "</span><br />";
params.forEach((item) => {
str +=
'<span style="color:#f00;font-size: 12px;color: #1D1D20;"><span style="float:left; margin-top:8px; margin-right:5px;border-radius:50%;width:6px;height:6px;background-color:'+item.color+'"></span>' + "&nbsp;&nbsp;&nbsp;&nbsp;" + item.data + "</span>";
});
str += '</div>'
return str;
// console.log(params[0]);
}
},
legend: {
data: ['KLine', 'MA5'],
},
grid: [{
left: '3%',
right: '3%',
bottom: '5%',
}],
xAxis: [
{
type: 'category',
data: xdata.value,
gridIndex: 0,
scale: true,
boundaryGap: false,
axisLine: { onZero: false },
splitLine: { show: false },
splitNumber: 20,
min: 'dataMin',
max: 'dataMax',
sampling: "lttb", // 线
},
],
yAxis: [
{
gridIndex: 0,
scale: true,
splitArea: {
show: false,
},
},
],
dataZoom: [
{
type:'slider'
},
{
type:'inside'
}
],
series: [
{
name: 'KLine',
type: 'candlestick',
xAxisIndex: 0,
yAxisIndex: 0,
data: kdata.value,
itemStyle: {
normal: {
color: '#ef232a',
color0: '#14b143',
borderColor: '#ef232a',
borderColor0: '#14b143',
},
},
// markArea: {
// silent: true,
// itemStyle: {
// normal: {
// color: 'Honeydew',
// },
// },
// data: [],
// },
// markPoint: {
// data: [
// { type: 'max', name: '' },
// { type: 'min', name: '' },
// ],
// },
// markLine: {
// label: {
// normal: {
// position: 'middle',
// textStyle: { color: 'Blue', fontSize: 12 },
// },
// },
// data: [],
// symbol: ['circle', 'none'],
// },
},
// {
// name: 'MA5',
// type: 'line',
// xAxisIndex: 0,
// yAxisIndex: 0,
// data: [],
// smooth: true,
// lineStyle: {
// normal: {
// opacity: 0.5,
// },
// },
// },
],
}
//
chartBox.setOption(option)
// mergeOptions
// ?
chartBox.setOption(options)
//
chartBox.group = 'group1'
//
window.addEventListener('resize', function(){
chartBox.resize()
})
}
//Echarts便使echarts.connect()
const commonecharts = (containerId, options = {}) => {
// _echarts_instance_
document.getElementById(containerId).removeAttribute('_echarts_instance_')
//
const chart = echarts.init(document.getElementById(containerId))
//
const option = {
xAxis: {
type: 'category',
data: xdata.value,
},
yAxis: {
type: 'value',
},
grid: {
top: '10%',
left: '3%',
right: '3%',
bottom: '20%',
},
dataZoom: [
{
type: 'inside',
},
],
series: [
{
data: randomArray.value,
type: 'line',
smooth: true,
},
],
}
//
chart.setOption(option)
// mergeOptions
chart.setOption(options)
//
chart.group = 'group1'
//
window.addEventListener('resize', function(){
chart.resize()
})
return chart
}
//
echarts.connect('group1')
onMounted(() => {
nextTick(()=>{
// fixszdata()
redata()
// dynamicsHeight()
// configecharts()
})
})
onBeforeUnmount(()=>{
// echarts.disconnect()
})
</script>
<template>
<div class="box">
<div class="chartsinfo" ref="chartsInfo">
<!-- K线图 -->
<div
id="main"
ref="mKline"
class="flex-item"
:style="{ height: `${heightList[0]}px` }"
></div>
<div
v-if="chartConfigs[0].status"
id="charts1"
ref="charts1"
:style="{ height: `${heightList[1]}px` }"
></div>
<div
v-if="chartConfigs[1].status"
id="charts2"
ref="charts2"
:style="{ height: `${heightList[1]}px` }"
></div>
<div
v-if="chartConfigs[2].status"
id="charts3"
ref="charts3"
:style="{ height: `${heightList[1]}px` }"
></div>
<div
v-if="chartConfigs[3].status"
id="charts4"
ref="charts4"
:style="{ height: `${heightList[1]}px` }"
></div>
<div
v-if="chartConfigs[4].status"
id="charts5"
ref="charts5"
:style="{ height: `${heightList[1]}px` }"
></div>
</div>
<!-- 底部的各个图表选项信息 -->
<ul class="typelist">
<li
v-for="(item, index) in chartConfigs"
:key="index"
@click="addChart(item)"
>
{{ item.name }}
</li>
</ul>
</div>
</template>
<style lang="scss" scoped>
.box {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
.chartsinfo {
height: calc(100vh - 20px);
}
.typelist {
margin-top: auto; // 使 margin-top: auto .typelist
position: relative;
z-index: 99999999;
background-color: #191919;
width: 100%;
color: #afb3b4;
font-size: 12px;
display: flex;
list-style: none;
padding: 0; // padding
}
.typelist > li {
padding: 2px 8px;
cursor: pointer;
}
.active {
color: #2d98b9;
}
</style>

21
src/main.js Normal file

@ -0,0 +1,21 @@
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
// 引入 createPinia 函数
import { createPinia } from 'pinia'
// 引入echarts
import echarts from './utils/echarts';
const app = createApp(App)
app.use(createPinia())
app.config.globalProperties.$echarts = echarts
app.use(router)
app.mount('#app')

48
src/router/index.js Normal file

@ -0,0 +1,48 @@
import { createRouter, createWebHashHistory } from 'vue-router'
const router = createRouter({
history: createWebHashHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/',
name: 'home',
redirect: '/hour-line',
component: () => import('@/views/HomeView.vue'),
children: [
{
path: 'hour-line',
name: 'hour-line',
component: () => import('@/end/EndDesign.vue')
},
{
path: 'day-line',
name: 'day-line',
component: () => import('@/end/DayDesign.vue')
},
{
path: 'week-line',
name: 'week-line',
component: () => import('@/end/DayDesign.vue')
},
{
path: 'month-line',
name: 'month-line',
component: () => import('@/end/DayDesign.vue')
},
{
path: 'year-line',
name: 'year-line',
component: () => import('@/end/DayDesign.vue')
},
]
},
{
path: '/test',
name: 'test',
component: () => import('@/components/NewFather.vue'),
}
],
})
export default router

557
src/store/useechartstore.js Normal file

@ -0,0 +1,557 @@
import { defineStore } from 'pinia'
//数组处理
function splitData (rawData) {
var datas = []
var times = []
var vols = []
var macds = []
var difs = []
var deas = []
for (var i = 0; i < rawData.length; i++) {
datas.push(rawData[i])
times.push(rawData[i].splice(0, 1)[0])
vols.push(rawData[i][4])
macds.push(rawData[i][6])
difs.push(rawData[i][7])
deas.push(rawData[i][8])
}
return {
datas: datas,
times: times,
vols: vols,
macds: macds,
difs: difs,
deas: deas,
}
}
//分段计算
function fenduans (data) {
var markLineData = []
var idx = 0
var tag = 0
var vols = 0
for (var i = 0; i < data.times.length; i++) {
//初始化数据
if (data.datas[i][5] != 0 && tag == 0) {
idx = i
vols = data.datas[i][4]
tag = 1
}
if (tag == 1) {
vols += data.datas[i][4]
}
if (data.datas[i][5] != 0 && tag == 1) {
markLineData.push([
{
xAxis: idx,
yAxis:
data.datas[idx][1] > data.datas[idx][0]
? data.datas[idx][3].toFixed(2)
: data.datas[idx][2].toFixed(2),
value: vols,
},
{
xAxis: i,
yAxis:
data.datas[i][1] > data.datas[i][0]
? data.datas[i][3].toFixed(2)
: data.datas[i][2].toFixed(2),
},
])
idx = i
vols = data.datas[i][4]
tag = 2
}
//更替数据
if (tag == 2) {
vols += data.datas[i][4]
}
if (data.datas[i][5] != 0 && tag == 2) {
markLineData.push([
{
xAxis: idx,
yAxis:
data.datas[idx][1] > data.datas[idx][0]
? data.datas[idx][3].toFixed(2)
: data.datas[idx][2].toFixed(2),
value: (vols / (i - idx + 1)).toFixed(2) + ' M',
},
{
xAxis: i,
yAxis:
data.datas[i][1] > data.datas[i][0]
? data.datas[i][3].toFixed(2)
: data.datas[i][2].toFixed(2),
},
])
idx = i
vols = data.datas[i][4]
}
}
return markLineData
}
//MA计算公式
function calculateMA (data, dayCount) {
var result = []
for (var i = 0, len = data.times.length; i < len; i++) {
if (i < dayCount) {
result.push('-')
continue
}
var sum = 0
for (var j = 0; j < dayCount; j++) {
sum += data.datas[i - j][1]
}
result.push((sum / dayCount).toFixed(2))
}
return result
}
const useEcharts = defineStore("user", {
state: () => ({
datas: [],
times: [],
vols: [],
macds: [],
difs: [],
deas: [],
//子页面信息
addedCharts: [],
option: {
animation: false,
tooltip: {
trigger: 'axis', // 触发类型为坐标轴
axisPointer: {
// 坐标轴指示器
type: 'cross', // 类型为交叉
label: {
backgroundColor: '#6a7985', // 标签背景色
},
animation:false,
},
},
legend: {
data: ['KLine', 'MA5'],
},
grid: [{
left: '3%',
right: '3%',
bottom: '5%',
}],
xAxis: [
{
type: 'category',
data: [],
gridIndex: 0,
scale: true,
boundaryGap: false,
axisLine: { onZero: false },
splitLine: { show: false },
splitNumber: 20,
min: 'dataMin',
max: 'dataMax',
sampling: "lttb", // 最大程度保证采样后线条的趋势,形状和极值。
},
],
yAxis: [
{
gridIndex: 0,
scale: true,
splitArea: {
show: false,
},
},
],
dataZoom: [
{
type:'slider'
},
{
type:'inside'
}
],
series: [
{
name: 'KLine',
type: 'candlestick',
xAxisIndex: 0,
yAxisIndex: 0,
data: [],
itemStyle: {
normal: {
color: '#ef232a',
color0: '#14b143',
borderColor: '#ef232a',
borderColor0: '#14b143',
},
},
markArea: {
silent: true,
itemStyle: {
normal: {
color: 'Honeydew',
},
},
data: [],
},
markPoint: {
data: [
{ type: 'max', name: '最大值' },
{ type: 'min', name: '最小值' },
],
},
markLine: {
label: {
normal: {
position: 'middle',
textStyle: { color: 'Blue', fontSize: 12 },
},
},
data: [],
symbol: ['circle', 'none'],
},
},
{
name: 'MA5',
type: 'line',
xAxisIndex: 0,
yAxisIndex: 0,
data: [],
smooth: true,
lineStyle: {
normal: {
opacity: 0.5,
},
},
},
],
},
}),
actions: {
optionConfigData () {
let data = splitData([
['2015-10-16', 18.4, 18.58, 18.33, 18.79, 67.0, 1, 0.04, 0.11, 0.09],
['2015-10-19', 18.56, 18.25, 18.19, 18.56, 55.0, 0, -0.0, 0.08, 0.09],
['2015-10-20', 18.3, 18.22, 18.05, 18.41, 37.0, 0, 0.01, 0.09, 0.09],
['2015-10-21', 18.18, 18.69, 18.02, 18.98, 89.0, 0, 0.03, 0.1, 0.08],
['2015-10-22', 18.42, 18.29, 18.22, 18.48, 43.0, 0, -0.06, 0.05, 0.08],
['2015-10-23', 18.26, 18.19, 18.08, 18.36, 46.0, 0, -0.1, 0.03, 0.09],
['2015-10-26', 18.33, 18.07, 17.98, 18.35, 65.0, 0, -0.15, 0.03, 0.1],
['2015-10-27', 18.08, 18.04, 17.88, 18.13, 37.0, 0, -0.19, 0.03, 0.12],
['2015-10-28', 17.96, 17.86, 17.82, 17.99, 35.0, 0, -0.24, 0.03, 0.15],
['2015-10-29', 17.85, 17.81, 17.8, 17.93, 27.0, 0, -0.24, 0.06, 0.18],
['2015-10-30', 17.79, 17.93, 17.78, 18.08, 43.0, 0, -0.22, 0.11, 0.22],
['2015-11-02', 17.78, 17.83, 17.78, 18.04, 27.0, 0, -0.2, 0.15, 0.25],
['2015-11-03', 17.84, 17.9, 17.84, 18.06, 34.0, 0, -0.12, 0.22, 0.28],
['2015-11-04', 17.97, 18.36, 17.85, 18.39, 62.0, 0, -0.0, 0.3, 0.3],
['2015-11-05', 18.3, 18.57, 18.18, 19.08, 177.0, 0, 0.07, 0.33, 0.3],
['2015-11-06', 18.53, 18.68, 18.3, 18.71, 95.0, 0, 0.12, 0.35, 0.29],
['2015-11-09', 18.75, 19.08, 18.75, 19.98, 202.0, 1, 0.16, 0.35, 0.27],
['2015-11-10', 18.85, 18.64, 18.56, 18.99, 85.0, 0, 0.09, 0.29, 0.25],
['2015-11-11', 18.64, 18.44, 18.31, 18.64, 50.0, 0, 0.06, 0.27, 0.23],
['2015-11-12', 18.55, 18.27, 18.17, 18.57, 43.0, 0, 0.05, 0.25, 0.23],
['2015-11-13', 18.13, 18.14, 18.09, 18.34, 35.0, 0, 0.05, 0.24, 0.22],
['2015-11-16', 18.01, 18.1, 17.93, 18.17, 34.0, 0, 0.07, 0.25, 0.21],
['2015-11-17', 18.2, 18.14, 18.08, 18.45, 58.0, 0, 0.11, 0.25, 0.2],
['2015-11-18', 18.23, 18.16, 18.0, 18.45, 47.0, 0, 0.13, 0.25, 0.19],
['2015-11-19', 18.08, 18.2, 18.05, 18.25, 32.0, 0, 0.15, 0.24, 0.17],
['2015-11-20', 18.15, 18.15, 18.11, 18.29, 36.0, 0, 0.13, 0.21, 0.15],
['2015-11-23', 18.16, 18.19, 18.12, 18.34, 47.0, 0, 0.11, 0.18, 0.13],
['2015-11-24', 18.23, 17.88, 17.7, 18.23, 62.0, 0, 0.03, 0.13, 0.11],
['2015-11-25', 17.85, 17.73, 17.56, 17.85, 66.0, 0, -0.03, 0.09, 0.11],
['2015-11-26', 17.79, 17.53, 17.5, 17.92, 63.0, 0, -0.1, 0.06, 0.11],
['2015-11-27', 17.51, 17.04, 16.9, 17.51, 67.0, 0, -0.16, 0.05, 0.13],
['2015-11-30', 17.07, 17.2, 16.98, 17.32, 55.0, 0, -0.12, 0.09, 0.15],
['2015-12-01', 17.28, 17.11, 16.91, 17.28, 39.0, 0, -0.09, 0.12, 0.16],
['2015-12-02', 17.13, 17.91, 17.05, 17.99, 102.0, 0, -0.01, 0.17, 0.18],
['2015-12-03', 17.8, 17.78, 17.61, 17.98, 71.0, 0, -0.09, 0.14, 0.18],
['2015-12-04', 17.6, 17.25, 17.13, 17.69, 51.0, 0, -0.18, 0.1, 0.19],
['2015-12-07', 17.2, 17.39, 17.15, 17.45, 43.0, 0, -0.19, 0.12, 0.22],
['2015-12-08', 17.3, 17.42, 17.18, 17.62, 45.0, 0, -0.23, 0.13, 0.24],
['2015-12-09', 17.33, 17.39, 17.32, 17.59, 44.0, 0, -0.29, 0.13, 0.28],
['2015-12-10', 17.39, 17.26, 17.21, 17.65, 44.0, 0, -0.37, 0.13, 0.32],
['2015-12-11', 17.23, 16.92, 16.66, 17.26, 114.0, 1, -0.44, 0.15, 0.37],
['2015-12-14', 16.75, 17.06, 16.5, 17.09, 94.0, 0, -0.44, 0.21, 0.44],
['2015-12-15', 17.03, 17.03, 16.9, 17.06, 46.0, 0, -0.44, 0.28, 0.5],
['2015-12-16', 17.08, 16.96, 16.87, 17.09, 30.0, 0, -0.4, 0.36, 0.56],
['2015-12-17', 17.0, 17.1, 16.95, 17.12, 50.0, 0, -0.3, 0.47, 0.62],
['2015-12-18', 17.09, 17.52, 17.04, 18.06, 156.0, 0, -0.14, 0.59, 0.66],
['2015-12-21', 17.43, 18.23, 17.35, 18.45, 152.0, 1, 0.02, 0.69, 0.68],
['2015-12-22', 18.14, 18.27, 18.06, 18.32, 94.0, 0, 0.08, 0.72, 0.68],
['2015-12-23', 18.28, 18.19, 18.17, 18.71, 108.0, 0, 0.13, 0.73, 0.67],
['2015-12-24', 18.18, 18.14, 18.01, 18.31, 37.0, 0, 0.19, 0.74, 0.65],
['2015-12-25', 18.22, 18.33, 18.2, 18.36, 48.0, 0, 0.26, 0.75, 0.62],
['2015-12-28', 18.35, 17.84, 17.8, 18.39, 48.0, 0, 0.27, 0.72, 0.59],
['2015-12-29', 17.83, 17.94, 17.71, 17.97, 36.0, 0, 0.36, 0.73, 0.55],
['2015-12-30', 17.9, 18.26, 17.55, 18.3, 71.0, 1, 0.43, 0.71, 0.5],
['2015-12-31', 18.12, 17.99, 17.91, 18.33, 72.0, 0, 0.4, 0.63, 0.43],
['2016-01-04', 17.91, 17.28, 17.16, 17.95, 37.0, 1, 0.34, 0.55, 0.38],
['2016-01-05', 17.17, 17.23, 17.0, 17.55, 51.0, 0, 0.37, 0.51, 0.33],
['2016-01-06', 17.2, 17.31, 17.06, 17.33, 31.0, 0, 0.37, 0.46, 0.28],
['2016-01-07', 17.15, 16.67, 16.51, 17.15, 19.0, 0, 0.3, 0.37, 0.22],
['2016-01-08', 16.8, 16.81, 16.61, 17.06, 60.0, 0, 0.29, 0.32, 0.18],
['2016-01-11', 16.68, 16.04, 16.0, 16.68, 65.0, 0, 0.2, 0.24, 0.14],
['2016-01-12', 16.03, 15.98, 15.88, 16.25, 46.0, 0, 0.2, 0.21, 0.11],
['2016-01-13', 16.21, 15.87, 15.78, 16.21, 57.0, 0, 0.2, 0.18, 0.08],
['2016-01-14', 15.55, 15.89, 15.52, 15.96, 42.0, 0, 0.2, 0.16, 0.05],
['2016-01-15', 15.87, 15.48, 15.45, 15.92, 34.0, 1, 0.17, 0.11, 0.02],
['2016-01-18', 15.39, 15.42, 15.36, 15.7, 26.0, 0, 0.21, 0.1, -0.0],
['2016-01-19', 15.58, 15.71, 15.35, 15.77, 38.0, 0, 0.25, 0.09, -0.03],
['2016-01-20', 15.56, 15.52, 15.24, 15.68, 38.0, 0, 0.23, 0.05, -0.07],
['2016-01-21', 15.41, 15.3, 15.28, 15.68, 35.0, 0, 0.21, 0.0, -0.1],
['2016-01-22', 15.48, 15.28, 15.13, 15.49, 30.0, 0, 0.21, -0.02, -0.13],
['2016-01-25', 15.29, 15.48, 15.2, 15.49, 21.0, 0, 0.2, -0.06, -0.16],
['2016-01-26', 15.33, 14.86, 14.78, 15.39, 30.0, 0, 0.12, -0.13, -0.19],
['2016-01-27', 14.96, 15.0, 14.84, 15.22, 51.0, 0, 0.13, -0.14, -0.2],
['2016-01-28', 14.96, 14.72, 14.62, 15.06, 25.0, 0, 0.1, -0.17, -0.22],
['2016-01-29', 14.75, 14.99, 14.62, 15.08, 36.0, 0, 0.13, -0.17, -0.24],
['2016-02-01', 14.98, 14.72, 14.48, 15.18, 27.0, 0, 0.1, -0.21, -0.26],
['2016-02-02', 14.65, 14.85, 14.65, 14.95, 18.0, 0, 0.11, -0.21, -0.27],
['2016-02-03', 14.72, 14.67, 14.55, 14.8, 23.0, 0, 0.1, -0.24, -0.29],
['2016-02-04', 14.79, 14.88, 14.69, 14.93, 22.0, 0, 0.13, -0.24, -0.3],
['2016-02-05', 14.9, 14.86, 14.78, 14.93, 16.0, 0, 0.12, -0.26, -0.32],
['2016-02-15', 14.5, 14.66, 14.47, 14.82, 19.0, 0, 0.11, -0.28, -0.34],
['2016-02-16', 14.77, 14.94, 14.72, 15.05, 26.0, 0, 0.14, -0.28, -0.35],
['2016-02-17', 14.95, 15.03, 14.88, 15.07, 38.0, 0, 0.12, -0.31, -0.37],
['2016-02-18', 14.95, 14.9, 14.87, 15.06, 28.0, 0, 0.07, -0.35, -0.39],
['2016-02-19', 14.9, 14.75, 14.68, 14.94, 22.0, 0, 0.03, -0.38, -0.4],
['2016-02-22', 14.88, 15.01, 14.79, 15.11, 38.0, 1, 0.01, -0.4, -0.4],
['2016-02-23', 15.01, 14.83, 14.72, 15.01, 24.0, 0, -0.09, -0.45, -0.4],
['2016-02-24', 14.75, 14.81, 14.67, 14.87, 21.0, 0, -0.17, -0.48, -0.39],
['2016-02-25', 14.81, 14.25, 14.21, 14.81, 51.0, 1, -0.27, -0.5, -0.37],
['2016-02-26', 14.35, 14.45, 14.28, 14.57, 28.0, 0, -0.26, -0.46, -0.33],
['2016-02-29', 14.43, 14.56, 14.04, 14.6, 48.0, 0, -0.25, -0.41, -0.29],
['2016-03-01', 14.56, 14.65, 14.36, 14.78, 32.0, 0, -0.21, -0.36, -0.25],
['2016-03-02', 14.79, 14.96, 14.72, 14.97, 60.0, 0, -0.13, -0.29, -0.22],
['2016-03-03', 14.95, 15.15, 14.91, 15.19, 53.0, 1, -0.05, -0.23, -0.21],
['2016-03-04', 15.14, 15.97, 15.02, 16.02, 164.0, 1, 0.06, -0.17, -0.2],
['2016-03-07', 15.9, 15.78, 15.65, 16.0, 41.0, 0, 0.04, -0.19, -0.21],
['2016-03-08', 15.78, 15.96, 15.21, 15.99, 45.0, 0, 0.05, -0.19, -0.21],
['2016-03-09', 15.73, 16.05, 15.41, 16.08, 74.0, 0, 0.03, -0.2, -0.22],
['2016-03-10', 15.82, 15.66, 15.65, 15.98, 19.0, 0, -0.02, -0.23, -0.22],
['2016-03-11', 15.59, 15.76, 15.42, 15.78, 32.0, 0, 0.01, -0.22, -0.22],
['2016-03-14', 15.78, 15.72, 15.65, 16.04, 31.0, 0, 0.03, -0.2, -0.22],
['2016-03-15', 15.81, 15.86, 15.6, 15.99, 35.0, 0, 0.1, -0.18, -0.23],
['2016-03-16', 15.88, 16.42, 15.79, 16.45, 123.0, 0, 0.17, -0.16, -0.24],
['2016-03-17', 16.39, 16.23, 16.11, 16.4, 46.0, 0, 0.14, -0.2, -0.26],
['2016-03-18', 16.39, 16.17, 16.04, 16.4, 59.0, 0, 0.13, -0.22, -0.28],
['2016-03-21', 16.21, 16.22, 16.11, 16.44, 50.0, 0, 0.12, -0.24, -0.3],
['2016-03-22', 16.27, 16.19, 16.16, 16.42, 33.0, 0, 0.1, -0.27, -0.32],
['2016-03-23', 16.26, 16.18, 16.18, 16.29, 19.0, 0, 0.08, -0.3, -0.33],
['2016-03-24', 16.18, 16.11, 16.01, 16.23, 23.0, 0, 0.04, -0.33, -0.35],
['2016-03-25', 16.12, 16.13, 16.1, 16.2, 15.0, 0, 0.0, -0.35, -0.35],
['2016-03-28', 16.15, 15.85, 15.81, 16.2, 22.0, 0, -0.06, -0.38, -0.35],
['2016-03-29', 15.9, 15.79, 15.76, 16.05, 19.0, 0, -0.06, -0.37, -0.34],
['2016-03-30', 15.79, 16.24, 15.78, 16.3, 29.0, 0, -0.03, -0.35, -0.33],
['2016-03-31', 16.3, 16.09, 16.02, 16.35, 25.0, 0, -0.07, -0.37, -0.33],
['2016-04-01', 16.18, 16.27, 15.98, 16.3, 38.0, 0, -0.08, -0.36, -0.32],
['2016-04-05', 16.13, 16.34, 16.07, 16.37, 39.0, 0, -0.13, -0.37, -0.31],
['2016-04-06', 16.21, 16.26, 16.19, 16.35, 30.0, 0, -0.2, -0.39, -0.29],
['2016-04-07', 16.32, 16.1, 16.05, 16.35, 29.0, 1, -0.26, -0.39, -0.26],
['2016-04-08', 16.0, 16.16, 15.98, 16.21, 22.0, 0, -0.28, -0.37, -0.23],
['2016-04-11', 16.16, 16.31, 16.15, 16.57, 31.0, 0, -0.3, -0.33, -0.19],
['2016-04-12', 16.41, 16.29, 16.12, 16.41, 17.0, 0, -0.31, -0.3, -0.14],
['2016-04-13', 16.39, 16.48, 16.0, 16.68, 40.0, 0, -0.3, -0.25, -0.1],
['2016-04-14', 16.5, 16.46, 16.37, 16.68, 22.0, 0, -0.27, -0.19, -0.06],
['2016-04-15', 16.56, 16.93, 16.46, 17.04, 58.0, 0, -0.2, -0.12, -0.02],
['2016-04-18', 16.76, 17.06, 16.72, 17.27, 50.0, 0, -0.16, -0.07, 0.01],
['2016-04-19', 17.21, 17.11, 17.02, 17.23, 30.0, 0, -0.12, -0.02, 0.03],
['2016-04-20', 17.11, 17.33, 16.8, 17.36, 78.0, 0, -0.04, 0.03, 0.05],
['2016-04-21', 17.27, 17.69, 17.17, 17.93, 79.0, 0, 0.05, 0.08, 0.06],
['2016-04-22', 17.6, 17.87, 17.56, 18.02, 55.0, 0, 0.09, 0.1, 0.05],
['2016-04-25', 17.75, 17.9, 17.41, 17.96, 39.0, 1, 0.11, 0.09, 0.04],
['2016-04-26', 17.81, 17.91, 17.6, 17.95, 39.0, 0, 0.12, 0.08, 0.02],
['2016-04-27', 17.9, 17.88, 17.81, 17.95, 25.0, 0, 0.12, 0.06, 0.0],
['2016-04-28', 17.93, 17.88, 17.67, 17.93, 28.0, 0, 0.11, 0.04, -0.01],
['2016-04-29', 17.87, 17.75, 17.73, 17.92, 19.0, 0, 0.08, 0.01, -0.03],
['2016-05-03', 17.79, 17.7, 17.56, 17.85, 35.0, 0, 0.05, -0.01, -0.04],
['2016-05-04', 17.7, 17.65, 17.59, 17.71, 24.0, 0, 0.02, -0.04, -0.05],
['2016-05-05', 17.65, 17.62, 17.46, 17.7, 20.0, 0, -0.03, -0.06, -0.05],
['2016-05-06', 17.62, 17.32, 17.3, 17.65, 29.0, 0, -0.1, -0.09, -0.05],
['2016-05-09', 17.33, 17.3, 17.21, 17.45, 23.0, 0, -0.13, -0.1, -0.03],
['2016-05-10', 17.11, 17.04, 16.98, 17.41, 28.0, 0, -0.15, -0.09, -0.01],
['2016-05-11', 17.06, 17.15, 17.06, 17.32, 20.0, 0, -0.12, -0.05, 0.01],
['2016-05-12', 17.02, 17.46, 17.02, 17.58, 26.0, 0, -0.07, -0.01, 0.03],
['2016-05-13', 17.41, 17.57, 17.34, 17.62, 23.0, 0, -0.06, 0.01, 0.03],
['2016-05-16', 17.55, 17.5, 17.48, 17.64, 37.0, 0, -0.06, 0.01, 0.04],
['2016-05-17', 17.49, 17.48, 17.39, 17.53, 13.0, 0, -0.03, 0.03, 0.05],
['2016-05-18', 17.41, 17.82, 17.39, 17.87, 46.0, 0, 0.01, 0.06, 0.06],
['2016-05-19', 17.74, 17.81, 17.67, 17.86, 17.0, 0, -0.01, 0.05, 0.05],
['2016-05-20', 17.76, 17.88, 17.7, 17.93, 14.0, 0, -0.03, 0.04, 0.06],
['2016-05-23', 17.88, 17.52, 17.48, 17.97, 16.0, 0, -0.09, 0.02, 0.06],
['2016-05-24', 17.51, 17.33, 17.32, 17.51, 8.0, 0, -0.09, 0.03, 0.07],
['2016-05-25', 17.59, 17.55, 17.44, 17.59, 10.0, 0, -0.03, 0.07, 0.08],
['2016-05-26', 17.5, 17.69, 17.5, 17.8, 12.0, 0, 0.0, 0.09, 0.09],
['2016-05-27', 17.77, 17.66, 17.62, 17.77, 7.0, 0, 0.03, 0.1, 0.09],
['2016-05-30', 17.75, 17.84, 17.62, 17.87, 20.0, 0, 0.08, 0.12, 0.08],
['2016-05-31', 17.88, 18.0, 17.81, 18.03, 41.0, 0, 0.1, 0.12, 0.07],
['2016-06-01', 18.09, 17.83, 17.73, 18.09, 22.0, 0, 0.08, 0.1, 0.06],
['2016-06-02', 17.82, 17.73, 17.66, 17.88, 10.0, 0, 0.07, 0.08, 0.05],
['2016-06-03', 17.8, 17.78, 17.71, 17.83, 9.0, 0, 0.08, 0.08, 0.04],
['2016-06-06', 17.73, 17.64, 17.56, 17.83, 12.0, 0, 0.07, 0.06, 0.03],
['2016-06-07', 17.76, 17.8, 17.59, 17.87, 11.0, 0, 0.08, 0.06, 0.02],
['2016-06-08', 17.75, 17.77, 17.65, 17.84, 9.0, 0, 0.04, 0.03, 0.01],
['2016-06-13', 17.58, 17.32, 17.29, 17.79, 16.0, 0, -0.02, -0.01, 0.0],
['2016-06-14', 17.33, 17.38, 17.29, 17.5, 10.0, 0, -0.01, 0.0, 0.0],
['2016-06-15', 17.25, 17.39, 17.25, 17.46, 18.0, 0, 0.0, 0.01, 0.0],
['2016-06-16', 17.26, 17.4, 17.26, 17.46, 22.0, 0, 0.01, 0.01, 0.0],
['2016-06-17', 17.38, 17.5, 17.37, 17.67, 13.0, 0, 0.03, 0.02, 0.0],
['2016-06-20', 17.62, 17.51, 17.42, 17.63, 15.0, 0, 0.03, 0.01, -0.0],
['2016-06-21', 17.53, 17.54, 17.5, 17.7, 11.0, 0, 0.02, 0.0, -0.01],
['2016-06-22', 17.5, 17.5, 17.46, 17.6, 10.0, 0, -0.01, -0.01, -0.01],
['2016-06-23', 17.52, 17.26, 17.24, 17.53, 16.0, 0, -0.04, -0.03, -0.01],
['2016-06-24', 17.26, 17.25, 17.18, 17.38, 60.0, 0, -0.03, -0.02, -0.0],
['2016-06-27', 17.25, 17.28, 17.18, 17.33, 19.0, 0, -0.01, -0.0, 0.0],
['2016-06-28', 17.25, 17.29, 17.21, 17.32, 13.0, 0, 0.02, 0.01, 0.0],
['2016-06-29', 17.31, 17.45, 17.27, 17.49, 21.0, 0, 0.07, 0.04, 0.0],
['2016-06-30', 17.47, 17.5, 17.39, 17.55, 17.0, 0, 0.11, 0.04, -0.01],
['2016-07-01', 17.5, 17.63, 17.49, 17.66, 10.0, 0, 0.14, 0.05, -0.03],
['2016-07-04', 17.63, 17.72, 17.63, 17.92, 17.0, 0, 0.16, 0.03, -0.05],
['2016-07-05', 17.79, 17.56, 17.45, 17.79, 18.0, 0, 0.14, 0.0, -0.07],
['2016-07-06', 17.53, 17.42, 17.31, 17.54, 20.0, 0, 0.14, -0.02, -0.09],
['2016-07-07', 17.41, 17.51, 17.35, 17.52, 15.0, 0, 0.16, -0.03, -0.11],
['2016-07-08', 17.5, 17.39, 17.35, 17.51, 15.0, 0, 0.16, -0.05, -0.13],
['2016-07-11', 17.49, 17.48, 17.4, 17.55, 16.0, 0, 0.17, -0.07, -0.15],
['2016-07-12', 17.48, 17.71, 17.46, 17.75, 25.0, 0, 0.16, -0.1, -0.18],
['2016-07-13', 17.13, 17.05, 17.02, 17.39, 28.0, 0, 0.07, -0.17, -0.2],
['2016-07-14', 17.07, 17.09, 17.0, 17.16, 12.0, 0, 0.08, -0.17, -0.21],
['2016-07-15', 17.08, 17.14, 17.08, 17.17, 11.0, 0, 0.09, -0.18, -0.22],
['2016-07-18', 17.15, 17.26, 17.13, 17.49, 24.0, 0, 0.1, -0.19, -0.23],
['2016-07-19', 17.26, 17.12, 17.09, 17.33, 13.0, 0, 0.07, -0.21, -0.25],
['2016-07-20', 17.1, 17.07, 17.02, 17.14, 11.0, 0, 0.06, -0.23, -0.26],
['2016-07-21', 17.07, 17.24, 17.07, 17.27, 14.0, 0, 0.07, -0.23, -0.27],
['2016-07-22', 17.25, 17.08, 17.03, 17.25, 10.0, 0, 0.04, -0.26, -0.28],
['2016-07-25', 17.09, 17.12, 17.01, 17.18, 8.0, 0, 0.04, -0.26, -0.28],
['2016-07-26', 17.05, 17.17, 17.05, 17.2, 11.0, 0, 0.04, -0.27, -0.29],
['2016-07-27', 17.2, 17.37, 16.89, 17.38, 32.0, 0, 0.02, -0.28, -0.29],
['2016-07-28', 17.19, 17.14, 17.09, 17.29, 19.0, 0, -0.04, -0.32, -0.3],
['2016-07-29', 17.15, 17.16, 17.04, 17.23, 12.0, 0, -0.08, -0.33, -0.29],
['2016-08-01', 17.15, 17.18, 17.1, 17.24, 19.0, 0, -0.13, -0.34, -0.28],
['2016-08-02', 17.21, 17.15, 17.12, 17.25, 9.0, 0, -0.19, -0.36, -0.26],
['2016-08-03', 17.08, 17.07, 17.01, 17.16, 9.0, 0, -0.25, -0.36, -0.24],
['2016-08-04', 17.11, 17.06, 16.98, 17.12, 11.0, 1, -0.29, -0.35, -0.2],
['2016-08-05', 17.06, 17.1, 17.05, 17.15, 16.0, 0, -0.33, -0.32, -0.16],
['2016-08-08', 17.14, 17.13, 17.07, 17.15, 13.0, 0, -0.35, -0.29, -0.11],
['2016-08-09', 17.13, 17.17, 17.1, 17.2, 25.0, 0, -0.35, -0.24, -0.06],
['2016-08-10', 17.17, 17.28, 17.15, 17.29, 18.0, 0, -0.31, -0.17, -0.01],
['2016-08-11', 17.3, 17.45, 17.26, 17.87, 31.0, 0, -0.24, -0.09, 0.03],
['2016-08-12', 17.51, 17.99, 17.47, 18.0, 44.0, 0, -0.14, -0.0, 0.07],
['2016-08-15', 18.1, 18.42, 18.02, 18.99, 81.0, 0, -0.09, 0.04, 0.09],
['2016-08-16', 18.64, 18.31, 18.12, 18.87, 60.0, 0, -0.1, 0.05, 0.1],
['2016-08-17', 18.43, 18.4, 18.31, 18.68, 21.0, 0, -0.08, 0.08, 0.11],
['2016-08-18', 18.33, 18.23, 18.13, 18.65, 32.0, 0, -0.07, 0.09, 0.13],
['2016-08-19', 18.34, 18.62, 18.31, 18.75, 39.0, 0, 0.0, 0.14, 0.14],
['2016-08-22', 18.62, 18.69, 18.51, 18.8, 20.0, 0, 0.01, 0.14, 0.13],
['2016-08-23', 18.61, 18.66, 18.52, 19.0, 28.0, 0, 0.01, 0.14, 0.13],
['2016-08-24', 18.66, 18.62, 18.43, 18.7, 19.0, 0, 0.0, 0.13, 0.13],
['2016-08-25', 18.57, 18.51, 18.19, 18.64, 19.0, 0, -0.0, 0.13, 0.13],
['2016-08-26', 18.49, 18.55, 18.44, 18.6, 16.0, 0, 0.01, 0.13, 0.13],
['2016-08-29', 18.46, 18.27, 18.03, 18.48, 20.0, 0, 0.01, 0.13, 0.13],
['2016-08-30', 18.24, 18.44, 18.23, 18.52, 19.0, 0, 0.07, 0.17, 0.13],
['2016-08-31', 18.36, 18.63, 18.36, 18.76, 15.0, 0, 0.13, 0.18, 0.12],
['2016-09-01', 18.6, 18.62, 18.55, 18.78, 15.0, 0, 0.16, 0.18, 0.1],
['2016-09-02', 18.52, 18.68, 18.48, 18.72, 17.0, 0, 0.19, 0.17, 0.08],
['2016-09-05', 18.68, 18.75, 18.57, 18.82, 19.0, 0, 0.2, 0.15, 0.05],
['2016-09-06', 18.75, 18.51, 18.43, 18.78, 17.0, 0, 0.18, 0.11, 0.02],
['2016-09-07', 18.51, 18.56, 18.4, 18.62, 17.0, 0, 0.17, 0.08, -0.0],
['2016-09-08', 18.58, 18.53, 18.48, 18.63, 8.0, 0, 0.13, 0.04, -0.03],
['2016-09-09', 18.52, 18.33, 18.31, 18.57, 8.0, 0, 0.06, -0.02, -0.05],
['2016-09-12', 18.16, 17.9, 17.81, 18.18, 28.0, 0, -0.02, -0.07, -0.06],
['2016-09-13', 17.91, 17.91, 17.9, 18.08, 13.0, 0, -0.05, -0.08, -0.05],
['2016-09-14', 17.99, 17.54, 17.48, 17.99, 22.0, 0, -0.09, -0.09, -0.05],
['2016-09-19', 17.55, 17.81, 17.55, 17.88, 16.0, 0, -0.06, -0.06, -0.03],
['2016-09-20', 17.8, 17.74, 17.67, 17.85, 10.0, 0, -0.06, -0.05, -0.02],
['2016-09-21', 17.75, 17.88, 17.75, 17.95, 7.0, 0, -0.03, -0.03, -0.02],
['2016-09-22', 17.99, 17.97, 17.88, 18.17, 12.0, 0, -0.02, -0.02, -0.01],
['2016-09-23', 17.99, 17.98, 17.93, 18.09, 13.0, 0, -0.01, -0.01, -0.01],
['2016-09-26', 17.91, 18.0, 17.85, 18.09, 14.0, 0, -0.0, -0.01, -0.01],
['2016-09-27', 17.97, 18.07, 17.94, 18.1, 10.0, 0, 0.0, -0.01, -0.01],
['2016-09-28', 18.06, 17.89, 17.83, 18.06, 10.0, 0, -0.0, -0.01, -0.01],
['2016-09-29', 17.96, 18.0, 17.92, 18.07, 10.0, 0, 0.03, 0.01, -0.01],
['2016-09-30', 17.96, 18.0, 17.95, 18.1, 8.0, 0, 0.06, 0.02, -0.01],
['2016-10-10', 18.03, 18.3, 18.03, 18.38, 19.0, 0, 0.11, 0.04, -0.02],
['2016-10-11', 18.33, 18.33, 18.26, 18.49, 12.0, 0, 0.1, 0.02, -0.04],
['2016-10-12', 18.28, 18.15, 18.1, 18.31, 10.0, 0, 0.07, -0.02, -0.05],
['2016-10-13', 18.15, 18.09, 18.05, 18.21, 10.0, 0, 0.06, -0.03, -0.06],
['2016-10-14', 18.1, 18.1, 18.0, 18.15, 12.0, 0, 0.04, -0.05, -0.07],
['2016-10-17', 18.07, 17.86, 17.83, 18.1, 12.0, 0, 0.01, -0.07, -0.08],
['2016-10-18', 17.86, 17.93, 17.84, 17.99, 14.0, 0, 0.03, -0.07, -0.08],
['2016-10-19', 17.93, 17.88, 17.83, 18.05, 11.0, 0, 0.03, -0.07, -0.08],
['2016-10-20', 17.9, 17.89, 17.83, 17.98, 12.0, 0, 0.05, -0.06, -0.09],
['2016-10-21', 17.91, 17.91, 17.82, 17.93, 12.0, 0, 0.07, -0.06, -0.09],
['2016-10-24', 17.93, 18.31, 17.86, 18.42, 29.0, 0, 0.11, -0.05, -0.1],
['2016-10-25', 18.31, 18.13, 18.09, 18.46, 19.0, 0, 0.06, -0.09, -0.12],
['2016-10-26', 18.12, 17.97, 17.95, 18.15, 14.0, 0, 0.02, -0.12, -0.13],
['2016-10-27', 18.06, 17.81, 17.77, 18.06, 21.0, 0, -0.01, -0.13, -0.13],
['2016-10-28', 17.8, 17.9, 17.8, 18.05, 20.0, 0, -0.01, -0.13, -0.13],
['2016-10-31', 17.87, 17.86, 17.72, 17.96, 12.0, 0, -0.02, -0.14, -0.13],
['2016-11-01', 17.87, 17.98, 17.79, 17.99, 18.0, 0, -0.03, -0.14, -0.12],
['2016-11-02', 17.86, 17.84, 17.76, 17.94, 30.0, 0, -0.06, -0.15, -0.12],
['2016-11-03', 17.83, 17.93, 17.79, 17.97, 27.0, 0, -0.07, -0.14, -0.11],
['2016-11-04', 17.9, 17.91, 17.87, 18.0, 26.0, 0, -0.09, -0.15, -0.1],
['2016-11-07', 17.91, 17.89, 17.85, 17.93, 20.0, 0, -0.11, -0.14, -0.09],
['2016-11-08', 17.92, 17.99, 17.89, 18.06, 26.0, 0, -0.12, -0.13, -0.07],
['2016-11-09', 18.0, 17.89, 17.77, 18.08, 34.0, 0, -0.15, -0.13, -0.06],
['2016-11-10', 17.95, 18.0, 17.94, 18.11, 27.0, 0, -0.15, -0.11, -0.03],
['2016-11-11', 17.95, 18.02, 17.93, 18.08, 27.0, 0, -0.17, -0.1, -0.01],
['2016-11-14', 18.0, 18.04, 17.95, 18.25, 35.0, 0, -0.18, -0.08, 0.01],
['2016-11-15', 18.1, 18.18, 18.03, 18.24, 25.0, 0, -0.18, -0.06, 0.04],
['2016-11-16', 18.23, 18.12, 18.05, 18.29, 23.0, 0, -0.21, -0.04, 0.06],
['2016-11-17', 18.11, 18.12, 18.01, 18.14, 27.0, 0, -0.21, -0.01, 0.09],
['2016-11-18', 18.12, 18.1, 18.03, 18.16, 18.0, 0, -0.19, 0.03, 0.12],
['2016-11-21', 18.08, 18.34, 18.08, 18.68, 41.0, 0, -0.13, 0.08, 0.15],
['2016-11-22', 18.37, 18.37, 18.28, 18.49, 52.0, 0, -0.09, 0.12, 0.17],
['2016-11-23', 18.4, 18.84, 18.37, 18.9, 66.0, 0, -0.02, 0.17, 0.18],
['2016-11-24', 18.77, 18.74, 18.61, 18.97, 26.0, 0, -0.02, 0.17, 0.18],
['2016-11-25', 18.8, 18.99, 18.66, 19.02, 40.0, 0, -0.01, 0.18, 0.19],
['2016-11-28', 19.1, 18.65, 18.52, 19.2, 85.0, 0, -0.06, 0.16, 0.19],
['2016-11-29', 18.65, 18.75, 18.51, 18.76, 49.0, 0, -0.06, 0.17, 0.2],
['2016-11-30', 18.76, 18.55, 18.47, 18.82, 39.0, 0, -0.08, 0.17, 0.21],
['2016-12-01', 18.55, 18.49, 18.41, 18.64, 53.0, 0, -0.06, 0.19, 0.22],
['2016-12-02', 18.53, 18.49, 18.24, 18.54, 48.0, 0, -0.02, 0.21, 0.23],
['2016-12-05', 18.39, 18.66, 18.34, 18.67, 50.0, 0, 0.03, 0.25, 0.23],
['2016-12-06', 18.66, 18.6, 18.57, 18.78, 31.0, 0, 0.08, 0.26, 0.23],
['2016-12-07', 18.65, 18.62, 18.58, 18.71, 12.0, 0, 0.15, 0.29, 0.21],
['2016-12-08', 18.67, 18.76, 18.62, 18.88, 26.0, 0, 0.25, 0.32, 0.19],
['2016-12-09', 18.76, 19.2, 18.75, 19.34, 62.0, 0, 0.34, 0.33, 0.16],
['2016-12-12', 19.16, 19.25, 18.9, 19.65, 79.0, 1, 0.34, 0.28, 0.11],
['2016-12-13', 19.09, 18.88, 18.81, 19.2, 24.0, 0, 0.27, 0.2, 0.06],
['2016-12-14', 18.8, 18.82, 18.8, 19.14, 32.0, 0, 0.23, 0.13, 0.02],
['2016-12-15', 18.73, 18.24, 18.2, 18.73, 36.0, 0, 0.13, 0.05, -0.01],
['2016-12-16', 18.24, 18.18, 18.12, 18.4, 24.0, 0, 0.1, 0.02, -0.03],
['2016-12-19', 18.15, 18.01, 17.93, 18.18, 24.0, 0, 0.06, -0.02, -0.05],
['2016-12-20', 17.99, 17.79, 17.7, 17.99, 29.0, 1, 0.02, -0.05, -0.05],
['2016-12-21', 17.83, 17.81, 17.77, 17.98, 30.0, 0, 0.0, -0.05, -0.06],
['2016-12-22', 17.85, 17.72, 17.65, 17.85, 21.0, 0, -0.03, -0.07, -0.06],
['2016-12-23', 17.77, 17.6, 17.54, 17.77, 18.0, 0, -0.04, -0.08, -0.05],
['2016-12-26', 17.56, 17.75, 17.39, 17.77, 16.0, 0, -0.04, -0.07, -0.05],
['2016-12-27', 17.73, 17.71, 17.65, 17.82, 10.0, 0, -0.06, -0.07, -0.04],
['2016-12-28', 17.72, 17.62, 17.49, 17.77, 26.0, 0, -0.09, -0.07, -0.03],
['2016-12-29', 17.6, 17.49, 17.43, 17.62, 28.0, 0, -0.09, -0.06, -0.02],
['2016-12-30', 17.53, 17.6, 17.47, 17.61, 22.0, 0, -0.05, -0.03, -0.01],
['2017-01-03', 17.6, 17.92, 17.57, 17.98, 28.0, 1, 0.0, 0.0, 0.0],
])
this.datas = data.datas
this.times = data.times
this.vols = data.vols
this.macds = data.macds
this.difs = data.difs
this.deas = data.deas
this.option.xAxis[0].data = data.times
this.option.series[0].data = data.datas
this.option.series[0].markArea = fenduans(data)
this.option.series[0].markLine = fenduans(data)
this.option.series[1].data = calculateMA(data, 5)
}
}
})
export default useEcharts

37
src/utils/echarts.js Normal file

@ -0,0 +1,37 @@
//这个必须要引入的
import * as echarts from "echarts/core";
/** 引入柱状图and折线图图表图表后缀都为 Chart*/
import { BarChart, LineChart } from "echarts/charts";
// 引入提示框,标题,直角坐标系,数据集,内置数据转换器组件,组件后缀都为 Component
import {
TitleComponent,
TooltipComponent,
GridComponent,
DatasetComponent,
TransformComponent,
} from "echarts/components";
// 标签自动布局,全局过渡动画等特性
import { LabelLayout, UniversalTransition } from "echarts/features";
// 引入 Canvas 渲染器,注意引入 CanvasRenderer 或者 SVGRenderer 是必须的一步
import { CanvasRenderer } from "echarts/renderers";
// 注册必须的组件
echarts.use([
TitleComponent,
TooltipComponent,
GridComponent,
DatasetComponent,
TransformComponent,
BarChart,
LabelLayout,
UniversalTransition,
CanvasRenderer,
LineChart,
]);
// 导出
export default echarts;

45
src/utils/http.js Normal file

@ -0,0 +1,45 @@
import axios from 'axios'
const request = axios.create({
method :"GET",
timeout:2000,
})
// 请求拦截器
request.interceptors.request.use(config => {
console.log("请求拦截成功")
// 例如给后端传递token,config是配置参数
//如有需要注意使用token的时候需要引入cookie方法或者用本地localStorage等方法推荐js-cookie
//const token = getCookie('名称');//这里取token之前你肯定需要先拿到token,存一下
//if(token){
//config.params = {'token':token} //如果要求携带在参数中
//config.headers.token= token; //如果要求携带在请求头中
return config
},
error => {
console.log('请求拦截失败')
return Promise.reject(error)
}
)
// 响应拦截器
request.interceptors.response.use(res => {
console.log("响应拦截成功")
if (res.status != 200) {
return
} else {
return res
}
},
error => {
console.log("响应拦截失败")
return Promise.reject(error)
}
)
export default (url, method = "GET", params = {}) => {
return request({
url,
method,
params
})
}
// export default request

57
src/utils/request.js Normal file

@ -0,0 +1,57 @@
// 进行axios的二次封装
import axios from "axios";
// 第一步利用axios对象的create方法去创建axios实例(其他的配置:基础路径,超时的时间)
let request=axios.create({
// 基础路径
baseURL:import.meta.env.VITE_APP_BASE_API,//基础路径上会携带/api
timeout:5000//超时的时间的设置
});
// 第二步:request实例添加请求与响应拦截器
request.interceptors.request.use((config)=>{
// config配置对象headers属性请求头经常给服务器端携带公共参数
// 返回配置对象
return config
})
// 第三步:响应拦截器
request.interceptors.response.use((response)=>{
// 成功回调
// 简化数据
console.log(response);
if(response.status==200){
return response.data.message
}
},(error)=>{
// 失败回调处理http网络问题
// 定义一个变量:存储网络错误信息
console.log(error);
let message=''
// http状态码
let status=error.response.status
switch(status){
case 401:
message='TOKEN过期'
break;
case 403:
message ='无权访问'
break;
case 404:
message ='请求地址错误'
break;
case 500:
message ='服务器出现问题'
break;
default:
message='网络出现问题'
break
}
return Promise.reject(error)
})
// 对外暴露
export default request

91
src/views/HomeView.vue Normal file

@ -0,0 +1,91 @@
<script setup>
import { onMounted, inject, ref, watchEffect } from 'vue' //
import { RouterView, RouterLink, useRouter } from 'vue-router'
const router = useRouter()
const headerData = ref([
'分时',
'日K',
'周K',
'月K',
'季K',
'年K',
'1分',
'3分',
'5分',
'15分',
'30分',
'1小时',
'2小时',
'3小时',
'4小时',
])
//
let routerList = [
'hour-line',
'day-line',
'week-line',
'month-line',
'year-line',
]
//
const activeIndex = ref(0)
//
function handleClick(index) {
//
activeIndex.value = index
//
router.push(`/${routerList[index]}`)
}
</script>
<template>
<div class="content">
<ul class="timelist">
<li
class="item"
v-for="(item, index) in headerData"
:key="item"
:class="{ active: activeIndex === index }"
@click="handleClick(index)"
>
{{ item }}
</li>
</ul>
<div class="view">
<RouterView></RouterView>
</div>
</div>
</template>
<style lang="scss" scoped>
.content {
width: 100vw;
height: 100vh;
display: flex;
flex-direction: column;
}
.timelist {
background-color: #191919;
color: #afb3b4;
font-size: 12px;
display: flex;
list-style: none;
}
.timelist > li {
padding: 2px 8px;
cursor: pointer;
}
.active {
color: #2d98b9;
}
.view {
height: calc(100vh - 20px);
}
::-webkit-scrollbar {
width: 0;
}
</style>

900
test.html Normal file

@ -0,0 +1,900 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
let obj = {
name: 'jack',
info: [
{
age: 20,
sex: '男'
}
]
}
let a = {
age: 20,
sex: '女'
}
console.log([...obj.info, a])
let newoption = {
grid: [
{
left: '3%',
right: '3%',
height: '30%',
},
{
left: '3%',
right: '3%',
top: '45%',
height: '10%',
},
{
left: '3%',
right: '3%',
top: '58%',
height: '10%',
},
{
left: '3%',
right: '3%',
top: '71%',
height: '10%',
},
{
left: '3%',
right: '3%',
top: '84%',
height: '10%',
},
// 3个图
{
left: '3%',
right: '3%',
top: '6%',
height: '60%',
},
{
left: '3%',
right: '3%',
top: '71%',
height: '10%',
},
{
left: '3%',
right: '3%',
top: '85%',
height: '10%',
},
// 2个图
{
left: '3%',
right: '3%',
top: '6%',
height: '75%',
},
{
left: '3%',
right: '3%',
top: '85%',
height: '10%',
},
// 4个图
{
left: '3%',
right: '3%',
top: '6%',
height: '48%',
},
{
left: '3%',
right: '3%',
top: '59%',
height: '10%',
},
{
left: '3%',
right: '3%',
top: '72%',
height: '10%',
},
{
left: '3%',
right: '3%',
top: '85%',
height: '10%',
},
]
}
// 定义图表配置数组
const chartConfigs = [
{
name: 'MA',
options: {
tooltip: {
trigger: 'axis', // 触发类型为坐标轴
axisPointer: {
// 坐标轴指示器
type: 'cross', // 类型为交叉
label: {
backgroundColor: '#6a7985', // 标签背景色
},
},
},
title: {
text: 'K线图',
left: 0,
},
dataZoom: [
{
show: true,
xAxisIndex: [0,1],
type: 'slider',
},
],
xAxis: {
type: 'category',
gridIndex: 1,
boundaryGap: false,
data: echartsState.times,
axisLabel: { show: false },
},
yAxis: {
type: 'value',
scale: true /*按比例显示*/,
gridIndex: 1,
splitNumber: 3,
},
series: [
{
name: 'Highest',
type: 'line',
xAxisIndex: 1,
yAxisIndex: 1,
smooth: true,
lineStyle: {
color: 'red',
},
data: [
10, 11, 13, 11, 12, 12, 9, 10, 11, 13, 11, 12, 12, 9, 10, 11, 13,
11, 12, 12, 9, 10, 11, 13, 11, 12, 12, 9, 10, 11, 13, 11, 12, 12, 9,
10, 11, 13, 11, 12, 12, 9, 10, 11, 13, 11, 12, 12, 9, 10, 11, 13,
11, 12, 12, 9,
],
},
{
name: 'Lowest',
type: 'bar',
xAxisIndex: 1,
yAxisIndex: 1,
itemStyle: {
normal: {
color: 'red',
},
},
data: [
1, -2, 2, 5, 3, 2, -3, 1, -2, 2, 5, 3, 2, -3, 1, -2, 2, 5, 3, 2, -3,
1, -2, 2, 5, 3, 2, -3, 1, -2, 2, 5, 3, 2, -3, 1, -2, 2, 5, 3, 2, -3,
1, -2, 2, 5, 3, 2, -3, 1, -2, 2, 5, 3, 2, -3,
],
},
{
name: 'rant',
type: 'line',
xAxisIndex: 1,
yAxisIndex: 1,
itemStyle: {
normal: {
//这里是颜色
color: 'green',
},
},
data: [
-5, 1, 7, 3, -1, 2, 0, -5, 1, 7, 3, -1, 2, 0, -5, 1, 7, 3, -1, 2, 0,
-5, 1, 7, 3, -1, 2, 0, -5, 1, 7, 3, -1, 2, 0, -5, 1, 7, 3, -1, 2, 0,
-5, 1, 7, 3, -1, 2, 0,
],
},
],
},
},
{
name: 'BOLL',
options: {
tooltip: {
trigger: 'axis', // 触发类型为坐标轴
axisPointer: {
// 坐标轴指示器
type: 'cross', // 类型为交叉
label: {
backgroundColor: '#6a7985', // 标签背景色
},
},
},
title: {
text: 'K线图',
left: 0,
},
dataZoom: [
{
type: 'inside',
},
],
xAxis: {
type: 'category',
gridIndex: 2,
boundaryGap: false,
data: echartsState.times,
axisLabel: { show: false },
},
yAxis: {
type: 'value',
scale: true /*按比例显示*/,
gridIndex: 2,
splitNumber: 3,
// axisLine: { onZero: false },
// axisTick: { show: false },
// splitLine: { show: false },
// axisLabel: { show: true },
},
series: [
{
name: 'Highest',
type: 'line',
xAxisIndex: 2,
yAxisIndex: 2,
smooth: true,
lineStyle: {
color: 'red',
},
data: [
10, 11, 13, 11, 12, 12, 9, 10, 11, 13, 11, 12, 12, 9, 10, 11, 13,
11, 12, 12, 9, 10, 11, 13, 11, 12, 12, 9, 10, 11, 13, 11, 12, 12, 9,
10, 11, 13, 11, 12, 12, 9, 10, 11, 13, 11, 12, 12, 9, 10, 11, 13,
11, 12, 12, 9,
],
markPoint: {
data: [
{ type: 'max', name: 'Max' },
{ type: 'min', name: 'Min' },
],
},
markLine: {
data: [{ type: 'average', name: 'Avg' }],
},
},
],
},
},
{
name: 'EMA',
options: {
tooltip: {
trigger: 'axis', // 触发类型为坐标轴
axisPointer: {
// 坐标轴指示器
type: 'cross', // 类型为交叉
label: {
backgroundColor: '#6a7985', // 标签背景色
},
},
},
title: {
text: 'K线图',
left: 0,
},
grid: {
top: '5%',
left: '2%',
right: '3%',
bottom: '3%',
},
legend: {},
dataZoom: [
{
type: 'inside', // 内置型数据区域缩放组件
start: 10, // 左边在10%的位置
end: 60, // 右边在60%的位置
},
],
xAxis: {
type: 'category',
boundaryGap: false,
data: [
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun',
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun',
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun',
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun',
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun',
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun',
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun',
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun',
],
},
yAxis: {
type: 'value',
axisLabel: {
// formatter: '{value} °%',
formatter: '{value}',
},
},
series: [
{
name: 'Highest',
type: 'line',
smooth: true,
lineStyle: {
color: 'red',
},
data: [
10, 11, 13, 11, 12, 12, 9, 10, 11, 13, 11, 12, 12, 9, 10, 11, 13,
11, 12, 12, 9, 10, 11, 13, 11, 12, 12, 9, 10, 11, 13, 11, 12, 12, 9,
10, 11, 13, 11, 12, 12, 9, 10, 11, 13, 11, 12, 12, 9, 10, 11, 13,
11, 12, 12, 9,
],
markPoint: {
data: [
{ type: 'max', name: 'Max' },
{ type: 'min', name: 'Min' },
],
},
markLine: {
data: [{ type: 'average', name: 'Avg' }],
},
},
{
name: 'Lowest',
type: 'bar',
itemStyle: {
normal: {
color: 'red',
},
},
data: [
1, -2, 2, 5, 3, 2, -3, 1, -2, 2, 5, 3, 2, -3, 1, -2, 2, 5, 3, 2, -3,
1, -2, 2, 5, 3, 2, -3, 1, -2, 2, 5, 3, 2, -3, 1, -2, 2, 5, 3, 2, -3,
1, -2, 2, 5, 3, 2, -3, 1, -2, 2, 5, 3, 2, -3,
],
markPoint: {
data: [{ name: '周最低', value: -2, xAxis: 1, yAxis: -1.5 }],
},
markLine: {
data: [
{ type: 'average', name: 'Avg' },
[
{
symbol: 'none',
x: '90%',
yAxis: 'max',
},
{
symbol: 'circle',
label: {
position: 'start',
formatter: 'Max',
},
type: 'max',
name: '最高点',
},
],
],
},
},
{
name: 'rant',
type: 'bar',
itemStyle: {
normal: {
//这里是颜色
color: 'green',
},
},
data: [
-5, 1, 7, 3, -1, 2, 0, -5, 1, 7, 3, -1, 2, 0, -5, 1, 7, 3, -1, 2, 0,
-5, 1, 7, 3, -1, 2, 0, -5, 1, 7, 3, -1, 2, 0, -5, 1, 7, 3, -1, 2, 0,
-5, 1, 7, 3, -1, 2, 0,
],
markPoint: {
data: [{ name: '周最低', value: -2, xAxis: 1, yAxis: -1.5 }],
},
markLine: {
data: [
{ type: 'average', name: 'Avg' },
[
{
symbol: 'none',
x: '90%',
yAxis: 'max',
},
{
symbol: 'circle',
label: {
position: 'start',
formatter: 'Max',
},
type: 'max',
name: '最高点',
},
],
],
},
},
],
},
},
{
name: 'SAR',
options: {
tooltip: {
trigger: 'axis', // 触发类型为坐标轴
axisPointer: {
// 坐标轴指示器
type: 'cross', // 类型为交叉
label: {
backgroundColor: '#6a7985', // 标签背景色
},
},
},
title: {
text: 'K线图',
left: 0,
},
grid: {
top: '5%',
left: '2%',
right: '3%',
bottom: '3%',
},
legend: {},
dataZoom: [
{
type: 'inside', // 内置型数据区域缩放组件
start: 10, // 左边在10%的位置
end: 60, // 右边在60%的位置
},
],
xAxis: {
type: 'category',
boundaryGap: false,
data: [
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun',
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun',
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun',
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun',
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun',
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun',
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun',
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun',
],
},
yAxis: {
type: 'value',
axisLabel: {
// formatter: '{value} °%',
formatter: '{value}',
},
},
series: [
{
name: 'Highest',
type: 'line',
smooth: true,
lineStyle: {
color: 'red',
},
data: [
10, 11, 13, 11, 12, 12, 9, 10, 11, 13, 11, 12, 12, 9, 10, 11, 13,
11, 12, 12, 9, 10, 11, 13, 11, 12, 12, 9, 10, 11, 13, 11, 12, 12, 9,
10, 11, 13, 11, 12, 12, 9, 10, 11, 13, 11, 12, 12, 9, 10, 11, 13,
11, 12, 12, 9,
],
markPoint: {
data: [
{ type: 'max', name: 'Max' },
{ type: 'min', name: 'Min' },
],
},
markLine: {
data: [{ type: 'average', name: 'Avg' }],
},
},
{
name: 'Lowest',
type: 'bar',
itemStyle: {
normal: {
color: 'red',
},
},
data: [
1, -2, 2, 5, 3, 2, -3, 1, -2, 2, 5, 3, 2, -3, 1, -2, 2, 5, 3, 2, -3,
1, -2, 2, 5, 3, 2, -3, 1, -2, 2, 5, 3, 2, -3, 1, -2, 2, 5, 3, 2, -3,
1, -2, 2, 5, 3, 2, -3, 1, -2, 2, 5, 3, 2, -3,
],
markPoint: {
data: [{ name: '周最低', value: -2, xAxis: 1, yAxis: -1.5 }],
},
markLine: {
data: [
{ type: 'average', name: 'Avg' },
[
{
symbol: 'none',
x: '90%',
yAxis: 'max',
},
{
symbol: 'circle',
label: {
position: 'start',
formatter: 'Max',
},
type: 'max',
name: '最高点',
},
],
],
},
},
{
name: 'rant',
type: 'bar',
itemStyle: {
normal: {
//这里是颜色
color: 'green',
},
},
data: [
-5, 1, 7, 3, -1, 2, 0, -5, 1, 7, 3, -1, 2, 0, -5, 1, 7, 3, -1, 2, 0,
-5, 1, 7, 3, -1, 2, 0, -5, 1, 7, 3, -1, 2, 0, -5, 1, 7, 3, -1, 2, 0,
-5, 1, 7, 3, -1, 2, 0,
],
markPoint: {
data: [{ name: '周最低', value: -2, xAxis: 1, yAxis: -1.5 }],
},
markLine: {
data: [
{ type: 'average', name: 'Avg' },
[
{
symbol: 'none',
x: '90%',
yAxis: 'max',
},
{
symbol: 'circle',
label: {
position: 'start',
formatter: 'Max',
},
type: 'max',
name: '最高点',
},
],
],
},
},
],
},
},
{
name: 'CDP',
options: {
tooltip: {
trigger: 'axis', // 触发类型为坐标轴
axisPointer: {
// 坐标轴指示器
type: 'cross', // 类型为交叉
label: {
backgroundColor: '#6a7985', // 标签背景色
},
},
},
title: {
text: 'K线图',
left: 0,
},
grid: {
top: '5%',
left: '2%',
right: '3%',
bottom: '3%',
},
legend: {},
dataZoom: [
{
type: 'inside', // 内置型数据区域缩放组件
start: 10, // 左边在10%的位置
end: 60, // 右边在60%的位置
},
],
xAxis: {
type: 'category',
boundaryGap: false,
data: [
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun',
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun',
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun',
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun',
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun',
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun',
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun',
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun',
],
},
yAxis: {
type: 'value',
axisLabel: {
// formatter: '{value} °%',
formatter: '{value}',
},
},
series: [
{
name: 'Highest',
type: 'line',
smooth: true,
lineStyle: {
color: 'red',
},
data: [
10, 11, 13, 11, 12, 12, 9, 10, 11, 13, 11, 12, 12, 9, 10, 11, 13,
11, 12, 12, 9, 10, 11, 13, 11, 12, 12, 9, 10, 11, 13, 11, 12, 12, 9,
10, 11, 13, 11, 12, 12, 9, 10, 11, 13, 11, 12, 12, 9, 10, 11, 13,
11, 12, 12, 9,
],
markPoint: {
data: [
{ type: 'max', name: 'Max' },
{ type: 'min', name: 'Min' },
],
},
markLine: {
data: [{ type: 'average', name: 'Avg' }],
},
},
{
name: 'Lowest',
type: 'bar',
itemStyle: {
normal: {
color: 'red',
},
},
data: [
1, -2, 2, 5, 3, 2, -3, 1, -2, 2, 5, 3, 2, -3, 1, -2, 2, 5, 3, 2, -3,
1, -2, 2, 5, 3, 2, -3, 1, -2, 2, 5, 3, 2, -3, 1, -2, 2, 5, 3, 2, -3,
1, -2, 2, 5, 3, 2, -3, 1, -2, 2, 5, 3, 2, -3,
],
markPoint: {
data: [{ name: '周最低', value: -2, xAxis: 1, yAxis: -1.5 }],
},
markLine: {
data: [
{ type: 'average', name: 'Avg' },
[
{
symbol: 'none',
x: '90%',
yAxis: 'max',
},
{
symbol: 'circle',
label: {
position: 'start',
formatter: 'Max',
},
type: 'max',
name: '最高点',
},
],
],
},
},
{
name: 'rant',
type: 'bar',
itemStyle: {
normal: {
//这里是颜色
color: 'green',
},
},
data: [
-5, 1, 7, 3, -1, 2, 0, -5, 1, 7, 3, -1, 2, 0, -5, 1, 7, 3, -1, 2, 0,
-5, 1, 7, 3, -1, 2, 0, -5, 1, 7, 3, -1, 2, 0, -5, 1, 7, 3, -1, 2, 0,
-5, 1, 7, 3, -1, 2, 0,
],
markPoint: {
data: [{ name: '周最低', value: -2, xAxis: 1, yAxis: -1.5 }],
},
markLine: {
data: [
{ type: 'average', name: 'Avg' },
[
{
symbol: 'none',
x: '90%',
yAxis: 'max',
},
{
symbol: 'circle',
label: {
position: 'start',
formatter: 'Max',
},
type: 'max',
name: '最高点',
},
],
],
},
},
],
},
},
]
</script>
</body>
</html>

97
test2.html Normal file

@ -0,0 +1,97 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ECharts KDJ指标示例</title>
<!-- 引入ECharts库 -->
<script src="./echarts.min.js"></script>
</head>
<body>
<!-- 创建用于绘制图表的DOM元素 -->
<div id="main" style="width: 100vw;height:600px;"></div>
<script type="text/javascript">
// 初始化ECharts实例
var myChart = echarts.init(document.getElementById('main'));
// 示例数据(最高价、最低价、收盘价等)
var stockData = [
{date: '2023-10-01', high: 10.5, low: 9.8, close: 10.0},
{date: '2023-10-02', high: 10.8, low: 9.9, close: 10.4},
// ...(更多数据)
];
// 计算KDJ值的函数这里以简单示例实际计算可能更复杂
function calculateKDJ(stockData, N=9, M1=3) {
var K = [], D = [], J = [];
var RSV = [], VAR1 = [], prevK = 0, prevD = 50; // 初始化prevK和prevD
stockData.forEach(function(item, index) {
var LLV = Math.min(...stockData.slice(Math.max(0, index - N + 1), index + 1).map(d => d.low));
var HHV = Math.max(...stockData.slice(Math.max(0, index - N + 1), index + 1).map(d => d.high));
RSV.push((item.close - LLV) / (HHV - LLV) * 100);
var Kvalue = (2 / 3) * prevK + (1 / 3) * RSV[RSV.length - 1];
K.push(Kvalue.toFixed(2));
var Dvalue = (2 / 3) * prevD + (1 / 3) * Kvalue;
D.push(Dvalue.toFixed(2));
var Jvalue = 3 * Kvalue - 2 * Dvalue;
J.push(Jvalue.toFixed(2));
prevK = Kvalue;
prevD = Dvalue;
});
return { K: K, D: D, J: J, dates: stockData.map(d => d.date) };
}
// 计算KDJ值
var kdjData = calculateKDJ(stockData);
// 配置ECharts
var option = {
title: {
text: 'KDJ指标示例'
},
tooltip: {
trigger: 'axis'
},
xAxis: {
type: 'category',
data: kdjData.dates
},
yAxis: {
type: 'value'
},
series: [
{
name: 'K值',
type: 'line',
data: kdjData.K,
smooth: true,
itemStyle: { color: '#ff3333' }
},
{
name: 'D值',
type: 'line',
data: kdjData.D,
smooth: true,
itemStyle: { color: '#33ff33' }
},
{
name: 'J值',
type: 'line',
data: kdjData.J,
smooth: true,
itemStyle: { color: '#3333ff' }
}
]
};
// 绘制图表
myChart.setOption(option);
</script>
</body>
</html>

112
test3.html Normal file

@ -0,0 +1,112 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
</head>
<body>
<script>
const API_URL = 'https://www.shidaotec.com/api/rank/getTop50StockList'
const stockCache = {
hold: [],
favorites: [],
china: [],
hk: [],
us: []
}
// 从服务器获取股票数据
async function fetchStocks (stockType) {
// 检查缓存
if (stockCache[stockType].length > 0) {
console.log('使用缓存数据:', stockType)
return stockCache[stockType] // 使用缓存
}
const stockTypeMapping = {
hold: { market: 'a', type: 2 },
favorites: { market: 'us', type: 2 },
china: { market: 'a', type: 1 },
hk: { market: 'hk', type: 1 },
us: { market: 'us', type: 1 }
}
const { market, type } = stockTypeMapping[stockType]
console.log(`请求的市场: ${market}, 类型: ${type}`)
try {
const response = await axios.get(API_URL, {
params: {
market: market,
stockPoolCode: 'None',
year: 'today',
type: type
}
})
console.log("响应数据: ", response.data)
if (response.data.code === 200 && response.data.data) {
const stockList = response.data.data
const stocks = stockList.map(stock => {
const price = parseFloat(stock.price)
const change = parseFloat(stock.change)
return {
stockName: stock.stockName,
formattedStockName: formatStockName(stock.stockName),
stockCode: stock.stockCode,
price: price,
change: change,
isPositiveChange: change > 0 // 新增属性判断涨跌幅是否大于0
}
})
stockCache[stockType] = stocks // 缓存结果
return stocks
} else {
throw new Error('Unexpected response format')
}
} catch (error) {
handleAxiosError(error)
throw new Error('无法获取股票数据')
}
}
// 辅助函数:格式化股票名称
function formatStockName (name) {
const maxLength = isFirstCharEnglish(name) ? 8 : 4
return name.length > maxLength
? name.substring(0, maxLength) + '...'
: name.padEnd(maxLength + 1, ' ')
}
// 辅助函数:判断名称的首字母是否为英文字符
function isFirstCharEnglish (name) {
return /^[A-Za-z]/.test(name)
}
// 错误处理函数
function handleAxiosError (error) {
if (axios.isAxiosError(error)) {
console.error('获取股票数据失败: ', error.response ? error.response.data : error.message)
} else if (error instanceof Error) {
console.error('获取股票数据失败: ', error.message)
} else {
console.error('获取股票数据失败: ', '未知错误')
}
}
fetchStocks('hold')
// K线图数据
// [open, close, lowest, highest] (即:[开盘值, 收盘值, 最低值, 最高值]
</script>
</body>
</html>

31
test4.html Normal file

@ -0,0 +1,31 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.bootcdn.net/ajax/libs/axios/1.7.2/axios.js"></script>
<title>Document</title>
</head>
<body>
<script>
axios.get('http://127.0.0.1:8015/stock',{
params:{
symbol: 'sz000001', // 股票代码
start_date: '2022-01-01', // 起始日期
end_date: '2022-12-31' // 结束日期
}
}
)
.then(response => {
console.log(response.data)
})
.catch(error => {
console.error(error)
})
</script>
</body>
</html>

19
vite.config.js Normal file

@ -0,0 +1,19 @@
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueDevTools from 'vite-plugin-vue-devtools'
// https://vite.dev/config/
export default defineConfig({
base: './',
plugins: [
vue(),
vueDevTools(),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
},
},
})