import React from 'react'; import {localeable, LocaleProps} from '../locale'; import {themeable, ThemeProps} from '../theme'; import {PlainObject} from '../types'; export interface SparkLineProps extends ThemeProps, LocaleProps { className?: string; width: number; height: number; value?: Array< | number | { value: number; label?: string; } >; onClick?: (e: React.MouseEvent, value?: PlainObject) => void; } export class SparkLine extends React.Component { static defaultProps = { width: 100, height: 50 }; normalizeValue(item: any): number { if (typeof item === 'number') { return item; } else if (item && typeof item.value === 'number') { return item.value; } else { return Number(item) || 0; } } renderLines() { const {width, height, value, classnames: cx} = this.props; const values = value!.map(item => this.normalizeValue(item)); const max = Math.max(...values); const min = Math.min(...values); const duration = max - min || 1; const gap = width / (values.length - 1); const points: Array<{ x: number; y: number; }> = []; values.forEach((value, index) => { points.push({ x: index * gap, y: height - ((value - min) * height) / duration }); }); const lineD = points .map((value, index) => `${index === 0 ? 'M' : 'L'} ${value.x} ${value.y}`) .join(' '); const areaD = `${lineD} V ${height} L 0 ${height} Z`; // todo 支持鼠标 hover 显示对应数据。 return ( ); } render() { const { classnames: cx, className, value, width, height, onClick } = this.props; return (
{Array.isArray(value) && value.length > 1 ? ( {this.renderLines()} ) : ( Invalid Value )}
); } } export default themeable(localeable(SparkLine));