UNPKG

deep-viz

Version:

A React component library, provide concise and beautiful diversity charts with Canvas, SVG, E-map, WebGL, Dom, based on data visualization experience and commercial data display practice.

297 lines (284 loc) 8.92 kB
import React from 'react'; import PropTypes from 'prop-types'; import ReactEcharts from 'echarts-for-react'; import Basic from './Basic'; import { comdify } from '../utils'; export default class KLineChart extends Basic { componentWillReceiveProps(nextProps) { if (this.chart) { const chartInstance = this.chart.getEchartsInstance(); chartInstance.clear(); if (nextProps) { chartInstance.setOption(this.getOption(nextProps)); } } } getOption(props) { const { color, config, onTooltipFormat } = props; const option = { color: color || this.color, legend: { data: (config.y.legend && config.y.legend.length > 0) ? [config.y.legend[0]] : [], textStyle: { color: this.fontColor, fontSize: this.fontSize }, top: 15, itemHeight: 10, itemWidth: 15, itemGap: 5, }, tooltip: { show: !!config.tooltipShow || true, enterable: true, trigger: 'axis', backgroundColor: 'transparent', padding: 0, textStyle: { fontSize: 12, color: config.tooltipColor || 'black', }, axisPointer: { type: 'cross', }, position: [0, 0], formatter: (params) => { let tipString = '<div><p>'; tipString += `时间:${params[0].axisValue} 开:${comdify(params[0].data[1])} 高:${comdify(params[0].data[4])} 低:${comdify(params[0].data[3])} 收:${comdify(params[0].data[2])}`; params.forEach((param, index) => { if (index > 0) { tipString += ` <span style="color: ${color ? color[index - 1] : this.color[index - 1]}">${param.seriesName}:${comdify(param.data)}</span>`; } }); tipString += '</p></div>'; return tipString; }, }, axisPointer: { link: { xAxisIndex: 'all' }, label: { backgroundColor: config.crossLabelBackcolor || '#108EE9' }, }, xAxis: [], yAxis: [], // toolbox: { // show: !!config.toolbox, // itemSize: this.fontSize, // iconStyle: { // normal: { borderColor: this.fontColor }, // emphasis: { borderColor: this.emphasisColor }, // }, // feature: { // dataZoom: {}, // dataView: { readOnly: false }, // restore: {}, // saveAsImage: {}, // }, // right: 15, // top: 0, // }, series: [{ name: (config.y.legend && config.y.legend.length > 0) && config.y.legend[0], type: 'candlestick', hoverAnimation: false, legendHoverLink: false, data: config.y.kData, itemStyle: { normal: { color: config.upColor || '#F04B5B', color0: config.downColor || '#2BBE65', borderColor: null, borderColor0: null, }, }, }], }; config.y.lineData.forEach((item, index) => { option.legend.data.push(config.y.legend[index + 1]); option.series.push({ name: config.y.legend[index + 1], type: 'line', data: item, hoverAnimation: false, symbolSize: 0, }); }); if (config.volume && config.volume.show) { option.series.push({ // name: config.bar.name || '', // type: config.bar.type || 'bar', type: 'bar', xAxisIndex: 1, yAxisIndex: 1, data: config.volume.data, axisPointer: { show: false }, }); option.visualMap = { show: false, seriesIndex: 1 + config.y.lineData.length, dimension: 2, pieces: [{ value: 1, color: config.upColor || '#F04B5B', }, { value: -1, color: config.downColor || '#2BBE65', }], }; option.grid = [{ show: false, left: (config.grid && config.grid.left) || 80, right: (config.grid && config.grid.right) || 10, top: (config.grid && config.grid.top) || 30, bottom: (config.grid && config.grid.bottom) || 10, height: (config.grid && config.grid.height) || 230, borderColor: this.gridColor, }, { show: false, left: (config.grid && config.grid.barLeft) || 80, right: (config.grid && config.grid.barRight) || 10, top: (config.grid && config.grid.barTop) || 290, bottom: (config.grid && config.grid.barBottom) || 10, height: (config.grid && config.grid.barHeight) || 80, borderColor: this.gridColor, }]; option.xAxis = [{ type: 'category', data: config.x.data, name: config.x.name, min: 'dataMin', max: 'dataMax', boundaryGap: false, axisLine: { onZero: false, lineStyle: { color: this.fontColor } }, axisLabel: { showMaxLabel: null }, }, { type: 'category', data: config.x.data, name: config.x.name, gridIndex: 1, min: 'dataMin', max: 'dataMax', scale: true, boundaryGap: false, axisLine: { onZero: false }, axisTick: { show: false }, splitLine: { show: false }, axisLabel: { show: false }, }]; option.yAxis = [{ name: config.y.name || null, position: config.y.position || 'left', scale: true, axisLine: { lineStyle: { color: this.fontColor } }, splitLine: { show: false }, }, { name: config.y.name || null, gridIndex: 1, scale: true, axisLabel: { show: false }, axisLine: { show: false }, axisTick: { show: false }, splitLine: { show: false }, }]; if (config.dataZoom) { const { start, end } = config.dataZoom; option.dataZoom = [ { xAxisIndex: [0, 1], start: (start === null || start === undefined) ? 30 : start, end: end || 100, type: 'inside', }, { type: 'slider', xAxisIndex: [0, 1], show: true, start: (start === null || start === undefined) ? 30 : start, end: end || 100, }, ]; } } else { option.grid = { left: (config.grid && config.grid.left) || 30, right: (config.grid && config.grid.right) || 10, top: (config.grid && config.grid.top) || 30, bottom: (config.grid && config.grid.bottom) || 10, height: (config.grid && config.grid.height) || 330, borderColor: this.gridColor, containLabel: true, }; option.xAxis = { type: 'category', data: config.x.data, name: config.x.name, min: 'dataMin', max: 'dataMax', axisLine: { lineStyle: { color: this.fontColor } }, axisLabel: { showMaxLabel: null }, }; option.yAxis = { name: config.y.name || null, position: config.y.position || 'left', scale: true, axisLine: { lineStyle: { color: this.fontColor } }, splitLine: { show: false }, }; if (config.dataZoom) { option.dataZoom = [ { start: config.dataZoom.start || 50, end: config.dataZoom.end || 100, type: 'inside', }, ]; } } if (onTooltipFormat) { option.tooltip.formatter = params => onTooltipFormat(params); } if (config.x.xLabelCallback && typeof config.x.xLabelCallback === 'function') { if (Array.isArray(option.xAxis)) { option.xAxis[0].axisLabel.formatter = (value, index) => config.x.xLabelCallback(value, index); } else { option.xAxis.axisLabel.formatter = (value, index) => config.x.xLabelCallback(value, index); } } return option; } render() { return ( <ReactEcharts ref={(ref) => { this.chart = ref; }} option={this.getOption(this.props)} style={this.props.style || { height: 450, width: '100%' }} notMerge lazyUpdate={false} onEvents={this.props.onEvents} /> ); } } KLineChart.propTypes = { color: PropTypes.array, config: PropTypes.shape({ x: PropTypes.object.isRequired, y: PropTypes.shape({ kData: PropTypes.array.isRequired, lineData: PropTypes.array, legend: PropTypes.array, position: PropTypes.string, name: PropTypes.string, }).isRequired, upColor: PropTypes.string, downColor: PropTypes.string, bar: PropTypes.object, dataZoom: PropTypes.object, grid: PropTypes.object, tooltipColor: PropTypes.string, tooltipShow: PropTypes.bool, crossLabelBackcolor: PropTypes.string, }).isRequired, style: PropTypes.object, onTooltipFormat: PropTypes.func, onEvents: PropTypes.object, };