Skip to content
This repository has been archived by the owner on Dec 20, 2024. It is now read-only.

Commit

Permalink
chore(lint): use impargo eslint configs
Browse files Browse the repository at this point in the history
  • Loading branch information
KhaledSakr committed Mar 7, 2024
1 parent 7a25c55 commit 066f0cb
Show file tree
Hide file tree
Showing 33 changed files with 2,571 additions and 1,574 deletions.
11 changes: 11 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module.exports = {
extends: ['@impargo/eslint-config'],
plugins: ['react-hooks'],
rules: {
'react-hooks/rules-of-hooks': 'error',
'react-hooks/exhaustive-deps': 'warn',
},
env: {
browser: true,
},
}
16 changes: 8 additions & 8 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
- uses: actions/setup-node@v4
with:
node-version: 14
node-version: 20
- name: Cache
uses: actions/cache@v1.0.3
with:
Expand All @@ -24,9 +24,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
- uses: actions/setup-node@v4
with:
node-version: 14
node-version: 20
- name: Restore cache
uses: actions/cache@v1.0.3
with:
Expand All @@ -40,9 +40,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
- uses: actions/setup-node@v4
with:
node-version: 14
node-version: 20
- name: Restore cache
uses: actions/cache@v1.0.3
with:
Expand All @@ -55,9 +55,9 @@ jobs:
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@v2
# - uses: actions/setup-node@v1
# - uses: actions/setup-node@v4
# with:
# node-version: 14
# node-version: 20
# - name: Restore cache
# uses: actions/cache@v1.0.3
# with:
Expand Down
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"typescript.tsdk": "node_modules/typescript/lib"
}
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"coverage:post": "cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js",
"prepublishOnly": "gulp",
"transpile": "gulp transpile",
"lint": "tslint --config tslint.json --project tsconfig.json --type-check",
"lint": "eslint 'src/**/*.{js,ts,tsx}' 'test/**/*.{js,ts,tsx}' 'testbench/**/*.{js,ts,tsx}'",
"dev": "parcel testbench/index.html"
},
"repository": {
Expand Down Expand Up @@ -46,6 +46,7 @@
"homepage": "https://github.com/impargo/react-here-maps#readme",
"devDependencies": {
"@babel/core": "^7.12.0",
"@impargo/eslint-config": "^1.4.0",
"@types/chai": "^4.0.1",
"@types/enzyme": "^3.10.8",
"@types/heremaps": "^3.1.5",
Expand All @@ -67,6 +68,7 @@
"coveralls": "^2.11.12",
"css-loader": "^0.28.4",
"enzyme": "^3.11.0",
"eslint-plugin-react-hooks": "^4.6.0",
"gulp": "^4.0.2",
"gulp-sass": "^5.1.0",
"gulp-typescript": "^5.0.1",
Expand Down Expand Up @@ -105,8 +107,6 @@
"source-map-loader": "^0.2.1",
"style-loader": "^0.18.2",
"ts-loader": "^2.2.2",
"tslint": "^5.5.0",
"tslint-react": "^3.0.0",
"typescript": "^4.0.5",
"vinyl-source-stream": "^1.1.0",
"watchify": "^3.7.0"
Expand Down
99 changes: 50 additions & 49 deletions src/Cluster.tsx
Original file line number Diff line number Diff line change
@@ -1,47 +1,48 @@
import { useCallback, useContext, useEffect, useMemo, useRef } from "react";
import { HEREMapContext } from "./context";
import getMarkerIcon from "./utils/get-marker-icon";
import { useCallback, useContext, useEffect, useMemo, useRef } from 'react'

import { HEREMapContext } from './context'
import getMarkerIcon from './utils/get-marker-icon'

export interface Datapoint<T> {
lat: number;
lon: number;
lat: number,
lon: number,
/**
* Any generic data that can be stored in the datapoint.
*/
data: T;
data: T,
}

export interface ClusterProps<T> {
/**
* The datapoints that should be clustered. They should contain coordinates, a bitmap, and any generic type of data.
* Note: a change in this array will force a reclustering of the entire cluster.
*/
points: Array<Datapoint<T>>;
points: Array<Datapoint<T>>,
/**
* Clustering options used by HERE maps clustering provider.
* Note: a change in these options will recreate the clustering provider.
*/
clusteringOptions?: H.clustering.Provider.ClusteringOptions;
clusteringOptions?: H.clustering.Provider.ClusteringOptions,
/**
* A function that should return the marker bitmap to be used for a specific set of cluster points.
* Note: a change in this function will trigger a redraw for all the datapoints in the cluster.
* So make sure to wrap it in a `useCallback` and only change its reference when necessary.
*/
getBitmapForCluster: (points: T[]) => string;
getBitmapForCluster: (points: T[]) => string,
/**
* A function that should return the marker bitmap for a single point.
* Note: a change in this function will trigger a redraw for all the datapoints in the cluster.
* So make sure to wrap it in a `useCallback` and only change its reference when necessary.
*/
getBitmapForPoint: (point: T) => string;
getBitmapForPoint: (point: T) => string,
/**
* A callback for when a cluster of points are clicked.
*/
onClusterClick: (data: T[], e: H.mapevents.Event) => void;
onClusterClick: (data: T[], e: H.mapevents.Event) => void,
/**
* A callback for when a single point in the cluster is clicked.
*/
onPointClick: (data: T, e: H.mapevents.Event) => void;
onPointClick: (data: T, e: H.mapevents.Event) => void,
}

export const defaultClusteringOptions: H.clustering.Provider.ClusteringOptions = {
Expand All @@ -53,98 +54,98 @@ export const defaultClusteringOptions: H.clustering.Provider.ClusteringOptions =
* Minimum weight of points required to form a cluster (default weight for a cluster point is 1).
*/
minWeight: 2,
};
}

function createTheme<T>(
function createTheme<T> (
getBitmapForCluster: (points: T[]) => string,
getBitmapForPoint: (point: T) => string,
): H.clustering.ITheme {
return {
getClusterPresentation: (cluster) => {
const clusterPoints: T[] = [];
cluster.forEachDataPoint((point) => clusterPoints.push(point.getData()));
const clusterPoints: T[] = []
cluster.forEachDataPoint((point) => clusterPoints.push(point.getData()))
return new H.map.Marker(cluster.getPosition(), {
data: clusterPoints,
icon: getMarkerIcon(getBitmapForCluster(clusterPoints)),
max: cluster.getMaxZoom(),
min: cluster.getMinZoom(),
});
})
},
getNoisePresentation: (point) => {
const data: T = point.getData();
const data: T = point.getData()
return new H.map.Marker(point.getPosition(), {
data,
icon: getMarkerIcon(getBitmapForPoint(data)),
min: point.getMinZoom(),
});
})
},
};
}
}

