UNPKG

lucid-ui

Version:

A UI component library from Xandr.

364 lines 17 kB
import _ from 'lodash'; import React, { useCallback } from 'react'; import createClass from 'create-react-class'; import DraggableLineChart from './DraggableLineChart'; import TextFieldValidated from '../TextFieldValidated/TextFieldValidated'; export default { title: 'Visualizations/DraggableLineChart', component: DraggableLineChart, parameters: { docs: { description: { component: DraggableLineChart.peek.description, }, }, }, args: DraggableLineChart.defaultProps, }; export const BasicDraggableLineChart = (args) => { const data = [ { x: '12 AM', y: 0 }, { x: '1 AM', y: 0 }, { x: '2 AM', y: 0 }, { x: '3 AM', y: 0 }, { x: '4 AM', y: 0 }, { x: '5 AM', y: 5 }, { x: '6 AM', y: 5 }, { x: '7 AM', y: 10 }, { x: '8 AM', y: 5 }, { x: '9 AM', y: 5 }, { x: '10 AM', y: 5 }, { x: '11 AM', y: 5 }, ]; const style = { paddingTop: '4rem', }; return (React.createElement("div", { style: style }, React.createElement(DraggableLineChart, { ...args, onDragEnd: (x, y) => console.info({ x, y }), data: data, width: 900, xAxisTicksVertical: true }))); }; /* Example With External X Axis Render Prop */ export const ExampleWithExternalXAxisRenderProp = (args) => { const initialCustomSpendDataPoints = [ { x: '12 AM', y: 0, ref: React.createRef() }, { x: '1 AM', y: 1, ref: React.createRef() }, { x: '2 AM', y: 1.5, ref: React.createRef() }, { x: '3 AM', y: 2, ref: React.createRef() }, { x: '4 AM', y: 3.8, ref: React.createRef() }, { x: '5 AM', y: 3.66, ref: React.createRef() }, { x: '6 AM', y: 5, ref: React.createRef() }, { x: '7 AM', y: 10, ref: React.createRef() }, { x: '8 AM', y: 5, ref: React.createRef() }, { x: '9 AM', y: 5, ref: React.createRef() }, { x: '10 AM', y: 5, ref: React.createRef() }, { x: '11 AM', y: 5, ref: React.createRef() }, ]; const style = { paddingTop: '4rem', }; const DataInput = ({ xValue, yValue, myRef, changeHandler, }) => { const onChange = useCallback((newYValue) => { changeHandler(newYValue, xValue); }, [changeHandler, xValue]); return (React.createElement("div", { style: { width: '70%', margin: 'auto' } }, React.createElement(TextFieldValidated, { value: yValue || 0, onBlur: onChange, tabIndex: 0, ref: myRef }), React.createElement("div", { style: { margin: 'auto', textAlign: 'center', width: '95%', marginTop: '15px', } }, xValue))); }; const Component = createClass({ getInitialState() { return { customSpendDataPoints: initialCustomSpendDataPoints, }; }, onDragHandler(newYValue, xValue, fromOnChangeHandler) { const cleanedYValue = fromOnChangeHandler ? newYValue : +Number(newYValue).toFixed(0); const newCustomSpendDataPoints = _.map(this.state.customSpendDataPoints, (dataPoint) => dataPoint.x === xValue ? { ...dataPoint, y: cleanedYValue } : dataPoint); this.setState({ customSpendDataPoints: newCustomSpendDataPoints }); return newCustomSpendDataPoints; }, onChangeHandler(newYValue, xValue) { const currentIndex = _.findIndex(this.state.customSpendDataPoints, [ 'x', xValue, ]); const currentYValue = this.state.customSpendDataPoints[currentIndex].y; const nextValue = +Number(newYValue).toFixed(0); if (currentYValue !== nextValue) { const newCustomSpendDataPoints = this.onDragHandler(newYValue, xValue, true); const nextIndex = currentIndex >= newCustomSpendDataPoints.length - 1 ? 0 : currentIndex + 1; const myRef = newCustomSpendDataPoints[nextIndex].ref; setTimeout(() => myRef.current.focus(), 1); } }, getRenderProp({ onChangeHandler, }, { x, y, ref }) { return (React.createElement(DataInput, { xValue: x, yValue: y, myRef: ref, changeHandler: onChangeHandler })); }, render() { const { customSpendDataPoints } = this.state; const renderProp = _.partial(this.getRenderProp, { onChangeHandler: this.onChangeHandler, }); return (React.createElement("div", { style: style }, React.createElement(DraggableLineChart, { ...args, data: customSpendDataPoints, width: 900, dataIsCentered: true, onDragEnd: this.onDragHandler, xAxisRenderProp: renderProp }))); }, }); return React.createElement(Component, null); }; /* Example With No Data With Preselect */ export const ExampleWithNoDataWithPreselect = (args) => { const initialCustomSpendDataPoints = [ { x: '12 AM', y: 0, ref: React.createRef() }, { x: '1 AM', y: 0, ref: React.createRef() }, { x: '2 AM', y: 0, ref: React.createRef() }, { x: '3 AM', y: 0, ref: React.createRef() }, { x: '4 AM', y: 0, ref: React.createRef() }, { x: '5 AM', y: 0, ref: React.createRef() }, { x: '6 AM', y: 0, ref: React.createRef() }, { x: '7 AM', y: 0, ref: React.createRef() }, { x: '8 AM', y: 0, ref: React.createRef() }, { x: '9 AM', y: 0, ref: React.createRef() }, { x: '10 AM', y: 0, ref: React.createRef() }, { x: '11 AM', y: 0, ref: React.createRef() }, ]; const style = { paddingTop: '4rem', }; const DataInput = ({ xValue, yValue, myRef, changeHandler, }) => { const onChange = useCallback((newYValue) => { changeHandler(newYValue, xValue); }, [changeHandler, xValue]); return (React.createElement("div", { style: { width: '70%', margin: 'auto' } }, React.createElement(TextFieldValidated, { value: yValue || 0, onBlur: onChange, tabIndex: 0, ref: myRef }), React.createElement("div", { style: { margin: 'auto', textAlign: 'center', width: '95%', marginTop: '15px', } }, xValue))); }; const Component = createClass({ getInitialState() { return { customSpendDataPoints: initialCustomSpendDataPoints, }; }, onDragHandler(newYValue, xValue, fromOnChangeHandler) { const cleanedYValue = fromOnChangeHandler ? newYValue : +Number(newYValue).toFixed(0); const newCustomSpendDataPoints = _.map(this.state.customSpendDataPoints, (dataPoint) => dataPoint.x === xValue ? { ...dataPoint, y: cleanedYValue } : dataPoint); this.setState({ customSpendDataPoints: newCustomSpendDataPoints }); return newCustomSpendDataPoints; }, onPreselectHandler(data) { const totalSelected = _.filter(data, ['isSelected', true]).length; const avg = Math.round((100 / totalSelected) * 10) / 10; const updatedData = _.map(data, (step) => ({ ref: step.ref, x: step.x, y: step.isSelected ? avg : step.y, })); this.setState({ customSpendDataPoints: updatedData }); }, onChangeHandler(newYValue, xValue) { const currentIndex = _.findIndex(this.state.customSpendDataPoints, [ 'x', xValue, ]); const currentYValue = this.state.customSpendDataPoints[currentIndex].y; const nextValue = +Number(newYValue).toFixed(0); if (currentYValue !== nextValue) { const newCustomSpendDataPoints = this.onDragHandler(newYValue, xValue, true); const nextIndex = currentIndex >= newCustomSpendDataPoints.length - 1 ? 0 : currentIndex + 1; const myRef = newCustomSpendDataPoints[nextIndex].ref; setTimeout(() => myRef.current.focus(), 1); } }, getRenderProp({ onChangeHandler, }, { x, y, ref }) { return (React.createElement(DataInput, { xValue: x, yValue: y, myRef: ref, changeHandler: onChangeHandler })); }, render() { const { customSpendDataPoints } = this.state; const renderProp = _.partial(this.getRenderProp, { onChangeHandler: this.onChangeHandler, }); return (React.createElement("div", { style: style }, React.createElement(DraggableLineChart, { ...args, data: customSpendDataPoints, width: 900, dataIsCentered: true, onDragEnd: this.onDragHandler, xAxisRenderProp: renderProp, onPreselect: this.onPreselectHandler, preSelectText: 'Click and drag to select hours' }))); }, }); return React.createElement(Component, null); }; /* Example With No Data Without Preselect */ export const ExampleWithNoDataWithoutPreselect = (args) => { const initialCustomSpendDataPoints = [ { x: '12 AM', y: 0, ref: React.createRef() }, { x: '1 AM', y: 0, ref: React.createRef() }, { x: '2 AM', y: 0, ref: React.createRef() }, { x: '3 AM', y: 0, ref: React.createRef() }, { x: '4 AM', y: 0, ref: React.createRef() }, { x: '5 AM', y: 0, ref: React.createRef() }, { x: '6 AM', y: 0, ref: React.createRef() }, { x: '7 AM', y: 0, ref: React.createRef() }, { x: '8 AM', y: 0, ref: React.createRef() }, { x: '9 AM', y: 0, ref: React.createRef() }, { x: '10 AM', y: 0, ref: React.createRef() }, { x: '11 AM', y: 0, ref: React.createRef() }, ]; const style = { paddingTop: '4rem', }; const DataInput = ({ xValue, yValue, myRef, changeHandler, }) => { const onChange = useCallback((newYValue) => { changeHandler(newYValue, xValue); }, [changeHandler, xValue]); return (React.createElement("div", { style: { width: '70%', margin: 'auto' } }, React.createElement(TextFieldValidated, { value: yValue || 0, onBlur: onChange, tabIndex: 0, ref: myRef }), React.createElement("div", { style: { margin: 'auto', textAlign: 'center', width: '95%', marginTop: '15px', } }, xValue))); }; const Component = createClass({ getInitialState() { return { customSpendDataPoints: initialCustomSpendDataPoints, }; }, onDragHandler(newYValue, xValue, fromOnChangeHandler) { const cleanedYValue = fromOnChangeHandler ? newYValue : +Number(newYValue).toFixed(0); const newCustomSpendDataPoints = _.map(this.state.customSpendDataPoints, (dataPoint) => dataPoint.x === xValue ? { ...dataPoint, y: cleanedYValue } : dataPoint); this.setState({ customSpendDataPoints: newCustomSpendDataPoints }); return newCustomSpendDataPoints; }, onPreselectHandler(data) { this.setState({ customSpendDataPoints: data }); }, onChangeHandler(newYValue, xValue) { const currentIndex = _.findIndex(this.state.customSpendDataPoints, [ 'x', xValue, ]); const currentYValue = this.state.customSpendDataPoints[currentIndex].y; const nextValue = +Number(newYValue).toFixed(0); if (currentYValue !== nextValue) { const newCustomSpendDataPoints = this.onDragHandler(newYValue, xValue, true); const nextIndex = currentIndex >= newCustomSpendDataPoints.length - 1 ? 0 : currentIndex + 1; const myRef = newCustomSpendDataPoints[nextIndex].ref; setTimeout(() => myRef.current.focus(), 1); } }, getRenderProp({ onChangeHandler, }, { x, y, ref }) { return (React.createElement(DataInput, { xValue: x, yValue: y, myRef: ref, changeHandler: onChangeHandler })); }, render() { const { customSpendDataPoints } = this.state; const renderProp = _.partial(this.getRenderProp, { onChangeHandler: this.onChangeHandler, }); return (React.createElement("div", { style: style }, React.createElement(DraggableLineChart, { ...args, data: customSpendDataPoints, width: 900, dataIsCentered: true, onDragEnd: this.onDragHandler, xAxisRenderProp: renderProp, onPreselect: this.onPreselectHandler }))); }, }); return React.createElement(Component, null); }; /* Example With Y Axis Formatter */ export const ExampleWithYAxisFormatter = (args) => { const initialCustomSpendDataPoints = [ { x: '12 AM', y: 0, ref: React.createRef() }, { x: '1 AM', y: 1, ref: React.createRef() }, { x: '2 AM', y: 1.5, ref: React.createRef() }, { x: '3 AM', y: 2, ref: React.createRef() }, { x: '4 AM', y: 3.8, ref: React.createRef() }, { x: '5 AM', y: 3.66, ref: React.createRef() }, { x: '6 AM', y: 5, ref: React.createRef() }, { x: '7 AM', y: 10, ref: React.createRef() }, { x: '8 AM', y: 5, ref: React.createRef() }, { x: '9 AM', y: 5, ref: React.createRef() }, { x: '10 AM', y: 5, ref: React.createRef() }, { x: '11 AM', y: 5, ref: React.createRef() }, ]; const style = { paddingTop: '4rem', }; const DataInput = ({ xValue, yValue, myRef, changeHandler, }) => { const onChange = useCallback((newYValue) => { changeHandler(newYValue, xValue); }, [changeHandler, xValue]); return (React.createElement("div", { style: { width: '70%', margin: 'auto' } }, React.createElement(TextFieldValidated, { value: yValue || 0, onBlur: onChange, tabIndex: 0, ref: myRef }), React.createElement("div", { style: { margin: 'auto', textAlign: 'center', width: '95%', marginTop: '15px', } }, xValue))); }; const Component = createClass({ getInitialState() { return { customSpendDataPoints: initialCustomSpendDataPoints, }; }, onDragHandler(newYValue, xValue, fromOnChangeHandler) { const cleanedYValue = fromOnChangeHandler ? newYValue : +Number(newYValue).toFixed(0); const newCustomSpendDataPoints = _.map(this.state.customSpendDataPoints, (dataPoint) => dataPoint.x === xValue ? { ...dataPoint, y: cleanedYValue } : dataPoint); this.setState({ customSpendDataPoints: newCustomSpendDataPoints }); return newCustomSpendDataPoints; }, onChangeHandler(newYValue, xValue) { const currentIndex = _.findIndex(this.state.customSpendDataPoints, [ 'x', xValue, ]); const currentYValue = this.state.customSpendDataPoints[currentIndex].y; const nextValue = +Number(newYValue).toFixed(0); if (currentYValue !== nextValue) { const newCustomSpendDataPoints = this.onDragHandler(newYValue, xValue, true); const nextIndex = currentIndex >= newCustomSpendDataPoints.length - 1 ? 0 : currentIndex + 1; const myRef = newCustomSpendDataPoints[nextIndex].ref; setTimeout(() => myRef.current.focus(), 1); } }, getRenderProp({ onChangeHandler, }, { x, y, ref }) { return (React.createElement(DataInput, { xValue: x, yValue: y, myRef: ref, changeHandler: onChangeHandler })); }, render() { const { customSpendDataPoints } = this.state; const renderProp = _.partial(this.getRenderProp, { onChangeHandler: this.onChangeHandler, }); return (React.createElement("div", { style: style }, React.createElement(DraggableLineChart, { ...args, data: customSpendDataPoints, width: 900, dataIsCentered: true, onDragEnd: this.onDragHandler, xAxisRenderProp: renderProp, yAxisFormatter: (value) => `${value}%` }))); }, }); return React.createElement(Component, null); }; //# sourceMappingURL=DraggableLineChart.stories.js.map