Skip to content

Commit a6d7a27

Browse files
authored
Merge pull request #34 from laurens94/v3
V3
2 parents 6888601 + 1c61422 commit a6d7a27

File tree

11 files changed

+242
-63
lines changed

11 files changed

+242
-63
lines changed

docs/.vitepress/config.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ export default defineConfig({
3636
items: [
3737
{ text: 'Props', link: '/reference/props' },
3838
{ text: 'Events', link: '/reference/events' },
39+
{ text: 'Methods', link: '/reference/methods' },
3940
{ text: 'Slots', link: '/reference/slots' },
4041
{ text: 'Types', link: '/reference/types', items: [
4142
{ text: 'TimelineGroup', link: '/reference/types#timelinegroup' },
@@ -56,6 +57,7 @@ export default defineConfig({
5657
{ text: 'Custom Charts or Canvas Rendering', link: '/examples/custom-charts-or-canvas-rendering' },
5758
{ text: 'Synced timelines', link: '/examples/synced-timelines' },
5859
{ text: 'Tooltips', link: '/examples/tooltips' },
60+
{ text: 'Set viewport', link: '/examples/set-viewport' },
5961
]
6062
}
6163
],

docs/examples/hover-position.vue

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
<template>
2626
<Timeline
2727
class="timeline"
28-
:items="items"
2928
:groups="groups"
3029
:viewportMin="1703112200000"
3130
:viewportMax="1714566600000"

docs/examples/set-viewport.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<script setup>
2+
import Example from './set-viewport.vue'
3+
</script>
4+
5+
# Set viewport example
6+
7+
<Example/>
8+
9+
## Code
10+
11+
<<< ./set-viewport.vue{vue}

docs/examples/set-viewport.vue

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<script setup lang="ts">
2+
import { computed, ref } from 'vue';
3+
4+
const timeline = ref(null);
5+
6+
const items = [
7+
{ group: '1', type: 'range', cssVariables: { '--item-background': 'var(--color-2)' }, start: 100000, end: 450000 },
8+
{ group: '2', type: 'range', cssVariables: { '--item-background': 'var(--color-4)' }, start: 450000, end: 600000 },
9+
{ group: '3', type: 'range', start: 600000, end: 800000 },
10+
];
11+
12+
const initialViewportRange = ref({ start: 400000, end: 700000 });
13+
const viewport = ref({ start: 400000, end: 700000 });
14+
const maxRange = ref({ start: 0, end: 800000 });
15+
16+
const viewportSize = computed(() => viewport.value.end - viewport.value.start);
17+
18+
</script>
19+
20+
<template>
21+
<Timeline
22+
ref="timeline"
23+
:items="items"
24+
:groups="[{id: '1'}, {id: '2'}, {id: '3'}]"
25+
:viewportMin="maxRange.start"
26+
:viewportMax="maxRange.end"
27+
:initialViewportStart="initialViewportRange.start"
28+
:initialViewportEnd="initialViewportRange.end"
29+
@changeViewport="viewport = $event"
30+
/>
31+
32+
<div class="controls">
33+
<button @click="viewport.start > maxRange.start && timeline.setViewport(viewport.start - viewportSize * 0.2, viewport.end - viewportSize * 0.2)">
34+
Move left
35+
</button>
36+
<button @click="viewport.end < maxRange.end && timeline.setViewport(viewport.start + viewportSize * 0.2, viewport.end + viewportSize * 0.2)">
37+
Move right
38+
</button>
39+
<button @click="timeline.setViewport(viewport.start - viewportSize * 0.2, viewport.end + viewportSize * 0.2)">
40+
Zoom out
41+
</button>
42+
<button @click="timeline.setViewport(viewport.start + viewportSize * 0.2, viewport.end - viewportSize * 0.2)">
43+
Zoom in
44+
</button>
45+
<button @click="timeline.setViewport(initialViewportRange.start, initialViewportRange.end)">
46+
Reset viewport
47+
</button>
48+
<button @click="timeline.setViewport(maxRange.start, maxRange.end)">
49+
Set viewport to max range
50+
</button>
51+
</div>
52+
</template>
53+
54+
<style lang="scss" scoped>
55+
.controls {
56+
display: flex;
57+
gap: .5rem;
58+
flex-wrap: wrap;
59+
}
60+
61+
button {
62+
border: 1px solid color-mix(in srgb, currentcolor, transparent 80%);
63+
border-radius: 4px;
64+
cursor: pointer;
65+
padding: 0.1rem 0.4rem;
66+
67+
&:hover {
68+
background-color: color-mix(in srgb, currentcolor, transparent 95%);
69+
}
70+
}
71+
</style>

docs/examples/synced-timelines.vue

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script setup lang="ts">
2-
import { ref } from 'vue';
2+
import { ref, watch } from 'vue';
33
44
const timeline = ref(null);
55
@@ -43,6 +43,10 @@
4343
}
4444
}
4545
46+
watch(viewport, (val) => {
47+
timeline.value?.setViewport(val.start, val.end);
48+
}, { deep: true });
49+
4650
window.addEventListener('pointerup', () => {
4751
isDraggingMapViewport = false;
4852
}, { capture: true });

docs/examples/tooltips.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
// ensure tippy is loaded (due to import within vitepress)
1010
setTimeout(() => resetTooltips(), 100);
1111
return;
12-
};
12+
}
1313
1414
tippyInstances.forEach((instance) => instance.destroy());
1515
tippyInstances = [];

