Skip to content

Commit

Permalink
feat(example): add data switching functionality with dynamic parameters
Browse files Browse the repository at this point in the history
- Add switch button to toggle between wind and ocean data
- Create dataConfigs to manage different data configurations
- Implement dynamic parameter updates for different datasets
- Add options change callback to ControlPanel
- Maintain non-specific parameters when switching datasets
- Update domain and speedFactor based on data type
  • Loading branch information
hongfaqiu committed Oct 31, 2024
1 parent eb249f9 commit af92391
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 47 deletions.
1 change: 1 addition & 0 deletions example/public/ocean.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion example/public/wind.json

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion example/public/wind2.json

This file was deleted.

20 changes: 13 additions & 7 deletions example/src/components/ControlPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -188,11 +188,13 @@ const TitleButton = styled.button`
interface ControlPanelProps {
windLayer: WindLayer | null;
initialOptions?: Partial<WindLayerOptions>;
onOptionsChange?: (options: Partial<WindLayerOptions>) => void;
}

export const ControlPanel: React.FC<ControlPanelProps> = ({
windLayer,
initialOptions,
onOptionsChange,
}) => {
const [form] = Form.useForm();
const [options, setOptions] = useState<WindLayerOptions>({
Expand All @@ -204,13 +206,15 @@ export const ControlPanel: React.FC<ControlPanelProps> = ({
const [visible, setVisible] = useState(true);

useEffect(() => {
const allValues = {
...WindLayer.defaultOptions,
...initialOptions,
};
setOptions(allValues);
form.setFieldsValue(allValues);
}, [windLayer, initialOptions]);
if (initialOptions) {
const newOptions = {
...options,
...initialOptions,
};
setOptions(newOptions);
form.setFieldsValue(newOptions);
}
}, [initialOptions]);

const renderLabel = (label: string, tooltip: string) => (
<div style={{ display: 'flex', alignItems: 'center', gap: '4px' }}>
Expand All @@ -229,6 +233,8 @@ export const ControlPanel: React.FC<ControlPanelProps> = ({
} else {
windLayer?.updateOptions(changedValues);
}

onOptionsChange?.(changedValues);
};

return (
Expand Down
140 changes: 102 additions & 38 deletions example/src/pages/earth.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,29 +22,69 @@ const CesiumContainer = styled.div`
overflow: hidden;
`;

const SwitchButton = styled.button`
position: absolute;
top: 20px;
right: 20px;
padding: 8px 16px;
background-color: rgba(255, 255, 255, 0.8);
border: 1px solid #ccc;
border-radius: 4px;
cursor: pointer;
z-index: 1000;
&:hover {
background-color: rgba(255, 255, 255, 0.9);
}
`;

// Add data configurations
const dataConfigs = {
wind: {
options: {
domain: {
min: 0,
max: 8,
},
speedFactor: 0.8,
},
file: '/wind.json'
},
ocean: {
options: {
domain: {
min: 0,
max: 1,
},
speedFactor: 8,
},
file: '/ocean.json'
}
};

const defaultOptions: Partial<WindLayerOptions> = {
particlesTextureSize: 200,
dropRate: 0.003,
particleHeight: 1000,
dropRateBump: 0.01,
speedFactor: 0.5,
lineWidth: 10.0,
colors: colorSchemes[3].colors,
flipY: true,
useViewerBounds: true,
domain: {
min: 0,
max: 8,
},
// Remove domain and speedFactor from here since they will be set dynamically
};

export function Earth() {
const viewerRef = useRef<Viewer | null>(null);
const windLayerRef = useRef<WindLayer | null>(null);
const [, setIsWindLayerReady] = useState(false);
const dataIndexRef = useRef(0);
const windDataFiles = ['/wind.json', '/wind2.json'];
const windDataFiles = [dataConfigs.wind.file, dataConfigs.ocean.file];
const isFirstLoadRef = useRef(true);
const [currentDataIndex, setCurrentDataIndex] = useState(0);
const [currentOptions, setCurrentOptions] = useState<WindLayerOptions>({
...defaultOptions,
...dataConfigs.wind.options
} as WindLayerOptions);

useEffect(() => {
let isComponentMounted = true;
Expand Down Expand Up @@ -98,6 +138,13 @@ export function Earth() {
}
};

// Apply initial options with wind configuration
const initialOptions = {
...defaultOptions,
...dataConfigs.wind.options
};
setCurrentOptions(initialOptions as WindLayerOptions);

if (isFirstLoadRef.current && windData.bounds) {
const rectangle = Rectangle.fromDegrees(
windData.bounds.west,
Expand All @@ -112,7 +159,7 @@ export function Earth() {
isFirstLoadRef.current = false;
}

const layer = new WindLayer(viewerRef.current, windData, defaultOptions);
const layer = new WindLayer(viewerRef.current, windData, initialOptions);

// Add event listeners
layer.addEventListener('dataChange', (data) => {
Expand All @@ -132,41 +179,12 @@ export function Earth() {
}
};

const updateWindData = async () => {
try {
const nextIndex = (dataIndexRef.current + 1) % windDataFiles.length;
const res = await fetch(windDataFiles[nextIndex]);
const data = await res.json();

if (!isComponentMounted || !windLayerRef.current) return;

const windData: WindData = {
...data,
bounds: {
west: data.bbox[0],
south: data.bbox[1],
east: data.bbox[2],
north: data.bbox[3],
}
};

windLayerRef.current.updateWindData(windData);
dataIndexRef.current = nextIndex;
} catch (error) {
console.error('Failed to update wind data:', error);
}
};

// Initialize wind layer
initWindLayer();

// Set up interval to update data
const intervalId = setInterval(updateWindData, 3000);

return () => {
isComponentMounted = false;
isFirstLoadRef.current = true;
clearInterval(intervalId);

if (windLayerRef.current) {
windLayerRef.current.destroy();
Expand All @@ -181,13 +199,59 @@ export function Earth() {
};
}, []);

const handleOptionsChange = (changedOptions: Partial<WindLayerOptions>) => {
setCurrentOptions({
...currentOptions,
...changedOptions
});
};

const handleSwitchData = async () => {
try {
const nextIndex = (currentDataIndex + 1) % windDataFiles.length;
const res = await fetch(windDataFiles[nextIndex]);
const data = await res.json();

if (!windLayerRef.current) return;

const windData: WindData = {
...data,
bounds: {
west: data.bbox[0],
south: data.bbox[1],
east: data.bbox[2],
north: data.bbox[3],
}
};

// Get the correct configuration based on the next index
const configKey = nextIndex === 0 ? 'wind' : 'ocean';
const newOptions = {
...currentOptions, // Keep current options
...dataConfigs[configKey].options // Only override specific options
};

// Update both the wind data and options
windLayerRef.current.updateOptions(newOptions);
windLayerRef.current.updateWindData(windData);
setCurrentOptions(newOptions);
setCurrentDataIndex(nextIndex);
} catch (error) {
console.error('Failed to switch wind data:', error);
}
};

return (
<PageContainer>
<SpeedQuery windLayer={windLayerRef.current} viewer={viewerRef.current} />
<CesiumContainer id="cesiumContainer">
<SwitchButton onClick={handleSwitchData}>
Switch to {currentDataIndex === 0 ? 'Ocean' : 'Wind'} Data
</SwitchButton>
<ControlPanel
windLayer={windLayerRef.current}
initialOptions={defaultOptions}
initialOptions={currentOptions}
onOptionsChange={handleOptionsChange}
/>
</CesiumContainer>
</PageContainer>
Expand Down

0 comments on commit af92391

Please sign in to comment.