All files / components/DraggableLineChart DraggableLineChart.tsx

0% Statements 0/29
0% Branches 0/13
0% Functions 0/9
0% Lines 0/28

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122                                                                                                                                                                                                                                                   
import * as d3Selection from 'd3-selection';
import React from 'react';
import { omitProps, Overwrite } from '../../util/component-types';
import { lucidClassNames } from '../../util/style-helpers';
import DraggableLineChartD3, {
	IData,
	IDraggableLineChart,
} from './DraggableLineChartD3';
 
const cx = lucidClassNames.bind('&-DraggableLineChart');
 
const getEmptyRenderProp = (preSelectText: string) => (
	<div style={{ height: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
		<div className={cx('&-empty-info')}>{preSelectText}</div>
	</div>
);
 
export type IDraggableLineChartProps = Overwrite<
	React.SVGProps<SVGGElement>,
	IDraggableLineChart
>;
 
const getCleanData = (data: IData): IData => {
	return data.map(({ x, y }) => ({ x, y: Number.isFinite(y) ? y : 0 }));
};
 
const draggableLineChartDefaultProps = {
	height: 315,
	width: 1000,
	margin: { top: 65, right: 80, bottom: 65, left: 80 },
};
 
class DraggableLineChart extends React.Component<IDraggableLineChartProps, {}> {
	ref: any;
	d3LineChart: any;
	constructor(props: any) {
		super(props);
		this.ref = React.createRef();
		this.d3LineChart = null;
	}
 
	componentDidUpdate() {
		this.d3LineChart.updateLineChart(this.props.data);
	}
	componentDidMount() {
		const svg = d3Selection.select(this.ref);
		const {
			height,
			width,
			margin,
			data,
			onDragEnd,
			xAxisTicksVertical,
			dataIsCentered,
			yAxisMin = 0,
			xAxisRenderProp,
			onPreselect,
			preSelectText,
		} = this.props;
		const emptyRenderProp =
			onPreselect && preSelectText
				? () => getEmptyRenderProp(preSelectText)
				: undefined;
 
		this.d3LineChart = new DraggableLineChartD3(svg, {
			height: height || draggableLineChartDefaultProps.height,
			width: width || draggableLineChartDefaultProps.width,
			margin: margin || draggableLineChartDefaultProps.margin,
			data: getCleanData(data),
			onDragEnd,
			xAxisTicksVertical,
			dataIsCentered,
			yAxisMin,
			xAxisRenderProp,
			emptyRenderProp,
			cx,
			onPreselect,
		});
		this.d3LineChart.renderLineChart();
	}
 
	static displayName = 'DraggableLineChart';
 
	static peek = {
		description: `
			The draggable line chart is a single-lined line chart where
			the points on the line are draggable and will update the data real-time.
		`,
		categories: ['visualizations', 'charts'],
	};
 
	static defaultProps = draggableLineChartDefaultProps;
 
	render(): React.ReactNode {
		const { height, width, ...passThroughs } = this.props;
 
		return (
			<svg
				{...omitProps(passThroughs, undefined, [
					'height',
					'width',
					'margin',
					'data',
					'onDragEnd',
					'xAxisTicksVertical',
					'dataIsCentered',
					'yAxisMin',
					'xAxisRenderProp',
					'onPreselect',
					'preSelectText',
				])}
				ref={(ref: SVGSVGElement) => (this.ref = ref)}
				className={cx('&')}
				width={width}
				height={height}
			/>
		);
	}
}
 
export default DraggableLineChart;