import React, { useState } from 'react';
import ScatterPlot, { ScatterPlotProps } from '../../plots/ScatterPlot';
import { Story, Meta } from '@storybook/react/types-6-0';
// test to use RadioButtonGroup directly instead of ScatterPlotControls
import RadioButtonGroup from '../../components/widgets/RadioButtonGroup';
import { FacetedData, ScatterPlotData } from '../../types/plots';
import FacetedScatterPlot from '../../plots/facetedPlots/FacetedScatterPlot';
import SliderWidget, {
SliderWidgetProps,
} from '../../components/widgets/Slider';
// Import scatterplot data
import {
dataSetSequentialGradient,
dataSet,
dateStringDataSet,
processInputData,
} from './ScatterPlot.storyData';
export default {
title: 'Plots/ScatterPlot',
component: ScatterPlot,
parameters: {
redmine: 'https://redmine.apidb.org/issues/41310',
},
} as Meta;
/*
Testing scatter, line, and density plots
Case 1: number string; Case 2: date string
Note that all plots will display smoothed mean line and confidence interval
:it is because only single dataset is commonly used in this story
uncomment Case (line starting with const { dataSetProcess, yMin, yMax }) to test each case
Did not try to make it separate because each case requires the same function, processInputData
**/
// Case 1. X and Y: number string cases
const independentValueType = 'number';
const dependentValueType = 'number';
// Case 1-1) checking scatter plot: raw data with smoothed mean and confidence interval
const { dataSetProcess, yMin, yMax } = processInputData(
dataSet,
'scatterplot',
'markers',
independentValueType,
dependentValueType,
true
);
const { dataSetProcess: dataSetProcessDefaultColors } = processInputData(
dataSet,
'scatterplot',
'markers',
independentValueType,
dependentValueType,
false
);
const { dataSetProcess: dataSetProcessSequentialGradient } = processInputData(
dataSetSequentialGradient,
'scatterplot',
'markers',
independentValueType,
dependentValueType,
false
);
// Case 1-2) checking line plot: raw data with line
// const { dataSetProcess, yMin, yMax } = processInputData(
// dataSet,
// 'lineplot',
// 'lines',
// independentValueType,
// dependentValueType
// );
// Case 1-3) checking density plot: raw data with filled area
// const { dataSetProcess, yMin, yMax } = processInputData(dataSet, 'densityplot', 'lines', independentValueType, dependentValueType);
// // // Case 2. X or Y : date string (yyyy-mm-dd) case
// // Case 2-1
// const independentValueType = 'date';
// const dependentValueType = 'number';
// // Case 2-2
// const independentValueType = 'number';
// const dependentValueType = 'date';
// const { dataSetProcess, yMin, yMax } = processInputData(dateStringDataSet, 'scatterplot', 'markers', independentValueType, dependentValueType, false);
// set some default props
const plotWidth = 1000;
const plotHeight = 600;
const independentAxisLabel = 'independent axis label';
const dependentAxisLabel = 'dependent axis label';
const plotTitle = '';
export const MultipleDataDefaultColors = () => {
return (
);
};
export const EmptyData = () => {
return (
);
};
export const EmptyDataLoading = () => {
return (
);
};
// test plot mode control to directly access RadioButtonGroup
// also, test for disabling radio item(s)
export const PlotModeControl = () => {
const [valueSpec, setValueSpec] = useState('Raw');
const onValueSpecChange = (value: string) => {
setValueSpec(value);
};
return (
);
};
const Template = (args: any) => ;
const disableDataControl = {
data: { control: { disable: true } },
};
// adding storybook control
export const WithStorybookControl: Story = Template.bind({});
// set default values for args that use default storybook control
WithStorybookControl.args = {
data: dataSetProcess,
interactive: true,
displayLegend: true,
displayLibraryControls: true,
showSpinner: false,
legendTitle: 'Legend title example',
independentAxisLabel: 'Floor material',
dependentAxisLabel: 'Sleeping rooms in dwelling',
containerStyles: {
width: plotWidth,
height: plotHeight,
},
};
// Don't show "data" in storybook controls because it's impractical to edit it
WithStorybookControl.argTypes = disableDataControl;
/**
* FACETING
*/
const facetedData: FacetedData = {
facets: [
{
label: 'Facet 1',
data: dataSetProcess,
},
{
label: 'Facet 2',
data: dataSetProcess,
},
{
label: 'Facet 3',
data: dataSetProcess,
},
{
label: 'Facet 400',
},
{
label: 'No data',
},
],
};
interface FacetedStoryProps {
data: FacetedData;
componentProps: ScatterPlotProps;
modalComponentProps: ScatterPlotProps;
}
const FacetedTemplate: Story = ({
data,
componentProps,
modalComponentProps,
}) => (
);
export const Faceted = FacetedTemplate.bind({});
Faceted.args = {
data: facetedData,
componentProps: {
title: 'Faceted ScatterPlot',
containerStyles: {
width: 300,
height: 300,
border: '1px solid #dadada',
},
},
modalComponentProps: {
containerStyles: {
width: '85%',
height: '100%',
margin: 'auto',
},
},
};
export const opacitySlider = () => {
const disabled = false;
const [markerBodyOpacity, setMarkerBodyOpacity] = useState(0);
const containerStyles = {
height: 100,
width: 425,
marginLeft: 75,
};
// gradient color
const colorSpecProps: SliderWidgetProps['colorSpec'] = {
type: 'gradient',
tooltip: '#aaa',
knobColor: '#aaa',
trackGradientStart: '#fff',
trackGradientEnd: '#000',
};
return (
<>
{/* Sequential gradient color */}
{
setMarkerBodyOpacity(newValue);
}}
containerStyles={containerStyles}
showLimits={true}
label={'Marker opacity'}
disabled={disabled}
// test gradient color
colorSpec={colorSpecProps}
/>
>
);
};