Skip to content

Commit

Permalink
Introduce stroke styles for lines (#239)
Browse files Browse the repository at this point in the history
  • Loading branch information
cdauth committed Feb 26, 2024
1 parent d3f482f commit df78811
Show file tree
Hide file tree
Showing 28 changed files with 334 additions and 91 deletions.
9 changes: 5 additions & 4 deletions docs/src/developers/client/types.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ separately through `linePoints` events.
* `mode` (string): The routing mode, an empty string for no routing, or `car`, `bicycle`, `pedestrian`, or `track`
* `colour` (string): The colour of this marker as a 6-digit hex value, for example `0000ff`
* `width` (number, min: 1): The width of the line
* `stroke` (string): The stroke style of the line, an empty string for solid or `dashed` or `dotted`.
* `name` (string): The name of the line
* `distance` (number): The distance of the line in kilometers (set by the server)
* `ascent`, `descent` (number): The total ascent/descent of the line in metres (set by the server)
Expand Down Expand Up @@ -107,20 +108,20 @@ their `idx` property.
* `id` (number): The ID of this type
* `name` (string): The name of this type
* `type` (string): `marker` or `line`
* `defaultColour`, `defaultSize`, `defaultSymbol`, `defaultShape`, `defaultWidth`, `defaultMode` (string/number): Default values for the
* `defaultColour`, `defaultSize`, `defaultSymbol`, `defaultShape`, `defaultWidth`, `defaultStroke`, `defaultMode` (string/number): Default values for the
different object properties
* `colourFixed`, `sizeFixed`, `symbolFixed`, `shapeFixed`, `widthFixed`, `modeFixed` (boolean): Whether those values are fixed and
* `colourFixed`, `sizeFixed`, `symbolFixed`, `shapeFixed`, `widthFixed`, `strokeFixed`, `modeFixed` (boolean): Whether those values are fixed and
cannot be changed for an individual object
* `fields` ([object]): The form fields for this type. Each field has the following properties:
* `name` (string): The name of the field. This is at the same time the key in the `data` properties of markers and lines
* `oldName` (string): When renaming a field (using [`editType(data)`](./methods.md#edittype-data)), specify the former name here
* `type` (string): The type of field, one of `textarea`, `dropdown`, `checkbox`, `input`
* `controlColour`, `controlSize`, `controlSymbol`, `controlShape`, `controlWidth` (boolean): If this field is a dropdown, whether the different options set a specific property on the object
* `controlColour`, `controlSize`, `controlSymbol`, `controlShape`, `controlWidth`, `controlStroke` (boolean): If this field is a dropdown, whether the different options set a specific property on the object
* `default` (string/boolean): The default value of this field
* `options` ([object]): If this field is a dropdown or a checkbox, an array of objects with the following properties. For a checkbox, the array has to have 2 items, the first representing the unchecked and the second the checked state.
* `value` (string): The value of this option.
* `oldValue` (string): When renaming a dropdown option (using [`editType(data)`](./methods.md#edittype-data)), specify the former value here
* `colour`, `size`, `shape`, `symbol`, `width` (string/number): The property value if this field controls that property
* `colour`, `size`, `shape`, `symbol`, `width`, `stroke` (string/number): The property value if this field controls that property

## SearchResult

Expand Down
2 changes: 1 addition & 1 deletion docs/src/developers/leaflet/lines.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ document.getElementById("draw-line-button").addEventListener("click", async () =

let routePoints;
try {
routePoints = await linesLayer.drawLine({ colour: "0000ff", width: 7 });
routePoints = await linesLayer.drawLine({ colour: "0000ff", width: 7, stroke: "" });
} catch (error) {
alert(error);
} finally {
Expand Down
3 changes: 2 additions & 1 deletion docs/src/users/lines/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

# Lines

A line is a connection of two or more points on the map and has a name, a certain style (width, colour) and some data (such as a description). It can be a straight line or a calculated route, depending on its route mode. When you add a line to a map, it is permanently saved there and visible for anyone who is viewing the map.
A line is a connection of two or more points on the map and has a name, a certain style (width, colour, stroke) and some data (such as a description). It can be a straight line or a calculated route, depending on its route mode. When you add a line to a map, it is permanently saved there and visible for anyone who is viewing the map.

By default, a collaborative map has one type of line called “Line” that has a description field and whose style can be configured freely. Other types of lines with fixed styles and additional fields can be defined using [custom types](../types/). For simplicity, the descriptions on this page are assuming that you are working with the default “Line” type.

Expand Down Expand Up @@ -62,6 +62,7 @@ To edit the details of a line, select the line and then click “Edit data” in
* **Routing mode:** The route mode of the line. By default, “straight line” is selected, but you can select something else to make the line points into route destinations. More information about route modes can be found under [routes](../route/#route-modes).
* **Colour:** The colour of the line.
* **Width:** The width of the line (in pixels). Use the + and − buttons to change the value.
* **Stroke:** The stroke style of the line (solid, dashed or dotted).
* **Description:** The description of the line. Will be shown in the line details. You can format the text using [Markdown](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet).

Click “Save” to save your changes.
Expand Down
2 changes: 1 addition & 1 deletion docs/src/users/types/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Give the type a name and select whether it is a marker or a line type. The meani

## Default style

By default, markers are red, 25 pixels tall, have no icon and a drop shape. Lines by default are blue, 4 pixels wide and use the “straight line” route mode. These settings can be changed for each individual marker.
By default, markers are red, 30 pixels tall, have no icon and a drop shape. Lines by default are blue, 4 pixels wide, solid and use the “straight line” route mode. These settings can be changed for each individual marker/line.

Using custom types, you can change these defaults. You can also make some or all of the values fixed, which means that they cannot be changed for an individual marker/line but are the same for all markers/lines of this type.

Expand Down
8 changes: 7 additions & 1 deletion frontend/src/lib/components/edit-filter-dialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@

<tr>
<td><code>mode</code></td>
<td>Line routing mode (<code>""</code> / <code>"car"</code> / <code>"bicycle"</code> / <code>"pedestrian"</code> / <code>"track"</code>)</td>
<td>Line routing mode (<code>&quot;&quot;</code> / <code>&quot;car&quot;</code> / <code>&quot;bicycle&quot;</code> / <code>&quot;pedestrian&quot;</code> / <code>&quot;track&quot;</code>)</td>
<td><code>mode in (&quot;bicycle&quot;, &quot;pedestrian&quot;)</code></td>
</tr>

Expand All @@ -157,6 +157,12 @@
<td><code>width &gt; 10</code></td>
</tr>

<tr>
<td><code>stroke</code></td>
<td>Line stroke (<code>`&quot;&quot;`</code> (solid) / <code>`&quot;dashed&quot;`</code> / <code>&quot;dotted&quot;</code>)</td>
<td><code>shape == &quot;dotted&quot;</code></td>
</tr>

<tr>
<td><code>distance</code></td>
<td>Line distance in kilometers</td>
Expand Down
13 changes: 13 additions & 0 deletions frontend/src/lib/components/edit-line-dialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import DropdownMenu from "./ui/dropdown-menu.vue";
import { injectContextRequired, requireClientContext } from "./facil-map-context-provider/facil-map-context-provider.vue";
import ValidatedField from "./ui/validated-form/validated-field.vue";
import StrokePicker from "./ui/stroke-picker.vue";
const context = injectContextRequired();
const client = requireClientContext(context);
Expand Down Expand Up @@ -120,6 +121,18 @@
</div>
</template>

<template v-if="resolvedCanControl.includes('stroke')">
<div class="row mb-3">
<label :for="`${id}-stroke-input`" class="col-sm-3 col-form-label">Stroke</label>
<div class="col-sm-9">
<StrokePicker
:id="`${id}-stroke-input`"
v-model="line.stroke"
></StrokePicker>
</div>
</div>
</template>

<template v-for="(field, idx) in client.types[line.typeId].fields" :key="field.name">
<div class="row mb-3">
<label :for="`${id}-${idx}-input`" class="col-sm-3 col-form-label text-break">{{field.name}}</label>
Expand Down
28 changes: 28 additions & 0 deletions frontend/src/lib/components/edit-type-dialog/edit-type-dialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import { showConfirm } from "../ui/alert.vue";
import { injectContextRequired, requireClientContext } from "../facil-map-context-provider/facil-map-context-provider.vue";
import ValidatedField from "../ui/validated-form/validated-field.vue";
import StrokePicker from "../ui/stroke-picker.vue";
const context = injectContextRequired();
const client = requireClientContext(context);
Expand Down Expand Up @@ -324,6 +325,33 @@
</div>
</template>

<template v-if="resolvedCanControl.includes('stroke')">
<div class="row mb-3">
<label :for="`${id}-default-stroke-input`" class="col-sm-3 col-form-label">Default stroke</label>
<div class="col-sm-9">
<div class="row align-items-center">
<div class="col-sm-9">
<StrokePicker
:id="`${id}-default-stroke-input`"
v-model="type.defaultStroke"
></StrokePicker>
</div>
<div class="col-sm-3">
<div class="form-check fm-form-check-with-label">
<input
type="checkbox"
class="form-check-input"
:id="`${id}-default-stroke-fixed`"
v-model="type.strokeFixed"
/>
<label :for="`${id}-default-stroke-fixed`" class="form-check-label">Fixed</label>
</div>
</div>
</div>
</div>
</div>
</template>

<template v-if="resolvedCanControl.includes('mode')">
<div class="row mb-3">
<label :for="`${id}-default-mode-input`" class="col-sm-3 col-form-label">Default routing mode</label>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script setup lang="ts">
import type { CRU, Field, FieldOptionUpdate, FieldUpdate, Type } from "facilmap-types";
import { canControl, mergeObject } from "facilmap-utils";
import { getUniqueId, validateRequired } from "../../utils/utils";
import { getUniqueId } from "../../utils/utils";
import { cloneDeep, isEqual } from "lodash-es";
import ColourPicker from "../ui/colour-picker.vue";
import Draggable from "vuedraggable";
Expand All @@ -16,6 +16,7 @@
import { showConfirm } from "../ui/alert.vue";
import { injectContextRequired } from "../facil-map-context-provider/facil-map-context-provider.vue";
import ValidatedField from "../ui/validated-form/validated-field.vue";
import StrokePicker from "../ui/stroke-picker.vue";
function getControlNumber(type: Type<CRU.READ | CRU.CREATE_VALIDATED>, field: FieldUpdate): number {
return [
Expand All @@ -26,7 +27,8 @@
field.controlShape
] : []),
...(type.type == "line" ? [
field.controlWidth
field.controlWidth,
field.controlStroke
] : [])
].filter((v) => v).length;
}
Expand Down Expand Up @@ -229,6 +231,22 @@
Control {{type.type}} width
</label>
</div>

<div v-if="type.type == 'line'" class="form-check">
<input
:id="`${id}-control-stroke`"
class="form-check-input"
type="checkbox"
v-model="fieldValue.controlStroke"
:disabled="!resolvedCanControl.includes('stroke')"
/>
<label
class="form-check-label"
:for="`${id}-control-stroke`"
>
Control {{type.type}} stroke
</label>
</div>
</div>
</div>
<table v-if="fieldValue.type != 'checkbox' || controlNumber > 0" class="table table-striped table-hover">
Expand All @@ -241,6 +259,7 @@
<th v-if="fieldValue.controlSymbol">Icon</th>
<th v-if="fieldValue.controlShape">Shape</th>
<th v-if="fieldValue.controlWidth">Width</th>
<th v-if="fieldValue.controlStroke">Stroke</th>
<th v-if="fieldValue.type != 'checkbox'"></th>
<th v-if="fieldValue.type != 'checkbox'" class="move"></th>
</tr>
Expand Down Expand Up @@ -305,6 +324,12 @@
class="fm-custom-range-with-label"
></WidthPicker>
</td>
<td v-if="fieldValue.controlStroke" class="field">
<StrokePicker
:modelValue="option.stroke ?? type.defaultStroke"
@update:modelValue="option.stroke = $event"
></StrokePicker>
</td>
<td v-if="fieldValue.type != 'checkbox'" class="td-buttons">
<button type="button" class="btn btn-secondary" @click="deleteOption(option)"><Icon icon="minus" alt="Remove"></Icon></button>
</td>
Expand Down
14 changes: 2 additions & 12 deletions frontend/src/lib/components/legend/legend-content.vue
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@
async function makeSymbol(typeInfo: LegendType, item: LegendItem, height = 15): Promise<string> {
if(typeInfo.type == "line")
return createLinePlaceholderHtml(item.colour || "rainbow", item.width || 5, 50);
return createLinePlaceholderHtml(item.colour || "rainbow", item.width || 5, 50, item.stroke ?? "");
else if (item.colour || item.shape != null)
return await getMarkerHtml(item.colour || typeInfo.fixedColour || "rainbow", height, item.symbol ?? typeInfo.fixedSymbol, item.shape ?? typeInfo.fixedShape);
return await getMarkerHtml(item.colour || "rainbow", height, item.symbol, item.shape);
else
return await getSymbolHtml("#000000", height, item.symbol);
}
Expand Down Expand Up @@ -218,14 +218,4 @@
}
}
}
.fm-legend-symbol {
&.fm-line > svg {
border-radius: 1000px;
}
&.fm-line.bright > svg {
box-shadow: 0 0 2px #000;
}
}
</style>
Loading

0 comments on commit df78811

Please sign in to comment.