ReactJS - GiovanniDw/frontend-applications GitHub Wiki
A JavaScript library for building user interfaces
Table of Content
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>
);
};
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);
}
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>;
};
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};
}
`;
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;
};