Skip to content

Commit

Permalink
Merge pull request #19 from Vizzuality/client/feature/story
Browse files Browse the repository at this point in the history
Add story
  • Loading branch information
barbara-chaves authored Nov 28, 2023
2 parents 604b2c9 + 6a99b6a commit d3d778c
Show file tree
Hide file tree
Showing 24 changed files with 5,326 additions and 10,282 deletions.
4,161 changes: 0 additions & 4,161 deletions client/package-lock.json

This file was deleted.

3 changes: 3 additions & 0 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"@types/node": "20.3.1",
"@types/react": "18.2.12",
"@types/react-dom": "18.2.5",
"apng-js": "^1.1.1",
"autoprefixer": "10.4.14",
"axios": "^1.4.0",
"class-variance-authority": "^0.6.0",
Expand All @@ -48,6 +49,8 @@
"eslint": "8.42.0",
"eslint-config-next": "13.4.5",
"framer-motion": "^10.16.4",
"highcharts": "^11.2.0",
"highcharts-react-official": "^3.2.1",
"lucide-react": "^0.252.0",
"mapbox-gl": "2.15.0",
"next": "13.4.5",
Expand Down
39 changes: 39 additions & 0 deletions client/src/components/chart/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import Highcharts from 'highcharts';
import HighchartsReact from 'highcharts-react-official';

const Chart = ({ options }: { options: any }) => {
return (
<div className="h-[500px] w-[500px]">
<HighchartsReact
highcharts={Highcharts}
options={{
title: { text: '' },
series: options.series,
chart: {
...options.chart,
backgroundColor: 'transparent',
height: '300px',
},
legend: { enabled: false },
xAxis: {
labels: { style: { color: '#fff' } },
legend: { style: { color: '#fff' } },
lineWidth: 0,
},
yAxis: {
title: { text: '' },
gridLineDashStyle: 'Dash',
gridLineColor: 'rgba(255, 255, 255, 0.80)',
lineColor: '#ff0000',
gridLineWidth: 1,
legend: { style: { color: '#fff' }, title: { text: '' } },
labels: { style: { color: '#fff' } },
},
...options,
}}
/>
</div>
);
};

export default Chart;
143 changes: 143 additions & 0 deletions client/src/components/map/layers/animated-tile-layer/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
'use client';

import { useEffect, useMemo, useState } from 'react';

import { TileLayer } from '@deck.gl/geo-layers';
import { BitmapLayer } from '@deck.gl/layers';
import parseAPNG from 'apng-js';
import { useIntervalWhen } from 'rooks';

import { LayerProps } from '@/types/layers';

import { useDeckMapboxOverlayContext } from '@/components/map/provider';

export type DeckLayerProps<T> = LayerProps &
T & {
type: any;
config: any;
paramsConfig: any;
};

const AnimatedTileLayer = <T,>({ id, type, config, paramsConfig, ...props }: DeckLayerProps<T>) => {
// Render deck layer
const i = `${id}-deck`;
const { addLayer, removeLayer } = useDeckMapboxOverlayContext();
const [frame, setFrame] = useState(0);
const SATELLITE_DECK_LAYER = useMemo(() => {
const { opacity = 1, visible = true } = paramsConfig;
const { minZoom, maxZoom, url } = config;
return [
new TileLayer({
id: i,
beforeId: id,
frame,
// getPolygonOffset: () => {
// return [0, 5000000];
// },
getTileData: (tile: any) => {
const {
index: { x, y, z },
signal,
} = tile;
// const url = `https://fra1.digitaloceanspaces.com/esa-gda-comms-staging/APNGs/SatelliteImagery/${z}/${x}/${y}.png`;
const url = `https://fra1.digitaloceanspaces.com/esa-gda-comms-staging/APNGs/Settlement/${z}/${x}/${y}.png`;
// const url = `https://storage.googleapis.com/skydipper_materials/movie-tiles/MODIS/APNGs/${z}/${x}/${y}.png`;

const response = fetch(url, { signal });

if (signal.aborted) {
return null;
}

return response
.then((res) => res.arrayBuffer())
.then((buffer) => {
const apng = parseAPNG(buffer);
if (apng instanceof Error) {
throw apng;
}
return apng.frames.map((f: any) => {
return {
...f,
bitmapData: createImageBitmap(f.imageData),
};
});
});
},
tileSize: 256,
visible: true,
opacity: 1,
refinementStrategy: 'no-overlap',
renderSubLayers: (sl: any) => {
if (!sl) return null;

const { id: subLayerId, data, tile, visible, opacity = 1, frame: f } = sl;

if (!tile || !data) return null;

const {
z,
bbox: { west, south, east, north },
} = tile;

const FRAME = data[f];

if (FRAME) {
return new BitmapLayer({
id: subLayerId,
beforeId: id,
image: FRAME.bitmapData,
bounds: [west, south, east, north],
getPolygonOffset: () => {
return [0, 5000];
},
// textureParameters: {
// [GL.TEXTURE_MIN_FILTER]: GL.NEAREST,
// [GL.TEXTURE_MAG_FILTER]: GL.NEAREST,
// [GL.TEXTURE_WRAP_S]: GL.CLAMP_TO_EDGE,
// [GL.TEXTURE_WRAP_T]: GL.CLAMP_TO_EDGE,
// },
zoom: z,
visible: true,
opacity: 1,
});
}
return null;
},
minZoom: 9,
maxZoom: 14,
// extent: initialViewState.bounds,
}),
];
}, [config, i, paramsConfig, frame]);

useIntervalWhen(() => {
setFrame((prev) => {
if (prev === 21) {
return 0;
}

return prev + 1;
});
}, 1000);

useEffect(() => {
// const ly = new type({
// ...props,
// id: i,
// beforeId: id,
// });
console.log(SATELLITE_DECK_LAYER);
addLayer(SATELLITE_DECK_LAYER);
}, [i, id, type, props, addLayer, SATELLITE_DECK_LAYER]);

useEffect(() => {
return () => {
removeLayer(i);
};
}, [i, removeLayer]);

return null;
};

