ReactJS - GiovanniDw/frontend-applications GitHub Wiki

React

A JavaScript library for building user interfaces

Table of Content

Components

const App = () => {
	const nld = useNLD();
	const penr = usePenR();
	const wrld = useWrld();

	if (!nld || !penr || !wrld) {
		return <pre>Loading...</pre>;
	}
	return (
		<div className='App'>
			<SVGContainer width='100%' height='100%'>
				<DrawMap nld={nld} penr={penr} wrld={wrld} />
			</SVGContainer>
			{/* <MapNL/> */}
			<GlobalStyle />
		</div>
	);
};

SVG Component with createContext()

The createContext() api creates a reference element, this reference element is exported and van be used in other components.

import React, {
	useEffect,
	useRef,
	useState,
	createContext,
	useContext,
} from 'react';

const Context = createContext(null);

export const SVGContainer = ({ children, width, height }) => {
	const svgRef = useRef(null);
	const [svg, setSvg] = useState(null);
	useEffect(() => setSvg(svgRef.current), []);
	return (
		<svg ref={svgRef} width={width} height={height}>
			<Context.Provider value={svg}>{children}</Context.Provider>
		</svg>
	);
};

export function useSvg() {
	return useContext(Context);
}

The useEffect() hook

can be used to change values, the return of the useEffect is created to update dom element values without side Effects

import { select, zoom, geoBounds } from 'd3';
import React, { useState, useEffect } from 'react';
import { useSvg } from './SVGContainer';

export const ZoomContainer = (props) => {
	const { children, activeProvince } = props;

	const svgElement = useSvg();
	const [{ x, y, k }, setTransform] = useState({ x: 0, y: 0, k: 1 });

	const zoomed = (event) => {
		setTransform(event.transform);
	};

	if (activeProvince) {
		const currentProvince = select(activeProvince);
		// console.log(currentProvince.node());
	}

	useEffect(() => {
		if (!svgElement) return;
		const selection = select(svgElement);
		const zoomMap = zoom().scaleExtent([1, 8]).on('zoom', zoomed);

		selection.call(zoomMap);
		return () => selection.on('.zoom', null);
	}, [svgElement]);

	return <g transform={`translate(${x}, ${y}) scale(${k})`}>{children}</g>;
};

DrawMap Component

Renders topojson features to display a map to the DOM. And adds points to that map.

export const DrawMap = (props) => {
	const { gemeente, province, provinceBorder } = props.nld;
	const { allPenR } = props.penr;

	const provinces = province.features;

	// const provinceEl = useRef(null);

	const [activeProvince, setActiveProvince] = useState(null);
	// useEffect(() => props.svg(activeProvince), []);

	return (
		<ZoomContainer activeProvince={activeProvince}>
			<g className='nld'>
				<g id='gemeentes'>
					{gemeente.features.map((d) => (
						<path
							key={d.id}
							className='gemeente-grens'
							d={path(d)}
						/>
					))}
				</g>
				<g id='provinces'>
					{provinces.map((d) => (
						<Province
							data={d}
							key={d.id}
							d={path(d)}
							isActive={activeProvince === d}
							onClick={() => setActiveProvince(d)}
						/>
					))}
				</g>

				<path id='province-borders' d={path(provinceBorder)} />
				{allPenR.map((d) => {
					const [x, y] = projection([d.longitude, d.latitude]);
					return <Circle key={d.id} cx={x} cy={y} r={1} />;
				})}
			</g>
		</ZoomContainer>
	);
};
const Province = ({ d, isActive, onClick }) => {
	return (
		<path
			className={isActive ? 'province active' : 'province'}
			d={d}
			onClick={onClick}
		/>
	);
};
const Circle = styled.circle`
	fill: ${colors.blue};
	fill-opacity: 1;

	&:hover {
		fill: ${colors.darkBlue};
	}
`;

useState()

const [data, setData] = useState();

The useState Function from react makes it easyer to manage states.

the data variable from useState(); will be updated with data when the setData(data) function is called. en wil set the current data to the data variable

const csvPenR =
	'https://gist.githubusercontent.com/GiovanniDw/9ebe42d142f40e58e333e546a82f9b0d/raw/1f4e17c5e2a072e12ed5b2dce628413294a13c5e/OpenParkingPenR.csv';

const row = (d) => {
	d.latitude = +d.latitude;
	d.longitude = +d.longitude;
	return d;
};

export const usePenR = () => {
	const [data, setData] = useState(null);
	useEffect(() => {
		csv(csvPenR).then((data) => {
			const byProvince = group(data, (d) => d.province);
			const byCity = group(data, (d) => d.city);
			setData({
				byProvince: byProvince,
				byCity: byCity,
				allPenR: row(data),
			});
		});
	}, []);
	return data;
};
⚠️ **GitHub.com Fallback** ⚠️