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)' } } } ] }; } }