Skip to content

Commit

Permalink
Map + Charts
Browse files Browse the repository at this point in the history
- implemented frappe chart for placemarks by category
- implemented leaflet map
- implemented both in the create (soon to be renamed dashboard) +page
- additional map layers and charts to come

known issue: svelte will occasionally throw a "window not defined" error resulting from the leaflet src. Investigating
  • Loading branch information
chipspeak authored Apr 28, 2024
1 parent ee97518 commit 2035948
Show file tree
Hide file tree
Showing 14 changed files with 293 additions and 18 deletions.
52 changes: 52 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,19 @@
"@sveltejs/kit": "^2.5.5",
"@sveltejs/vite-plugin-svelte": "^3.0.2",
"@types/eslint": "^8.56.7",
"@types/leaflet": "^1.9.12",
"@typescript-eslint/eslint-plugin": "^7.5.0",
"@typescript-eslint/parser": "^7.5.0",
"axios": "^1.6.8",
"eslint": "^8.56.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-svelte": "^2.35.1",
"leaflet": "^1.9.4",
"prettier": "^3.2.5",
"prettier-plugin-svelte": "^3.2.2",
"svelte": "^4.2.12",
"svelte-check": "^3.6.9",
"svelte-frappe-charts": "^1.10.0",
"tslib": "^2.6.2",
"typescript": "^5.4.4",
"vite": "^5.2.8"
Expand Down
9 changes: 7 additions & 2 deletions src/lib/types/placemark-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ export interface newPlacemark {
title: string;
description: string;
location: string;
latitude: string;
longitude: string;
latitude: number;
longitude: number;
category: string;
img?: string;
}
Expand All @@ -27,4 +27,9 @@ export interface Placemark extends newPlacemark {
userId: string;
}

export interface DataSet {
labels: string[];
datasets: [{ values: number[] }];
}


55 changes: 55 additions & 0 deletions src/lib/ui/LeafletMap.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<script lang="ts">
import "leaflet/dist/leaflet.css";
import { onMount } from "svelte";
import type { Control, Map as LeafletMap } from "leaflet";
import L from "leaflet";
export let id = "home-map-id";
export let height = 80;
export let location = { lat: 53.2734, lng: -7.7783203 };
export let zoom = 8;
export let minZoom = 5;
export let activeLayer = "Terrain";
let imap: LeafletMap;
let control: Control.Layers;
let overlays: Control.LayersObject = {};
let baseLayers: any;
onMount(async () => {
const leaflet = await import("leaflet");
baseLayers = {
Terrain: leaflet.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
maxZoom: 17,
attribution:
'Map data: &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, <a href="http://viewfinderpanoramas.org">SRTM</a> | Map style: &copy; <a href="https://opentopomap.org">OpenTopoMap</a> (<a href="https://creativecommons.org/licenses/by-sa/3.0/">CC-BY-SA</a>)'
}),
Satellite: leaflet.tileLayer("https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}", {
attribution: "Tiles &copy; Esri &mdash; Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community"
})
};
let defaultLayer = baseLayers[activeLayer];
imap = leaflet.map(id, {
center: [location.lat, location.lng],
zoom: zoom,
minZoom: minZoom,
layers: [defaultLayer]
});
control = leaflet.control.layers(baseLayers, overlays).addTo(imap);
});
export function moveTo(lat: number, lng: number) {
imap.flyTo({ lat: lat, lng: lng });
}
export function addMarker(lat: number, lng: number, popupText: string) {
const marker = L.marker([lat, lng]).addTo(imap);
const popup = L.popup({ autoClose: false, closeOnClick: false });
popup.setContent(popupText);
marker.bindPopup(popup);
}
</script>

<div {id} class="box" style="height: {height}vh" />
2 changes: 2 additions & 0 deletions src/lib/ui/Menu.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
<a class="navbar-item" href="/create"> Create </a>
<a class="navbar-item" href="/report"> View </a>
<a class="navbar-item" href="/gallery"> Gallery </a>
<a class="navbar-item" href="/charts"> Charts </a>
<a class="navbar-item" href="/maps"> Maps </a>
<a class="navbar-item" href="/logout"> Logout [{$currentSession.name}]</a>
</div>
</div>
Expand Down
21 changes: 21 additions & 0 deletions src/lib/utils/placemark-calculations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type { Placemark, DataSet } from "$lib/types/placemark-types";

export function calculateCategoryData(placemarks: Placemark[]): DataSet {
const categoriesTotal: DataSet = {
labels: [],
datasets: [{ values: [] }],
};

// Calculate category counts
const categoryCounts = placemarks.reduce((counts, placemark) => {
const category = placemark.category;
counts[category] = (counts[category] || 0) + 1;
return counts;
}, {} as Record<string, number>);

// Update chart data
categoriesTotal.labels = Object.keys(categoryCounts);
categoriesTotal.datasets[0].values = Object.values(categoryCounts);

return categoriesTotal;
}
8 changes: 5 additions & 3 deletions src/routes/+layout.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="ts">
import { browser } from "$app/environment";
import { currentSession } from "$lib/stores";
import { currentSession, subTitle } from "$lib/stores";
import Heading from "$lib/ui/Heading.svelte";
import Menu from "$lib/ui/Menu.svelte";
Expand All @@ -15,8 +15,10 @@

<div class="container">
{#if $currentSession?.token}
<Menu />
<Heading />
{#if $subTitle}
<Menu />
<Heading />
{/if}
{/if}
<slot />
</div>
43 changes: 43 additions & 0 deletions src/routes/charts/+page.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<script lang="ts">
// @ts-ignore
import Chart from "svelte-frappe-charts";
import Charts from "./Charts.svelte";
import Card from "$lib/ui/Card.svelte";
import { subTitle } from "$lib/stores";
import type { DataSet } from "$lib/types/placemark-types";
import { placemarkService } from "$lib/services/placemark-service";
import { currentSession, placemarkStore } from "$lib/stores";
import { get } from "svelte/store";
import { calculateCategoryData } from "$lib/utils/placemark-calculations";
import { onMount } from "svelte";
subTitle.set("Charts");
let placemarks = [];
placemarkStore.subscribe((value) => {
placemarks = value;
});
let categoriesTotal: DataSet = {
labels: [],
datasets: [{ values: [] }]
};
onMount(async () => {
const fetchedPlacemarks = await placemarkService.getPlacemarks(get(currentSession));
categoriesTotal = calculateCategoryData(fetchedPlacemarks);
});
</script>

<!-- Gallery of placemark images -->
<div>
<Card title="Charts">
<div class="columns">
<div class="column has-text-centered">
<h1 class="title is-4">Categories by number of Placemarks</h1>
<Chart data={categoriesTotal} type="bar" />
</div>
</div>
</Card>
</div>
21 changes: 21 additions & 0 deletions src/routes/charts/Charts.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<script lang="ts">
// @ts-ignore
import Chart from "svelte-frappe-charts";
let categoriesTotal = {
labels: [""],
datasets: [
{
values: [0, 0],
},
],
};
</script>

<div class="columns">
<div class="column has-text-centered">
<h1 class="title is-4">Categories by number of Placemarks</h1>
<Chart data={categoriesTotal} type="bar" />
</div>
</div>
Loading

0 comments on commit 2035948

Please sign in to comment.