Skip to content

Commit

Permalink
Merge pull request #530 from spencerwahl/timeslider-enhance
Browse files Browse the repository at this point in the history
Add timeslider append mode (#530)
  • Loading branch information
spencerwahl authored Jan 10, 2025
2 parents 5a0c643 + 504df69 commit 21c1c3a
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 9 deletions.
17 changes: 17 additions & 0 deletions StoryRampSchema.json
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,23 @@
"description": "A layer ID"
}
},
"animation": {
"type": "object",
"description": "Configuration for the timeslider animation/play function",
"properties": {
"playMode": {
"type": "string",
"description": "The mode to determine behaviour when the play button is used. By default it loops through the values one at a time.",
"default": "distinct",
"enum": ["distinct", "append"]
},
"interval": {
"type": "number",
"description": "The interval between steps in the animation in ms. 1400 is default.",
"default": "1400"
}
}
},
"sliderConfig": {
"type": "object",
"description": "A noUiSlider config object."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,10 @@
"timeSlider": {
"range": [2010, 2019],
"start": [2010, 2010],
"animation": {
"playMode": "append",
"interval": 500
},
"attribute": "Reporting_Year___Année"
},
"type": "map"
Expand Down
31 changes: 22 additions & 9 deletions src/components/panels/helpers/time-slider/time-slider.vue
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
<script setup lang="ts">
import type { PropType } from 'vue';
import { onMounted, ref } from 'vue';
import type { TimeSliderConfig } from '@storylines/definitions';
import { TimeSliderConfig, TimeSliderPlayMode } from '@storylines/definitions';
import noUiSlider, { type API, PipsMode } from 'nouislider';
const props = defineProps({
Expand Down Expand Up @@ -156,25 +156,38 @@ onMounted(() => {
/**
* Begins looping through the values on the time slider
*/
const startLoop = () => {
const sliderValues = slider.value!.get() as string | string[];
const startLoop = () => {
const sliderValues = slider.value!.get(true) as number | number[];
if (Array.isArray(sliderValues)) {
slider.value!.set(sliderValues.map(() => sliderValues[0]));
}
// delay happens before first call
intervalID.value = window.setInterval(moveHandleRight, 1400);
intervalID.value = window.setInterval(moveHandle, props.config.animation?.interval || 1400);
};
/**
* Moves handle(s) one to the right of the first (leftmost) handle. Loops if the handles are at the end.
* Moves handle(s) according to the play mode specified in the config. Default behaviour is to move all handles to the right one position.
*/
const moveHandleRight = () => {
const moveHandle = () => {
const sliderValues = slider.value!.get(true) as number | number[];
let newValues;
if (Array.isArray(sliderValues)) {
newValues = sliderValues.map(() => {
return sliderValues[0] === props.config.range[1] ? props.config.range[0] : sliderValues[0] + 1;
});
const nextMove = slider.value.steps()[sliderValues.length - 1][1]
switch (props.config.animation?.playMode) {
case TimeSliderPlayMode.Append:
// move only rightmost handle to the right
newValues = sliderValues.with(
sliderValues.length - 1,
nextMove ? sliderValues[sliderValues.length - 1] + nextMove : props.config.range[0]);
break;
case TimeSliderPlayMode.Distinct:
default:
// move all handles one position to the right
newValues = sliderValues.map(() => {
return nextMove ? sliderValues[sliderValues.length - 1] + nextMove : props.config.range[0];
});
break;
}
} else {
newValues = [sliderValues === props.config.range[1] ? props.config.range[0] : sliderValues + 1];
}
Expand Down
9 changes: 9 additions & 0 deletions src/definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,9 +216,18 @@ export interface TimeSliderConfig {
start: number[];
attribute: string;
layers?: string[];
animation: {
playMode?: TimeSliderPlayMode;
interval?: number;
};
sliderConfig?: nouiOptions;
}

export enum TimeSliderPlayMode {
Append = 'append',
Distinct = 'distinct'
}

export interface DynamicPanel extends BasePanel {
type: PanelType.Dynamic;
title: string;
Expand Down

0 comments on commit 21c1c3a

Please sign in to comment.