import React, { ReactElement, useState, useCallback, useEffect } from 'react'; import { Story, Meta } from '@storybook/react/types-6-0'; // import { action } from '@storybook/addon-actions'; import MapVEuMap, { MapVEuMapProps } from '../map/MapVEuMap'; import { BoundsViewport } from '../map/Types'; import { BoundsDriftMarkerProps } from '../map/BoundsDriftMarker'; import { defaultAnimationDuration } from '../map/config/map'; import { leafletZoomLevelToGeohashLevel } from '../map/utils/leaflet-geohash'; import { Viewport } from '../map/MapVEuMap'; import { getCollectionDateChartMarkers, getCollectionDateBasicMarkers, } from './api/getMarkersFromFixtureData'; // change target component import MapVEuLegendSampleList, { LegendProps, } from '../map/MapVEuLegendSampleList'; import { ChartMarkerStandalone } from '../map/ChartMarker'; // anim import geohashAnimation from '../map/animation_functions/geohash'; import { MouseMode } from '../map/MouseTools'; import LabelledGroup from '../components/widgets/LabelledGroup'; import { Toggle } from '@veupathdb/coreui'; export default { title: 'Map/Chart Markers', component: MapVEuMap, } as Meta; const defaultAnimation = { method: 'geohash', animationFunction: geohashAnimation, duration: defaultAnimationDuration, }; // no op const handleMarkerClick = () => {}; const dropDownProps = { dropdownTitle: 'Collection Date', dropdownHref: ['#/link-1', '#/link-2', '#/link-3', '#/link-4', '#/link-5'], dropdownItemText: ['Year', 'Month', 'Date', 'Hour', 'Minute'], }; const variableProps = { variableLabel: 'Collection date', quantityLabel: 'Record count', legendInfoNumberText: 'Collections', }; const defaultMouseMode: MouseMode = 'default'; export const AllInOneRequest: Story = (args) => { const [markerElements, setMarkerElements] = useState< ReactElement[] >([]); const [legendData, setLegendData] = useState([]); const [legendRadioValue, setLegendRadioValue] = useState( 'Individual' ); const [viewport, setViewport] = useState({ center: [13, 0], zoom: 6, }); const legendRadioChange = (e: React.ChangeEvent) => { setLegendRadioValue(e.target.value); }; const [dependentAxisRange, setDependentAxisRange] = useState([ 0, 0, ]); const legendType = 'numeric'; const duration = defaultAnimationDuration; // send legendRadioValue instead of knob_YAxisRangeMethod: also send setYAxisRangeValue const handleViewportChanged = useCallback( async (bvp: BoundsViewport) => { // anim add duration & scrambleKeys const markers = await getCollectionDateChartMarkers( bvp, duration, setLegendData, handleMarkerClick, legendRadioValue, setDependentAxisRange ); setMarkerElements(markers); }, [setMarkerElements, legendRadioValue] ); // define mouseMode const [mouseMode, setMouseMode] = useState(defaultMouseMode); return ( <> ); }; AllInOneRequest.args = { height: '100vh', width: '100vw', showGrid: true, showMouseToolbar: false, // not yet implemented }; export const TwoRequests: Story = (args) => { const [markerElements, setMarkerElements] = useState< ReactElement[] >([]); const [legendData, setLegendData] = useState([]); const [legendRadioValue, setLegendRadioValue] = useState( 'Individual' ); const [viewport, setViewport] = useState({ center: [13, 0], zoom: 6, }); const legendRadioChange = (e: React.ChangeEvent) => { setLegendRadioValue(e.target.value); }; const [bvp, setBvp] = useState(null); const handleViewportChanged = useCallback( async (bvp: BoundsViewport) => { setBvp(bvp); }, [setBvp] ); const [dependentAxisRange, setDependentAxisRange] = useState([ 0, 0, ]); const legendType = 'numeric'; const duration = defaultAnimationDuration; // define mouseMode const [mouseMode, setMouseMode] = useState(defaultMouseMode); useEffect(() => { // track if effect has been cancelled let isCancelled = false; if (bvp == null) return; // Create an anonymous async function, and call it immediately. // This way we can use async-await (async () => { const markers = await getCollectionDateBasicMarkers( bvp, duration, handleMarkerClick ); if (!isCancelled) setMarkerElements(markers); if (isCancelled) return; // avoid the next request if this effect has already been cancelled const fullMarkers = await getCollectionDateChartMarkers( bvp, duration, setLegendData, handleMarkerClick, legendRadioValue, setDependentAxisRange, 2000 ); if (!isCancelled) setMarkerElements(fullMarkers); })(); // Cleanup function to set `isCancelled` to `true` return () => { isCancelled = true; }; }, [bvp, legendRadioValue]); return ( <> ); }; TwoRequests.args = { height: '100vh', width: '100vw', showGrid: true, showMouseToolbar: false, // not yet implemented }; // dependent axis log scale story export const LogScale: Story = (args) => { const [markerElements, setMarkerElements] = useState< ReactElement[] >([]); const [legendData, setLegendData] = useState([]); const [legendRadioValue, setLegendRadioValue] = useState( 'Individual' ); const [viewport, setViewport] = useState({ center: [13, 0], zoom: 6, }); const legendRadioChange = (e: React.ChangeEvent) => { setLegendRadioValue(e.target.value); }; const [dependentAxisRange, setDependentAxisRange] = useState([ 0, 0, ]); const legendType = 'numeric'; const duration = defaultAnimationDuration; // define mouseMode const [mouseMode, setMouseMode] = useState(defaultMouseMode); const [dependentAxisLogScale, setDependentAxisLogScale] = useState(false); // send legendRadioValue instead of knob_YAxisRangeMethod: also send setYAxisRangeValue const handleViewportChanged = useCallback( async (bvp: BoundsViewport) => { // anim add duration & scrambleKeys const markers = await getCollectionDateChartMarkers( bvp, duration, setLegendData, handleMarkerClick, legendRadioValue, setDependentAxisRange, 0, dependentAxisLogScale ); setMarkerElements(markers); }, [setMarkerElements, legendRadioValue, dependentAxisLogScale] ); return ( <> {/* Y-axis range control */}
); }; LogScale.args = { height: '50vh', width: '50vw', showGrid: true, showMouseToolbar: false, // not yet implemented }; export const Standalone: Story = () => { return ( ); }; // test no data.color export const TestNoDataColor: Story = () => { return ( ); };