lucid-ui
Version:
A UI component library from Xandr.
364 lines • 17 kB
JavaScript
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