export default AnimatedTileLayer;
4 changes: 2 additions & 2 deletions client/src/components/ui/dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ const Dialog = DialogPrimitive.Root;

const DialogTrigger = DialogPrimitive.Trigger;

const DialogPortal = ({ className, ...props }: DialogPrimitive.DialogPortalProps) => (
<DialogPrimitive.Portal className={cn(className)} {...props} />
const DialogPortal = ({ ...props }: DialogPrimitive.DialogPortalProps) => (
<DialogPrimitive.Portal {...props} />
);
DialogPortal.displayName = DialogPrimitive.Portal.displayName;

Expand Down
4 changes: 2 additions & 2 deletions client/src/components/ui/sheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ const SheetTrigger = SheetPrimitive.Trigger;

const SheetClose = SheetPrimitive.Close;

const SheetPortal = ({ className, ...props }: SheetPrimitive.DialogPortalProps) => (
<SheetPrimitive.Portal className={cn(className)} {...props} />
const SheetPortal = ({ ...props }: SheetPrimitive.DialogPortalProps) => (
<SheetPrimitive.Portal {...props} />
);
SheetPortal.displayName = SheetPrimitive.Portal.displayName;

Expand Down
4 changes: 2 additions & 2 deletions client/src/constants/mapbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ import env from '@/env.mjs';
export const MAPBOX_STYLES = {
default:
env.NEXT_PUBLIC_ENVIRONMENT === 'production'
? 'mapbox://styles/layer-manager/clj8fgofm000t01pjcu21agsd?fresh=true'
: 'mapbox://styles/layer-manager/clj8fgofm000t01pjcu21agsd?fresh=true',
? 'mapbox://styles/vizzualityesa/clpb479bt007101o9cmnn1dq9?fresh=true'
: 'mapbox://styles/vizzualityesa/clpb479bt007101o9cmnn1dq9?fresh=2',
};
6 changes: 3 additions & 3 deletions client/src/containers/map/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import HomeMarkers from '@/containers/map/markers/home-markers';
import StoryMarkers from '@/containers/map/markers/story-markers';
import Popup from '@/containers/map/popup';
// import MapSettings from '@/containers/map/settings';
import MapSettingsManager from '@/containers/map/settings/manager';
// import MapSettingsManager from '@/containers/map/settings/manager';

import Map from '@/components/map';
// import Controls from '@/components/map/controls';
Expand Down Expand Up @@ -204,7 +204,7 @@ export default function MapContainer() {
minZoom={minZoom}
maxZoom={maxZoom}
mapStyle={MAPBOX_STYLES.default}
fog={FOG}
// fog={FOG}
interactiveLayerIds={layersInteractiveIds}
// onClick={handleMapClick}
onMouseMove={handleMapMove}
Expand All @@ -225,7 +225,7 @@ export default function MapContainer() {

<Popup />

<MapSettingsManager />
{/* <MapSettingsManager /> */}

{isHomePage && <HomeMarkers />}

Expand Down
14 changes: 14 additions & 0 deletions client/src/containers/map/layer-manager/item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { useGetLayersId } from '@/types/generated/layer';
import { LayerResponseDataObject } from '@/types/generated/strapi.schemas';
import { Config, LayerTyped } from '@/types/layers';

import AnimatedDeckLayer from '@/components/map/layers/animated-tile-layer';
import DeckJsonLayer from '@/components/map/layers/deck-json-layer';
import MapboxLayer from '@/components/map/layers/mapbox-layer';

Expand Down Expand Up @@ -103,6 +104,19 @@ const LayerManagerItem = ({ id, beforeId, settings }: LayerManagerItemProps) =>

return <DeckJsonLayer id={`${id}-layer`} beforeId={beforeId} config={c} />;
}

if (type === 'animated-tiles') {
const { config, params_config } = data.data.attributes;
return (
<AnimatedDeckLayer
type=""
id={`${id}-layer`}
beforeId={beforeId}
config={config}
paramsConfig={params_config}
/>
);
}
};

export default LayerManagerItem;
29 changes: 18 additions & 11 deletions client/src/containers/story/steps/layouts/map-step.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {

import CategoryIcon from '@/components/ui/category-icon';
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
import Chart from '@/components/chart';

const Legend = dynamic(() => import('@/containers/map/legend'), {
ssr: false,
Expand All @@ -33,6 +34,8 @@ const MapStepLayout = ({ step, category, showContent, stepIndex }: MapStepLayout
scrollToItem(stepIndex + 1);
};

console.log(card);

return (
<div className="pointer-events-none h-full">
<div className="bg-yellow-400a flex h-full justify-between px-14 pt-[84px]">
Expand Down Expand Up @@ -63,18 +66,22 @@ const MapStepLayout = ({ step, category, showContent, stepIndex }: MapStepLayout
<div className="flex flex-1 items-end justify-end">
<div className="h-[150vh] w-fit">
<div className="sticky top-0 flex h-screen flex-col justify-end space-y-6 pb-6">
<div
onClick={handleClickCard}
className={cn(
'pointer-events-auto cursor-pointer overflow-hidden rounded border border-gray-800 bg-[#335e6f] bg-opacity-50 p-8 backdrop-blur transition-all duration-300 ease-in-out',
showContent ? 'opacity-100' : 'opacity-0'
)}
>
<div className="h-full w-96 space-y-1">
{card?.title && <h3 className="text-2xl font-bold">{card?.title}</h3>}
<p className="font-inter text-sm">{card?.content}</p>
{card?.map((item) => (
<div
key={item?.id}
onClick={handleClickCard}
className={cn(
'pointer-events-auto cursor-pointer overflow-hidden rounded border border-gray-800 bg-[#335e6f] bg-opacity-50 p-8 backdrop-blur transition-all duration-300 ease-in-out',
showContent ? 'opacity-100' : 'opacity-0'
)}
>
<div className="h-full w-[500px] space-y-1">
{item?.title && <h3 className="text-2xl font-bold">{item?.title}</h3>}
{item?.content && <p className="font-inter text-sm">{item?.content}</p>}
{!!item?.widget && <Chart options={item?.widget} />}
</div>
</div>
</div>
))}
<div
className={cn('pointer-events-auto', {
'opacity-100': showContent,
Expand Down
7 changes: 5 additions & 2 deletions client/src/lib/json-converter/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import FUNCTIONS from '@/lib/utils';

import { ParamsConfig } from '@/types/layers';

import AnimatedTileLayer from '@/components/map/layers/animated-tile-layer';
import {
LegendTypeBasic,
LegendTypeChoropleth,
Expand All @@ -27,6 +28,7 @@ export const JSON_CONFIGURATION = new JSONConfiguration({
LegendTypeBasic,
LegendTypeChoropleth,
LegendTypeGradient,
AnimatedTileLayer,
},
});

Expand Down Expand Up @@ -68,8 +70,8 @@ interface ParseConfigurationProps {
}
export const parseConfig = <T>({
config,
params_config,
settings,
params_config = [],
settings = {},
}: ParseConfigurationProps): T | null => {
if (!config || !params_config) {
return null;
Expand All @@ -87,5 +89,6 @@ export const parseConfig = <T>({
params,
},
});

return JSON_CONVERTER.convert(config);
};
Loading

0 comments on commit d3d778c

Please sign in to comment.