Skip to content

Commit

Permalink
Start a different browse layout:
Browse files Browse the repository at this point in the history
- get rid of the enormous list of scheme cards, and move the buttons
  into the intervention map popup
- group all of the schemes stuff and treat as a layer
- move the layers to the left
  • Loading branch information
dabreegster committed Oct 2, 2024
1 parent 5f5cb06 commit 7a486bc
Show file tree
Hide file tree
Showing 7 changed files with 130 additions and 122 deletions.
22 changes: 11 additions & 11 deletions src/lib/browse/Filters.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,17 @@
}
</script>

<CheckboxGroup small>
<Checkbox bind:checked={show}>
Showing {schemesToBeShown.size.toLocaleString()} schemes ({counts.route.toLocaleString()}
routes, {counts.area.toLocaleString()} areas,
{counts.crossing.toLocaleString()} crossings, {counts.other.toLocaleString()}
other, with total LineString length of {metersToMiles(
counts.totalLength,
).toFixed(1)} miles)
</Checkbox>
</CheckboxGroup>

<CollapsibleCard label="Filters">
<SecondaryButton on:click={resetFilters}>Reset all filters</SecondaryButton>
<Select
Expand Down Expand Up @@ -264,14 +275,3 @@
</FormElement>
<InterventionColorSelector />
</CollapsibleCard>

<CheckboxGroup small>
<Checkbox bind:checked={show}>
Showing {schemesToBeShown.size.toLocaleString()} schemes ({counts.route.toLocaleString()}
routes, {counts.area.toLocaleString()} areas,
{counts.crossing.toLocaleString()} crossings, {counts.other.toLocaleString()}
other, with total LineString length of {metersToMiles(
counts.totalLength,
).toFixed(1)} miles)
</Checkbox>
</CheckboxGroup>
48 changes: 47 additions & 1 deletion src/lib/browse/InterventionPopup.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
<script lang="ts">
import { SecondaryButton } from "govuk-svelte";
import type { FeatureCollection } from "geojson";
import { bbox } from "lib/maplibre";
import { map } from "stores";
import { prettyPrintMeters } from "lib/maplibre";
import { filterInterventionText, filterSchemeText, schemes } from "./stores";
import {
filterInterventionText,
filterSchemeText,
schemes,
schemesGj,
} from "./stores";
import { setLocalStorageItem } from "lib/common";
import DescribePipelineTiming from "./DescribePipelineTiming.svelte";
import DescribePipelineBudget from "./DescribePipelineBudget.svelte";
Expand All @@ -18,6 +28,35 @@
(match) => `<mark>${match}</mark>`,
);
}
function showScheme() {
// TODO Highlight on the map? Or fade everything else?
let gj: FeatureCollection = {
type: "FeatureCollection",
features: $schemesGj.features.filter(
(f) => f.properties.scheme_reference == scheme.scheme_reference,
),
};
$map?.fitBounds(bbox(gj), { padding: 20, animate: false });
}
function editScheme() {
let gj = {
type: "FeatureCollection",
features: $schemesGj.features.filter(
(f) => f.properties.scheme_reference == scheme.scheme_reference,
),
};
let filename = scheme.browse?.authority_or_region || "unknown authority";
// Assuming the schema is always v1
// Put the file in local storage, so it'll be loaded from the next page
setLocalStorageItem(filename, JSON.stringify(gj));
window.open(
`scheme.html?authority=${scheme.browse?.authority_or_region}`,
"_blank",
);
}
</script>

<div style="max-width: 30vw; max-height: 60vh; overflow: auto;">
Expand Down Expand Up @@ -95,4 +134,11 @@
<DescribePipelineBudget props={p} />
<DescribePipelineTiming props={p} />
{/if}

<SecondaryButton on:click={showScheme}>
Zoom to show entire scheme
</SecondaryButton>
<SecondaryButton on:click={editScheme}>
Edit a copy of this scheme
</SecondaryButton>
</div>
8 changes: 5 additions & 3 deletions src/lib/browse/LayerControls.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@
import Stats19LayerControl from "./layers/points/Stats19.svelte";
import VehicleCountsLayerControl from "./layers/points/VehicleCounts.svelte";
import ProblemsLayerControl from "./layers/points/Problems.svelte";
import { interactiveMapLayersEnabled } from "./stores";
import SchemesLayer from "./SchemesLayer.svelte";
import { interactiveMapLayersEnabled, controls } from "./stores";
import { getRoadLayerNames } from "lib/maplibre";
import { get } from "svelte/store";
import { map, mapStyle } from "stores";
Expand Down Expand Up @@ -71,7 +72,8 @@
};
</script>

<CollapsibleCard label="Layers" open>
<div bind:this={$controls}>
<SchemesLayer />
<CollapsibleCard label="Trip generators">
<CheckboxGroup small>
<EducationLayerControl />
Expand Down Expand Up @@ -131,7 +133,7 @@
<LineMeasureTool />
</CollapsibleCard>
<BaselayerSwitcher disabled={!$interactiveMapLayersEnabled} />
</CollapsibleCard>
</div>

<GeoJSON data={coverEverything}>
<FillLayer
Expand Down
54 changes: 0 additions & 54 deletions src/lib/browse/SchemeCard.svelte

This file was deleted.