function pointToDatapoint<T>(point: Datapoint<T>): H.clustering.DataPoint {
return new H.clustering.DataPoint(point.lat, point.lon, null, point.data);
function pointToDatapoint<T> (point: Datapoint<T>): H.clustering.DataPoint {
return new H.clustering.DataPoint(point.lat, point.lon, null, point.data)
}

/**
* A component that can automatically cluster a group of datapoints.
*/
export default function Cluster<T>({
export default function Cluster<T> ({
points,
clusteringOptions = defaultClusteringOptions,
getBitmapForCluster,
getBitmapForPoint,
onClusterClick,
onPointClick,
}: ClusterProps<T>): null {
const { map } = useContext(HEREMapContext);
const { map } = useContext(HEREMapContext)

const onClusterClickRef = useRef(onClusterClick);
onClusterClickRef.current = onClusterClick;
const onClusterClickRef = useRef(onClusterClick)
onClusterClickRef.current = onClusterClick

const onPointClickRef = useRef(onPointClick);
onPointClickRef.current = onPointClick;
const onPointClickRef = useRef(onPointClick)
onPointClickRef.current = onPointClick

const theme: H.clustering.ITheme = useMemo(() => createTheme(
getBitmapForCluster,
getBitmapForPoint,
), [getBitmapForCluster, getBitmapForPoint]);
), [getBitmapForCluster, getBitmapForPoint])

const datapoints = useMemo(() => points.map(pointToDatapoint), [points]);
const datapoints = useMemo(() => points.map(pointToDatapoint), [points])

const onClick = useCallback((evt: Event) => {
const e = evt as unknown as H.mapevents.Event;
const data: T | T[] = (e.target as H.map.Object).getData();
const e = evt as unknown as H.mapevents.Event
const data: T | T[] = (e.target as H.map.Object).getData()
if (Array.isArray(data)) {
onClusterClickRef.current(data, e);
onClusterClickRef.current(data, e)
} else {
onPointClickRef.current(data, e);
onPointClickRef.current(data, e)
}
}, []);
}, [])

const clusteredDataProvider = useMemo(() => {
const provider = new H.clustering.Provider(datapoints, {
clusteringOptions,
theme,
});
provider.addEventListener("tap", onClick);
return provider;
}, [clusteringOptions, onClick /* theme, datapoints */]);
})
provider.addEventListener('tap', onClick)
return provider
}, [clusteringOptions, onClick])

Check warning on line 132 in src/Cluster.tsx

View workflow job for this annotation

GitHub Actions / lint

React Hook useMemo has missing dependencies: 'datapoints' and 'theme'. Either include them or remove the dependency array

useEffect(() => {
clusteredDataProvider.setTheme(theme);
}, [theme, clusteredDataProvider]);
clusteredDataProvider.setTheme(theme)
}, [theme, clusteredDataProvider])

useEffect(() => {
clusteredDataProvider.setDataPoints(datapoints);
}, [datapoints, clusteredDataProvider]);
clusteredDataProvider.setDataPoints(datapoints)
}, [datapoints, clusteredDataProvider])

useEffect(() => {
const layer = new H.map.layer.ObjectLayer(clusteredDataProvider);
map?.addLayer(layer);
const layer = new H.map.layer.ObjectLayer(clusteredDataProvider)
map?.addLayer(layer)
return () => {
map?.removeLayer(layer);
};
}, [map, clusteredDataProvider]);
map?.removeLayer(layer)
}
}, [map, clusteredDataProvider])

return null;
return null
}
Loading

0 comments on commit 066f0cb

Please sign in to comment.