docs/reference/methods.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
outline: deep
3+
---
4+
5+
# Methods
6+
7+
| Method | Arguments | Description |
8+
| --- | --- | --- |
9+
| `setViewport` | `{ start?: number, end?: number }` | Set the visible range of the timeline. See [setViewport example](/examples/set-viewport.html). |
10+
| `onWheel` | `WheelEvent` | Trigger a wheel event on the timeline, useful when [syncing multiple timelines](/examples/synced-timelines.html). |

docs/reference/props.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ outline: deep
99
| `groups` | [TimelineGroup[]](/reference/types#timelinegroup) | `[]` | Define (rows)
1010
| `items` | [TimelineItem[]](/reference/types#timelineitem) | `[]` | Items to display |
1111
| `markers` | [TimelineMarker[]](/reference/types#timelinemarker) | `[]` | Markers to display |
12-
| `viewportMin` | `number` | `undefined` | Minimum timestamp of the viewport (prevents scrolling to before this point) |
13-
| `viewportMax` | `number` | `undefined` | Maximum timestamp of the viewport (prevents scrolling past this point) |
14-
| `minViewportDuration` | `number` | `60000` (1 min) | Minimum duration of the viewport in ms (limits zooming in) |
12+
| `viewportMin` | `number` | `undefined` | Minimum timestamp (whole number) of the viewport (prevents scrolling to before this point) |
13+
| `viewportMax` | `number` | `undefined` | Maximum timestamp (whole number) of the viewport (prevents scrolling past this point) |
14+
| `minViewportDuration` | `number` | `1000` (1 second) | Minimum duration of the viewport in ms (limits zooming in) |
1515
| `maxViewportDuration` | `number` | `undefined` | Maximum duration of the viewport in ms (limits zooming out) |
16-
| `initialViewportStart` | `number` | `undefined` | Initial start timestamp of the viewport (must be greater than or equal to viewportMin) |
17-
| `initialViewportEnd` | `number` | `undefined` | Initial end timestamp of the viewport (must be smaller than or equal to viewportMax) |
16+
| `initialViewportStart` | `number` | `undefined` | Initial start timestamp of the viewport |
17+
| `initialViewportEnd` | `number` | `undefined` | Initial end timestamp of the viewport |
1818
| `renderTimestampLabel` | `function(timestamp: number, scale: { unit: string, step: number})` | `undefined` | Custom function to render timestamp labels |
1919
| `fixedLabels` | `boolean` | `false` | Whether to display group labels on top of the timeline |
2020
| `minTimestampWidth` | `number` | `100` | Minimum width a timestamp label should have in px (determines how many timestamps should be displayed) |

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "vue-timeline-chart",
3-
"version": "2.12.0",
3+
"version": "3.0.0",
44
"description": "Vue3 Timeline Chart component",
55
"author": "Laurens Bruijn",
66
"license": "MIT",

sandbox/App.vue

Lines changed: 75 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
<template>
22
<div>
33
<Timeline
4+
ref="timeline"
45
class="timeline"
56
:groups="groups"
67
:items="items"
78
:markers="markers"
8-
:viewportMin="minDate"
9-
:viewportMax="maxDate"
10-
:initialViewportStart="1691089357146"
11-
:initialViewportEnd="1691101020000"
9+
:viewportMin="maxRange[0]"
10+
:viewportMax="maxRange[1]"
11+
:initialViewportStart="initialViewportRange[0]"
12+
:initialViewportEnd="initialViewportRange[1]"
13+
:minViewportDuration="minViewportDuration"
14+
:maxViewportDuration="maxViewportDuration"
1215
:weekStartsOn="0"
1316
@mousemoveTimeline="onMousemoveTimeline"
1417
@mouseleaveTimeline="onMouseleaveTimeline"
@@ -23,22 +26,72 @@
2326
<template #item="{item}">
2427
<div :title="'title' in item ? item.title : undefined" style="inset: 0; position: absolute;"></div>
2528
</template>
26-
<template #marker="{item}">
27-
<div class="marker-content">
28-
{{ item }}
29-
</div>
30-
</template>
3129
</Timeline>
3230
</div>
33-
<details class="debug" open>
31+
<details open>
32+
<summary>
33+
Controls
34+
</summary>
35+
<div class="flex">
36+
<button @click="timeline.setViewport(debug.viewport.start - viewportSize * 0.2, debug.viewport.end - viewportSize * 0.2)">
37+
Move left
38+
</button>
39+
<button @click="timeline.setViewport(debug.viewport.start + viewportSize * 0.2, debug.viewport.end + viewportSize * 0.2)">
40+
Move right
41+
</button>
42+
<button @click="timeline.setViewport(debug.viewport.start - viewportSize * 0.2, debug.viewport.end + viewportSize * 0.2)">
43+
Zoom out
44+
</button>
45+
<button @click="timeline.setViewport(debug.viewport.start + viewportSize * 0.2, debug.viewport.end - viewportSize * 0.2)">
46+
Zoom in
47+
</button>
48+
<button @click="timeline.setViewport(initialViewportRange[0], initialViewportRange[1])">
49+
Reset viewport
50+
</button>
51+
<button @click="timeline.setViewport(maxRange[0], maxRange[1])">
52+
Set viewport to max range
53+
</button>
54+
</div>
55+
</details>
56+
57+
<details open>
58+
<summary>
59+
Props
60+
</summary>
61+
<div class="flex">
62+
<label>initialViewportStart</label>
63+
<input v-model="initialViewportRange[0]" type="number"/>
64+
</div>
65+
<div class="flex">
66+
<label>initialViewportEnd</label>
67+
<input v-model="initialViewportRange[1]" type="number"/>
68+
</div>
69+
<div class="flex">
70+
<label>viewportMin</label>
71+
<input v-model="maxRange[0]" type="number"/>
72+
</div>
73+
<div class="flex">
74+
<label>viewportMax</label>
75+
<input v-model="maxRange[1]" type="number"/>
76+
</div>
77+
<div class="flex">
78+
<label>minViewportDuration</label>
79+
<input v-model="minViewportDuration" type="number"/>
80+
</div>
81+
<div class="flex">
82+
<label>maxViewportDuration</label>
83+
<input v-model="maxViewportDuration" type="number"/>
84+
</div>
85+
</details>
86+
<details open>
3487
<summary>
3588
Debug
3689
</summary>
3790

3891
<div
3992
v-for="debugItem in Object.keys(debug)"
4093
:key="debugItem"
41-
class="pair"
94+
class="flex"
4295
>
4396
<label>{{ debugItem }}</label>
4497
<div class="data">
@@ -63,15 +116,21 @@
63116
64117
const debug = reactive({
65118
scale: undefined as Scale | undefined,
66-
firedEvents: [] as string[],
67119
viewport: {
68120
start: 0,
69121
end: 0,
70122
},
123+
firedEvents: [] as string[],
71124
});
72125
73-
const minDate = -500000000000000;
74-
const maxDate = 100000000000000;
126+
const viewportSize = computed(() => debug.viewport.end - debug.viewport.start);
127+
128+
const timeline = ref();
129+
130+
const maxRange = ref([-500000000000000, 100000000000000]);
131+
const initialViewportRange = ref([1691089357146, 1691101020000]);
132+
const minViewportDuration = ref(10000);
133+
const maxViewportDuration = ref(10000000000000);
75134
76135
const groups = computed((): TimelineGroup[] => {
77136
return [
@@ -256,15 +315,15 @@
256315
}
257316
}
258317
259-
.debug {
318+
details {
260319
background-color: rgba(0, 0, 0, 50%);
261320
color: white;
262321
padding: 0.5rem;
263322
font-family: monospace;
264323
border-radius: 0.5rem;
265324
margin-top: 2rem;
266325
267-
.pair {
326+
.flex {
268327
display: flex;
269328
gap: 2rem;
270329
margin: 1rem;

0 commit comments

Comments
 (0)