59 changes: 59 additions & 0 deletions src/lib/browse/SchemesLayer.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<script lang="ts">
import {
CollapsibleCard,
ErrorMessage,
FileInput,
SecondaryButton,
} from "govuk-svelte";
import { appVersion, Modal } from "lib/common";
import LoadRemoteSchemeData from "./LoadRemoteSchemeData.svelte";
import { processInput } from "./data";
import Filters from "./Filters.svelte";
import { schemes, schemesGj } from "./stores";
import InterventionLayer from "./InterventionLayer.svelte";
let schemesToBeShown: Set<string> = new Set();
let showSchemes = true;
let showSchemeNotes = false;
let errorMessage = "";
function loadFile(filename: string, text: string) {
try {
schemesGj.set(JSON.parse(text));
schemes.set(processInput($schemesGj));
errorMessage = "";
} catch (err) {
errorMessage = `The file you loaded is broken: ${err}`;
}
}
</script>

<CollapsibleCard label="Schemes">
{#if appVersion() == "Private (development)"}
<LoadRemoteSchemeData {loadFile} />
{/if}
{#if $schemesGj.notes}
<SecondaryButton on:click={() => (showSchemeNotes = true)}>
About the scheme data
</SecondaryButton>
<Modal title="About this scheme data" bind:open={showSchemeNotes}>
<div class="govuk-prose">
<p>Please note there are data quality caveats for all scheme data:</p>
<ul>
{#each $schemesGj.notes as note}
<li><p>{note}</p></li>
{/each}
</ul>
</div>
</Modal>
{/if}
<FileInput label="Load schemes from GeoJSON" onLoad={loadFile} />
<ErrorMessage {errorMessage} />

{#if $schemes.size > 0}
<Filters bind:schemesToBeShown bind:show={showSchemes} />
{/if}
</CollapsibleCard>

<InterventionLayer {showSchemes} />
2 changes: 2 additions & 0 deletions src/lib/browse/stores.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@ export const schemes: Writable<Map<string, SchemeData>> = writable(new Map());
export const interactiveMapLayersEnabled: Writable<boolean> = writable(true);
export const filterInterventionText: Writable<string> = writable("");
export const filterSchemeText: Writable<string> = writable("");

export let controls: Writable<HTMLDivElement | null> = writable(null);
59 changes: 6 additions & 53 deletions src/pages/BrowseSchemes.svelte
Original file line number Diff line number Diff line change
@@ -1,25 +1,18 @@
<script lang="ts">
// @ts-ignore no declarations
import { initAll } from "govuk-frontend";
import { processInput } from "lib/browse/data";
import Filters from "lib/browse/Filters.svelte";
import LayerControls from "lib/browse/LayerControls.svelte";
import LoadRemoteSchemeData from "lib/browse/LoadRemoteSchemeData.svelte";
import SchemeCard from "lib/browse/SchemeCard.svelte";
import "../style/main.css";
import InterventionLayer from "lib/browse/InterventionLayer.svelte";
import { schemes, schemesGj } from "lib/browse/stores";
import { schemesGj, controls } from "lib/browse/stores";
import {
appVersion,
Geocoder,
Layout,
LoggedIn,
MapLibreMap,
Modal,
ZoomOutMap,
Header,
} from "lib/common";
import { ErrorMessage, FileInput, SecondaryButton } from "govuk-svelte";
import { map, mapStyle } from "stores";
import { onMount } from "svelte";
import { map as sketchMapStore } from "scheme-sketcher-lib/config";
Expand All @@ -31,25 +24,16 @@
const params = new URLSearchParams(window.location.search);
mapStyle.set(params.get("style") || "dataviz");
let errorMessage = "";
let schemesToBeShown: Set<string> = new Set();
let showSchemes = true;
let showSchemeNotes = false;
// Need this for zordering to work
$: if ($map) {
sketchMapStore.set($map);
}
function loadFile(filename: string, text: string) {
try {
schemesGj.set(JSON.parse(text));
schemes.set(processInput($schemesGj));
errorMessage = "";
} catch (err) {
errorMessage = `The file you loaded is broken: ${err}`;
}
let sidebarDiv: HTMLDivElement;
$: if (sidebarDiv && $controls) {
sidebarDiv.innerHTML = "";
sidebarDiv.appendChild($controls);
}
</script>

Expand All @@ -62,44 +46,13 @@
</div>
<LoggedIn />
<p>App version: {appVersion()}</p>
{#if appVersion() == "Private (development)"}
<LoadRemoteSchemeData {loadFile} />
{/if}
{#if $schemesGj.notes}
<SecondaryButton on:click={() => (showSchemeNotes = true)}>
About the scheme data
</SecondaryButton>
<Modal title="About this scheme data" bind:open={showSchemeNotes}>
<div class="govuk-prose">
<p>Please note there are data quality caveats for all scheme data:</p>
<ul>
{#each $schemesGj.notes as note}
<li><p>{note}</p></li>
{/each}
</ul>
</div>
</Modal>
{/if}
<FileInput label="Load schemes from GeoJSON" onLoad={loadFile} />
<ErrorMessage {errorMessage} />

{#if $schemes.size > 0}
<Filters bind:schemesToBeShown bind:show={showSchemes} />
{/if}

<ul>
{#each $schemes.values() as scheme}
{#if schemesToBeShown.has(scheme.scheme_reference)}
<SchemeCard {scheme} />
{/if}
{/each}
</ul>
<div bind:this={sidebarDiv} />
</div>
<div slot="main">
<MapLibreMap style={$mapStyle} startBounds={[-5.96, 49.89, 2.31, 55.94]}>
<Geocoder />
{#if $sketchMapStore}
<InterventionLayer {showSchemes} />
<div class="top-right">
<LayerControls />
</div>
Expand Down

0 comments on commit 7a486bc

Please sign in to comment.