import { Component, Input } from '@angular/core';
import { CommonModule } from '@angular/common';
import { BaseChartComponent } from './base-chart.component';
import * as echarts from 'echarts';
@Component({
selector: 'lib-candlestick-chart-basic',
standalone: true,
imports: [CommonModule, BaseChartComponent],
template: '',
styles: [':host { display: block; }']
})
export class CandlestickChartBasicComponent extends BaseChartComponent {
@Input() data: any[] = [
['2023-01-01', 2320.26, 2320.26, 2287.3, 2362.94],
['2023-01-02', 2300, 2291.3, 2288.26, 2308.38],
['2023-01-03', 2295.35, 2346.5, 2295.35, 2346.92],
['2023-01-04', 2347.22, 2358.98, 2337.35, 2363.8],
['2023-01-05', 2360.75, 2382.48, 2347.89, 2383.76],
['2023-01-06', 2383.43, 2385.42, 2371.23, 2391.82],
['2023-01-07', 2377.41, 2419.02, 2369.57, 2421.15],
['2023-01-08', 2425.92, 2428.15, 2417.58, 2440.38],
['2023-01-09', 2411, 2433.13, 2403.3, 2437.42],
['2023-01-10', 2432.68, 2434.48, 2427.7, 2441.73]
];
@Input() override width = 600;
@Input() override height = 400;
override ngOnInit(): void {
this.options = {
title: {
text: '基础K线图',
left: 'center'
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross'
}
},
grid: {
left: '10%',
right: '10%',
bottom: '15%'
},
xAxis: {
data: this.data.map((item: any) => item[0]),
scale: true,
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: this.data.map((item: any) => [item[1], item[2], item[3], item[4]]),
itemStyle: {
color: '#ec0000',
color0: '#00da3c',
borderColor: '#8A0000',
borderColor0: '#008F28'
}
}
]
};
}
}
@Component({
selector: 'lib-candlestick-chart-ma',
standalone: true,
imports: [CommonModule, BaseChartComponent],
template: '',
styles: [':host { display: block; }']
})
export class CandlestickChartMAComponent extends BaseChartComponent {
@Input() data: any[] = [
['2023-01-01', 2320.26, 2320.26, 2287.3, 2362.94],
['2023-01-02', 2300, 2291.3, 2288.26, 2308.38],
['2023-01-03', 2295.35, 2346.5, 2295.35, 2346.92],
['2023-01-04', 2347.22, 2358.98, 2337.35, 2363.8],
['2023-01-05', 2360.75, 2382.48, 2347.89, 2383.76],
['2023-01-06', 2383.43, 2385.42, 2371.23, 2391.82],
['2023-01-07', 2377.41, 2419.02, 2369.57, 2421.15],
['2023-01-08', 2425.92, 2428.15, 2417.58, 2440.38],
['2023-01-09', 2411, 2433.13, 2403.3, 2437.42],
['2023-01-10', 2432.68, 2434.48, 2427.7, 2441.73]
];
@Input() override width = 600;
@Input() override height = 400;
calculateMA(dayCount: number): number[] {
const result: number[] = [];
for (let i = 0, len = this.data.length; i < len; i++) {
if (i < dayCount) {
result.push(NaN);
continue;
}
let sum = 0;
for (let j = 0; j < dayCount; j++) {
sum += this.data[i - j][4];
}
result.push(+(sum / dayCount).toFixed(3));
}
return result;
}
override ngOnInit(): void {
const dates = this.data.map((item: any) => item[0]);
const values = this.data.map((item: any) => [item[1], item[2], item[3], item[4]]);
const ma5 = this.calculateMA(5);
const ma10 = this.calculateMA(10);
const ma20 = this.calculateMA(20);
this.options = {
title: {
text: 'K线图+均线',
left: 'center'
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross'
}
},
legend: {
data: ['日K', 'MA5', 'MA10', 'MA20'],
top: 30
},
grid: {
left: '10%',
right: '10%',
bottom: '15%'
},
xAxis: {
data: dates,
scale: true,
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: values,
itemStyle: {
color: '#ec0000',
color0: '#00da3c',
borderColor: '#8A0000',
borderColor0: '#008F28'
}
},
{
name: 'MA5',
type: 'line',
data: ma5,
smooth: true,
lineStyle: {
opacity: 0.5
}
},
{
name: 'MA10',
type: 'line',
data: ma10,
smooth: true,
lineStyle: {
opacity: 0.5
}
},
{
name: 'MA20',
type: 'line',
data: ma20,
smooth: true,
lineStyle: {
opacity: 0.5
}
}
]
};
}
}
@Component({
selector: 'lib-candlestick-chart-volume',
standalone: true,
imports: [CommonModule, BaseChartComponent],
template: '',
styles: [':host { display: block; }']
})
export class CandlestickChartVolumeComponent extends BaseChartComponent {
@Input() data: any[] = [
['2023-01-01', 2320.26, 2320.26, 2287.3, 2362.94, 5000],
['2023-01-02', 2300, 2291.3, 2288.26, 2308.38, 4500],
['2023-01-03', 2295.35, 2346.5, 2295.35, 2346.92, 6000],
['2023-01-04', 2347.22, 2358.98, 2337.35, 2363.8, 5500],
['2023-01-05', 2360.75, 2382.48, 2347.89, 2383.76, 7000],
['2023-01-06', 2383.43, 2385.42, 2371.23, 2391.82, 6500],
['2023-01-07', 2377.41, 2419.02, 2369.57, 2421.15, 8000],
['2023-01-08', 2425.92, 2428.15, 2417.58, 2440.38, 7500],
['2023-01-09', 2411, 2433.13, 2403.3, 2437.42, 9000],
['2023-01-10', 2432.68, 2434.48, 2427.7, 2441.73, 8500]
];
@Input() override width = 600;
@Input() override height = 400;
override ngOnInit(): void {
const dates = this.data.map((item: any) => item[0]);
const values = this.data.map((item: any) => [item[1], item[2], item[3], item[4]]);
const volumes = this.data.map((item: any) => item[5]);
this.options = {
title: {
text: 'K线图+成交量',
left: 'center'
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross'
}
},
grid: [
{
left: '10%',
right: '8%',
height: '50%'
},
{
left: '10%',
right: '8%',
top: '63%',
height: '16%'
}
],
xAxis: [
{
type: 'category',
data: dates,
scale: true,
boundaryGap: false,
axisLine: { onZero: false },
splitLine: { show: false },
min: 'dataMin',
max: 'dataMax'
},
{
type: 'category',
gridIndex: 1,
data: dates,
scale: true,
boundaryGap: false,
axisLine: { onZero: false },
axisTick: { show: false },
splitLine: { show: false },
axisLabel: { show: false },
min: 'dataMin',
max: 'dataMax'
}
],
yAxis: [
{
scale: true,
splitArea: {
show: true
}
},
{
scale: true,
gridIndex: 1,
splitNumber: 2,
axisLabel: { show: false },
axisLine: { show: false },
axisTick: { show: false },
splitLine: { show: false }
}
],
dataZoom: [
{
type: 'inside',
xAxisIndex: [0, 1],
start: 50,
end: 100
},
{
show: true,
xAxisIndex: [0, 1],
type: 'slider',
top: '85%',
start: 50,
end: 100
}
],
series: [
{
name: '日K',
type: 'candlestick',
data: values,
itemStyle: {
color: '#ec0000',
color0: '#00da3c',
borderColor: '#8A0000',
borderColor0: '#008F28'
}
},
{
name: '成交量',
type: 'bar',
xAxisIndex: 1,
yAxisIndex: 1,
data: volumes,
itemStyle: {
color: (params: any) => {
const colorList = ['#ec0000', '#00da3c'];
return colorList[params.dataIndex % 2];
}
}
}
]
};
}
}
@Component({
selector: 'lib-candlestick-chart-brush',
standalone: true,
imports: [CommonModule, BaseChartComponent],
template: '',
styles: [':host { display: block; }']
})
export class CandlestickChartBrushComponent extends BaseChartComponent {
@Input() data: any[] = [
['2023-01-01', 2320.26, 2320.26, 2287.3, 2362.94],
['2023-01-02', 2300, 2291.3, 2288.26, 2308.38],
['2023-01-03', 2295.35, 2346.5, 2295.35, 2346.92],
['2023-01-04', 2347.22, 2358.98, 2337.35, 2363.8],
['2023-01-05', 2360.75, 2382.48, 2347.89, 2383.76],
['2023-01-06', 2383.43, 2385.42, 2371.23, 2391.82],
['2023-01-07', 2377.41, 2419.02, 2369.57, 2421.15],
['2023-01-08', 2425.92, 2428.15, 2417.58, 2440.38],
['2023-01-09', 2411, 2433.13, 2403.3, 2437.42],
['2023-01-10', 2432.68, 2434.48, 2427.7, 2441.73]
];
@Input() override width = 600;
@Input() override height = 400;
override ngOnInit(): void {
this.options = {
title: {
text: 'K线图+刷选',
left: 'center'
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross'
}
},
grid: {
left: '10%',
right: '10%',
bottom: '15%'
},
xAxis: {
data: this.data.map((item: any) => item[0]),
scale: true,
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
}
],
brush: {
xAxisIndex: 'all',
brushLink: 'all',
toolbox: ['rect', 'polygon', 'lineX', 'lineY', 'keep', 'clear'],
outOfBrush: {
colorAlpha: 0.1
}
},
series: [
{
name: '日K',
type: 'candlestick',
data: this.data.map((item: any) => [item[1], item[2], item[3], item[4]]),
itemStyle: {
color: '#ec0000',
color0: '#00da3c',
borderColor: '#8A0000',
borderColor0: '#008F28'
}
}
]
};
}
}
@Component({
selector: 'lib-candlestick-chart-dynamic',
standalone: true,
imports: [CommonModule, BaseChartComponent],
template: '',
styles: [':host { display: block; }']
})
export class CandlestickChartDynamicComponent extends BaseChartComponent {
@Input() data: any[] = [
['2023-01-01', 2320.26, 2320.26, 2287.3, 2362.94],
['2023-01-02', 2300, 2291.3, 2288.26, 2308.38],
['2023-01-03', 2295.35, 2346.5, 2295.35, 2346.92],
['2023-01-04', 2347.22, 2358.98, 2337.35, 2363.8],
['2023-01-05', 2360.75, 2382.48, 2347.89, 2383.76],
['2023-01-06', 2383.43, 2385.42, 2371.23, 2391.82],
['2023-01-07', 2377.41, 2419.02, 2369.57, 2421.15],
['2023-01-08', 2425.92, 2428.15, 2417.58, 2440.38],
['2023-01-09', 2411, 2433.13, 2403.3, 2437.42],
['2023-01-10', 2432.68, 2434.48, 2427.7, 2441.73]
];
@Input() override width = 600;
@Input() override height = 400;
override ngOnInit(): void {
this.options = {
title: {
text: '动态K线图',
left: 'center'
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross'
}
},
animation: true,
animationDuration: 1000,
animationEasing: 'cubicOut',
animationDelay: function (idx: number) {
return idx * 10;
},
grid: {
left: '10%',
right: '10%',
bottom: '15%'
},
xAxis: {
data: this.data.map((item: any) => item[0]),
scale: true,
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: this.data.map((item: any) => [item[1], item[2], item[3], item[4]]),
itemStyle: {
color: '#ec0000',
color0: '#00da3c',
borderColor: '#8A0000',
borderColor0: '#008F28'
},
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
]
};
}
}