@protomaze/time 1.4.3 → 1.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/README.md +29 -1
  2. package/TimeSliderDemo.d.ts +12 -1
  3. package/TimeSliderDemo.js +1 -1
  4. package/common/TimeTools.d.ts +17 -5
  5. package/common/TimeTools.js +1 -1
  6. package/data/CompositeTimeSliderModel.js +1 -1
  7. package/data/TimeSliderBush.js +1 -1
  8. package/data/TimeSliderIntervalsModel.js +1 -1
  9. package/data/TimeSliderLanesModel.js +1 -1
  10. package/data/TimeSliderModel.js +1 -1
  11. package/data/TimeSliderPointsModel.js +1 -1
  12. package/data/TimeSliderRange.d.ts +8 -0
  13. package/data/TimeSliderRange.js +1 -1
  14. package/data/histogram/TimeSliderDynamicHistogram.js +1 -1
  15. package/data/histogram/TimeSliderFixedHistogram.js +1 -1
  16. package/data/histogram/TimeSliderHistogram.js +1 -1
  17. package/data/histogram/TimeSliderSplittingFixedHistogram.js +1 -1
  18. package/demo/Common.d.ts +5 -1
  19. package/demo/Common.js +1 -1
  20. package/demo/Metrics.d.ts +2 -2
  21. package/demo/Metrics.js +1 -1
  22. package/demo/Nasdaq.d.ts +5 -2
  23. package/demo/Nasdaq.js +1 -1
  24. package/demo/Quakes.d.ts +6 -3
  25. package/demo/Quakes.js +1 -1
  26. package/demo/QuakesFilters.d.ts +3 -1
  27. package/demo/QuakesFilters.js +1 -1
  28. package/demo/Random.d.ts +45 -35
  29. package/demo/Random.js +1 -1
  30. package/demo/Test.d.ts +5 -2
  31. package/demo/Test.js +1 -1
  32. package/demo/Wars.js +1 -1
  33. package/engine/TimeSlider.d.ts +131 -5
  34. package/engine/TimeSlider.js +1 -1
  35. package/engine/TimeSliderEngine.js +1 -1
  36. package/index.d.ts +62 -1
  37. package/index.js +1 -1
  38. package/layer/TimeSliderHistogramLayer.js +1 -1
  39. package/layer/TimeSliderHistogramLayerOld.js +1 -1
  40. package/layer/TimeSliderIntervalsLayer.js +1 -1
  41. package/layer/TimeSliderLayer.js +1 -1
  42. package/layer/TimeSliderLayerLoader.d.ts +2 -0
  43. package/layer/TimeSliderPointsLayer.js +1 -1
  44. package/package.json +60 -58
  45. package/react/DateLabelWithPicker.js +1 -1
  46. package/react/DateRangeLabelWithPicker.js +1 -1
  47. package/react/FullscreenButton.js +1 -1
  48. package/react/ReactTimeSlider.js +1 -1
  49. package/react/TimeLabelWithPicker.js +1 -1
  50. package/style/TimeSliderIntervalsStyle.d.ts +4 -0
  51. package/three/Three3DTimeSliderEngine.js +1 -1
  52. package/three/ThreeTimeSlider.js +1 -1
  53. package/three/ThreeTimeSliderEngine.js +1 -1
  54. package/three/layer/GrowingBufferGeometry.js +1 -1
  55. package/three/layer/GrowingInstanceMatrix.js +1 -1
  56. package/three/layer/Three3DIntervalsTimeLayerLoader.d.ts +2 -2
  57. package/three/layer/Three3DIntervalsTimeLayerLoader.js +1 -1
  58. package/three/layer/Three3DPointsTimeLayerLoader.d.ts +1 -2
  59. package/three/layer/Three3DPointsTimeLayerLoader.js +1 -1
  60. package/three/layer/ThreeIntervalsTimeLayerLoader.d.ts +2 -2
  61. package/three/layer/ThreeIntervalsTimeLayerLoader.js +1 -1
  62. package/three/layer/ThreePointsTimeLayerLoader.d.ts +1 -2
  63. package/three/layer/ThreePointsTimeLayerLoader.js +1 -1
  64. package/three/layer/ThreeTimeLayerLoader.js +1 -1
  65. package/three/react/ReactThreeTimeSlider.js +1 -1
  66. package/ticks/TimeTicksBar.d.ts +14 -1
  67. package/ticks/TimeTicksBar.js +1 -1
package/demo/Random.js CHANGED
@@ -1 +1 @@
1
- import{v4 as t}from"uuid";import{TimeSliderLanesModel as e}from"../data/TimeSliderLanesModel";import{TimeSliderPointsModel as o}from"../data/TimeSliderPointsModel";import{ONE_SECOND as n}from"../ticks/TimeSliderConstants";import{createDemoHistogramLayer as a,createDemoIntervalsLayer as r,createDemoPointsLayer as i}from"./Common";const d=function(){const e=new o;return e.name="Measurements",function(e){const n=e||new o;setInterval(()=>{const e=Date.now()+10*Math.random(),o=5+90*generateRealisticY(.02*e,.1,.8);n.add({id:t(),t:e,v:o,name:"M#"+n.data.length+" ("+Math.round(o)+"%)"})},10)}(e),e}(),{model:c,styleMap:m}=function(){const o=new e;o.name="Tracks";const a=function(e){const o=e,a=new Set,r=new Map,i=()=>{const e=getDistinctColors()[Math.floor(20*Math.random())],i=getDistinctColors()[Math.floor(20*Math.random())],d=t(),c={id:d,name:getRandomFunkyName(),t:[Date.now(),Date.now()]};return r.set(d,{fill:{color:e},border:{color:i}}),a.add(c),o.add(c),setTimeout(()=>{o.update(c,{t:[c.t[0],Date.now()]}),a.delete(c)},n+7*Math.random()*n),c};i();const d=7,c=()=>{a.size<d&&Math.random()<1*Math.random()*(1-a.size/d)&&i(),a.forEach(t=>{o.update(t,{t:[t.t[0],Date.now()]})}),requestAnimationFrame(c)};return c(),r}(o);return{model:o,styleMap:a}}();export const RANDOM_SINGLE_LAYERS=[a([d,c],{min:.9,style:{weighted:!0}}),i(d,{min:.5,max:.9,style:{area:{color:"#df0",height:.2,opacity:1}}}),r(c,{max:.5})];export const RANDOM_MULTI_LAYERS=[[i(d,{min:.25,max:1,style:{line:void 0,area:void 0}}),a([d],{min:0,max:.25,style:{weighted:!0,mode:{fixed:{duration:100}},inverted:!1}})],[i(d,{min:.5,max:1,style:{point:void 0,area:{color:"#df0",height:.2,opacity:1}}}),r(c,{min:0,max:.5,style:{border:{width:2,color:"#df0"}}})],[r(c,{max:.8,style:{border:{centered:!1,width:4}},styler:t=>m.get(t.id)}),a([c],{min:.9})]];export function getDistinctColors(){return["#e6194B","#3cb44b","#ffe119","#4363d8","#f58231","#911eb4","#42d4f4","#bfef45","#f032e6","#808000","#fabed4","#469990","#dcbeff","#9A6324","#fffac8","#800000","#aaffc3","#ffd8b1","#000075","#a9a9a9"]}export function invertColor(t,e){const[o,n,a]=parseColor(t),r=void 0!==e?Math.max(0,Math.min(1,e)):1,i=t=>255*t;return`rgb(${i(1-o)}, ${i(1-n)}, ${i(1-a)}, ${r})`}export function parseColor(t){const e=document.createElement("canvas").getContext("2d");e.fillStyle=t,e.fillRect(0,0,1,1);const[o,n,a]=e.getImageData(0,0,1,1).data;return[o/255,n/255,a/255]}export function getRandomFunkyName(){const t=t=>t[Math.floor(Math.random()*t.length)];return`${t(["Funky","Groovy","Zany","Wacky","Spicy","Nifty","Bouncy","Chill","Snazzy","Sassy","Loopy","Trippy","Nerdy","Cranky","Fluffy","Quirky"])}${t(["Banana","Tofu","Octopus","Falcon","Pineapple","Robot","Llama","Pizza","Koala","Unicorn","Muffin","Cactus","Taco","Yeti","Squirrel","Donut"])}`}const s=256,l=new Array(2*s);export function generateRealisticY(t,e=.1,o=1){const n=function(t){const e=Math.floor(t),o=t-e,n=l[e&s-1],a=l[e+1&s-1],r=.5*(1-Math.cos(o*Math.PI));return n*(1-r)+a*r}(t*e),a=.5+(n-.5)*o;return Math.max(0,Math.min(1,a))}(()=>{for(let t=0;t<s;t++)l[t]=l[t+s]=Math.random()})();
1
+ import{v4 as t}from"uuid";import{TimeSliderLanesModel as e}from"../data/TimeSliderLanesModel.js";import{TimeSliderPointsModel as o}from"../data/TimeSliderPointsModel.js";import{ONE_SECOND as n}from"../ticks/TimeSliderConstants.js";import{createDemoHistogramLayer as a,createDemoIntervalsLayer as r,createDemoPointsLayer as i}from"./Common.js";export function createRandomDemo(){const s=[],c=function(e){const n=new o;return n.name="Measurements",e.push(function(e){const o=setInterval(()=>{const o=Date.now()+10*Math.random(),n=5+90*generateRealisticY(.02*o,.1,.8);e.add({id:t(),t:o,v:n,name:"M#"+e.data.length+" ("+Math.round(n)+"%)"})},10);return()=>clearInterval(o)}(n)),n}(s),{model:l,styleMap:d}=function(o){const a=new e;a.name="Tracks";const{styleMap:r,stop:i}=function(e){const o=e,a=new Set,r=new Map,i=()=>{const e=getDistinctColors()[Math.floor(20*Math.random())],i=getDistinctColors()[Math.floor(20*Math.random())],s=t(),c={id:s,name:getRandomFunkyName(),t:[Date.now(),Date.now()]};return r.set(s,{fill:{color:e},border:{color:i}}),a.add(c),o.add(c),setTimeout(()=>{o.update(c,{t:[c.t[0],Date.now()]}),a.delete(c)},n+7*Math.random()*n),c};i();const s=7;let c=!0;const l=()=>{c&&(a.size<s&&Math.random()<1*Math.random()*(1-a.size/s)&&i(),a.forEach(t=>{o.update(t,{t:[t.t[0],Date.now()]})}),requestAnimationFrame(l))};return l(),{styleMap:r,stop:()=>c=!1}}(a);return o.push(i),{model:a,styleMap:r}}(s);return{single:[a([c,l],{min:.9,style:{weighted:!0}}),i(c,{min:.5,max:.9,style:{area:{color:"#df0",height:.2,opacity:1}}}),r(l,{max:.5})],multiple:[[i(c,{min:.25,max:1,style:{line:void 0,area:void 0}}),a([c],{min:0,max:.25,style:{weighted:!0,mode:{fixed:{duration:100}},inverted:!1}})],[i(c,{min:.5,max:1,style:{point:void 0,area:{color:"#df0",height:.2,opacity:1}}}),r(l,{min:0,max:.5,style:{border:{width:2,color:"#df0"}}})],[r(l,{max:.8,style:{border:{centered:!1,width:4}},styler:t=>d.get(t.id)}),a([l],{min:.9})]],stop:()=>s.forEach(t=>t())}}export function getDistinctColors(){return["#e6194B","#3cb44b","#ffe119","#4363d8","#f58231","#911eb4","#42d4f4","#bfef45","#f032e6","#808000","#fabed4","#469990","#dcbeff","#9A6324","#fffac8","#800000","#aaffc3","#ffd8b1","#000075","#a9a9a9"]}export function invertColor(t,e){const[o,n,a]=parseColor(t),r=void 0!==e?Math.max(0,Math.min(1,e)):1,i=t=>255*t;return`rgb(${i(1-o)}, ${i(1-n)}, ${i(1-a)}, ${r})`}export function parseColor(t){const e=document.createElement("canvas").getContext("2d");e.fillStyle=t,e.fillRect(0,0,1,1);const[o,n,a]=e.getImageData(0,0,1,1).data;return[o/255,n/255,a/255]}export function getRandomFunkyName(){const t=t=>t[Math.floor(Math.random()*t.length)];return`${t(["Funky","Groovy","Zany","Wacky","Spicy","Nifty","Bouncy","Chill","Snazzy","Sassy","Loopy","Trippy","Nerdy","Cranky","Fluffy","Quirky"])}${t(["Banana","Tofu","Octopus","Falcon","Pineapple","Robot","Llama","Pizza","Koala","Unicorn","Muffin","Cactus","Taco","Yeti","Squirrel","Donut"])}`}const s=256,c=new Array(2*s);export function generateRealisticY(t,e=.1,o=1){const n=function(t){const e=Math.floor(t),o=t-e,n=c[e&s-1],a=c[e+1&s-1],r=.5*(1-Math.cos(o*Math.PI));return n*(1-r)+a*r}(t*e),a=.5+(n-.5)*o;return Math.max(0,Math.min(1,a))}(()=>{for(let t=0;t<s;t++)c[t]=c[t+s]=Math.random()})();
package/demo/Test.d.ts CHANGED
@@ -1,5 +1,8 @@
1
1
  import { TimeSliderElement } from "../data/TimeSliderElement";
2
2
  import { TimeSliderModel } from "../data/TimeSliderModel";
3
3
  import { TimeSliderHistogramLayerOld } from "../layer/TimeSliderHistogramLayerOld";
4
- export declare const testHistogramLayer: TimeSliderHistogramLayerOld<TimeSliderModel<TimeSliderElement>>;
5
- export declare const TEST_LAYERS: TimeSliderHistogramLayerOld<TimeSliderModel<TimeSliderElement>>[];
4
+ /** 10 000 seeded points in a histogram, for testing the histogram */
5
+ export declare function createTestDemo(): {
6
+ single: TimeSliderHistogramLayerOld<TimeSliderModel<TimeSliderElement>>[];
7
+ multiple: TimeSliderHistogramLayerOld<TimeSliderModel<TimeSliderElement>>[][];
8
+ };
package/demo/Test.js CHANGED
@@ -1 +1 @@
1
- import{v4 as t}from"uuid";import{TimeSliderPointsModel as e}from"../data/TimeSliderPointsModel";import{MAGNITUDE_COLORS as r}from"../style/TimeSliderColors";import{ONE_YEAR as i}from"../ticks/TimeSliderConstants";import{TimeSliderHistogramLayerOld as o}from"../layer/TimeSliderHistogramLayerOld";const s=function(){const r=(s=42,()=>{let t=s+=1831565813;return t=Math.imul(t^t>>>15,1|t),t^=t+Math.imul(t^t>>>7,61|t),((t^t>>>14)>>>0)/4294967296}),o=new e;var s;o.name="Test";for(let e=0;e<1e4;e++){const e={id:t(),t:Date.now()-r()*i,v:100*r(),attributes:{test:r(),ok:r()}};o.add(e)}return o}(),a=Array.from({length:10},(t,e)=>e.toString()),n=Array.from({length:20},(t,e)=>e.toString());export const testHistogramLayer=function(t){const e=t=>l(10*t.attributes.test,a)+"",i=t=>l(t.v/10,a)+"",s=new o(t,{name:"Histogram",min:0,max:1,style:{loggin:!0,fill:{color:"#fff",opacity:.3},border:{color:"#fff",width:4,centered:!1},inverted:!1,mode:{fixedUnit:"month"},classOrder:n},classifier:e,styler:t=>{const e=r[parseInt(t.attributes?.classification||"0")];return{fill:{color:e},border:{color:e}}},labeler:t=>`Test #${parseInt(t.attributes?.classification||"0")}`,yAxis:{visible:!0,style:{labels:{position:"left"}}}});let m=!0,d=!1,c=!1;document.addEventListener("keypress",t=>{"t"===t.key&&(m=!1,s.histogram.classifier=i),"g"===t.key&&(m=!0,s.histogram.classifier=e)}),document.addEventListener("keydown",t=>{"y"===t.key&&(c=!0),"h"===t.key&&(d=!0)}),document.addEventListener("keyup",t=>{"y"===t.key&&(c=!1),"h"===t.key&&(d=!1)});let f=0;return setInterval(()=>{(c||d)&&(s.histogram.classifier=m?t=>l(10*t.attributes.test,a)+(t.attributes.ok<f?10:0)+"":t=>l(t.v/10,a)+(t.attributes.ok<f?10:0)+"");let t=0;c&&(t+=.05),d&&(t-=.05),f=Math.max(0,Math.min(1,f+t))},50),s}(s);export const TEST_LAYERS=[testHistogramLayer];function l(t,e){return Math.min(e.length-1,Math.max(0,Math.round(t)))}
1
+ import{v4 as t}from"uuid";import{TimeSliderPointsModel as e}from"../data/TimeSliderPointsModel.js";import{MAGNITUDE_COLORS as r}from"../style/TimeSliderColors.js";import{ONE_YEAR as i}from"../ticks/TimeSliderConstants.js";import{TimeSliderHistogramLayerOld as o}from"../layer/TimeSliderHistogramLayerOld.js";const s=Array.from({length:10},(t,e)=>e.toString()),n=Array.from({length:20},(t,e)=>e.toString());export function createTestDemo(){const l=[function(t){const e=t=>a(10*t.attributes.test,s)+"",i=t=>a(t.v/10,s)+"",l=new o(t,{name:"Histogram",min:0,max:1,style:{loggin:!0,fill:{color:"#fff",opacity:.3},border:{color:"#fff",width:4,centered:!1},inverted:!1,mode:{fixedUnit:"month"},classOrder:n},classifier:e,styler:t=>{const e=r[parseInt(t.attributes?.classification||"0")];return{fill:{color:e},border:{color:e}}},labeler:t=>`Test #${parseInt(t.attributes?.classification||"0")}`,yAxis:{visible:!0,style:{labels:{position:"left"}}}});let m=!0,c=!1,d=!1;document.addEventListener("keypress",t=>{"t"===t.key&&(m=!1,l.histogram.classifier=i),"g"===t.key&&(m=!0,l.histogram.classifier=e)}),document.addEventListener("keydown",t=>{"y"===t.key&&(d=!0),"h"===t.key&&(c=!0)}),document.addEventListener("keyup",t=>{"y"===t.key&&(d=!1),"h"===t.key&&(c=!1)});let f=0;return setInterval(()=>{(d||c)&&(l.histogram.classifier=m?t=>a(10*t.attributes.test,s)+(t.attributes.ok<f?10:0)+"":t=>a(t.v/10,s)+(t.attributes.ok<f?10:0)+"");let t=0;d&&(t+=.05),c&&(t-=.05),f=Math.max(0,Math.min(1,f+t))},50),l}(function(){const r=(s=42,()=>{let t=s+=1831565813;return t=Math.imul(t^t>>>15,1|t),t^=t+Math.imul(t^t>>>7,61|t),((t^t>>>14)>>>0)/4294967296}),o=new e;var s;o.name="Test";for(let e=0;e<1e4;e++){const e={id:t(),t:Date.now()-r()*i,v:100*r(),attributes:{test:r(),ok:r()}};o.add(e)}return o}())];return{single:l,multiple:[l]}}function a(t,e){return Math.min(e.length-1,Math.max(0,Math.round(t)))}
package/demo/Wars.js CHANGED
@@ -1 +1 @@
1
- import{v4 as o}from"uuid";import{getTimeUnitRange as m}from"../common/TimeTools";import{TimeSliderLanesModel as r}from"../data/TimeSliderLanesModel";export const WARS_SINGLE_LAYERS=[];export const WARS_MULTI_LAYERS=[[],[]];
1
+ import{v4 as o}from"uuid";import{getTimeUnitRange as m}from"../common/TimeTools.js";import{TimeSliderLanesModel as r}from"../data/TimeSliderLanesModel.js";export const WARS_SINGLE_LAYERS=[];export const WARS_MULTI_LAYERS=[[],[]];
@@ -1,3 +1,4 @@
1
+ import { TimeUnit } from '../common/TimeTools';
1
2
  import { TimeSliderElement } from "../data/TimeSliderElement";
2
3
  import { TimeSliderRange, TimeSliderTimeRange, TimeSliderTimeRangeWithDuration, TimeSliderValueRange } from "../data/TimeSliderRange";
3
4
  import { TypedEventEmitter } from "../event/TypedEventEmitter";
@@ -8,16 +9,65 @@ import { TimeSliderEngine } from "./TimeSliderEngine";
8
9
  export type TimeSliderHoverOptions = {
9
10
  time?: boolean;
10
11
  date?: boolean;
12
+ /** Set false to disable the built-in tooltip and render your own from the 'hover' event instead. Default true. */
13
+ tooltip?: boolean;
11
14
  };
15
+ export type TimeSliderPickMode = 'element' | 'column';
12
16
  export type TimeSliderSelectionOptions = {
13
17
  highlight?: boolean;
14
18
  label?: boolean;
19
+ /** Dims the time outside the range(s) set via setSelection(). Default true. */
20
+ shading?: boolean;
21
+ /** Dims inside the selected range(s) instead of outside. Default false. */
22
+ invertShading?: boolean;
23
+ /**
24
+ * 'element' (default) picks elements near the cursor's time AND height, the
25
+ * existing behavior. 'column' picks every visible layer's element(s) whose
26
+ * time interval contains the cursor time, regardless of cursor height —
27
+ * for picking thin bars/bins by clicking anywhere in their column. Applies
28
+ * to both hover and click. See also setPickMode().
29
+ */
30
+ pick?: TimeSliderPickMode;
31
+ /** Style of the column highlight band drawn on hover when pick is 'column'. */
32
+ columnBand?: {
33
+ color?: string;
34
+ opacity?: number;
35
+ };
15
36
  };
16
37
  export type TimeSliderSelection = {
17
38
  layer: TimeSliderLayer;
18
39
  elements: TimeSliderElement[];
19
40
  };
20
- export type TimeSliderSelectRangeMode = 'zoom' | 'select';
41
+ export type TimeSliderHoverInfo = {
42
+ elements: {
43
+ layer: TimeSliderLayer;
44
+ elements: TimeSliderElement[];
45
+ }[];
46
+ t: number;
47
+ clientX: number;
48
+ clientY: number;
49
+ };
50
+ /** Fired by clicking a tick label on the ticks bar (e.g. clicking "2023" while bins are months). unit is this library's best guess at the tick's granularity, via getMatchingTimeUnit — undefined if the range doesn't cleanly match one. */
51
+ export type TimeSliderTickClickInfo = {
52
+ startTime: number;
53
+ endTime: number;
54
+ unit?: TimeUnit;
55
+ };
56
+ /** Returns per-tick label overrides, e.g. to fade ticks outside a selection like a chart legend. */
57
+ export type TimeSliderTickLabelStyler = (range: {
58
+ startTime: number;
59
+ endTime: number;
60
+ }) => {
61
+ color?: string;
62
+ opacity?: number;
63
+ } | undefined;
64
+ /** A programmatic, draggable time-range selection (distinct from the click-driven element `select`/`'select'` event). startTime/endTime may be -Infinity/Infinity for an open-ended "before X" / "after X" range. */
65
+ export type TimeSliderSelectionRange = {
66
+ startTime: number;
67
+ endTime: number;
68
+ };
69
+ export type TimeSliderSelectionChangePhase = 'start' | 'drag' | 'end';
70
+ export type TimeSliderSelectRangeMode = 'zoom' | 'select' | 'createSelection';
21
71
  export interface TimeSliderOptions {
22
72
  showCurrent?: boolean;
23
73
  showTicks?: boolean;
@@ -27,6 +77,16 @@ export interface TimeSliderOptions {
27
77
  playSpeed?: number | 'auto';
28
78
  hover?: TimeSliderHoverOptions;
29
79
  selection?: TimeSliderSelectionOptions;
80
+ /** BCP-47 tag (e.g. 'de', 'en-GB'). Defaults to navigator.language. See also setLocale(). */
81
+ locale?: string;
82
+ /** 'calendarWeek' labels week ticks as ISO 8601 calendar weeks (e.g. "KW12") instead of a date range. Defaults to 'default' (unchanged behavior). */
83
+ weekLabel?: 'default' | 'calendarWeek';
84
+ /** Overrides the localized calendar-week prefix (e.g. "KW" for German). Only used when weekLabel is 'calendarWeek'. */
85
+ weekLabelPrefix?: string;
86
+ /** Per-tick label color/opacity override, e.g. to fade ticks outside a selection. */
87
+ tickLabelStyler?: TimeSliderTickLabelStyler;
88
+ /** Outer bounds of the visible time range: zooming out never shows more than this and panning stops at its edges. Applied in setTimeRange(), so wheel, pinch, up(), fit() and animations all respect it. Either side may be -Infinity/Infinity. See also setLimits(). */
89
+ limits?: TimeSliderTimeRange;
30
90
  }
31
91
  export declare class TimeSlider extends TypedEventEmitter<{
32
92
  live: boolean;
@@ -40,6 +100,17 @@ export declare class TimeSlider extends TypedEventEmitter<{
40
100
  value: TimeSliderValueRange;
41
101
  select: TimeSliderSelection[];
42
102
  valueRanges: string;
103
+ locale: string;
104
+ selectionchange: {
105
+ ranges: TimeSliderSelectionRange[];
106
+ phase: TimeSliderSelectionChangePhase;
107
+ };
108
+ /** Fires once the engine passed to setEngine() has finished its async init() and layers can actually render. See also engineReady / whenReady(). */
109
+ ready: void;
110
+ /** Fires on every hover position update (and on leave/drag, with null), regardless of whether the built-in tooltip is shown. */
111
+ hover: TimeSliderHoverInfo | null;
112
+ /** Fires when a tick label on the ticks bar is clicked. Also still zooms/fits to that tick's range, same as before this event existed. */
113
+ tickclick: TimeSliderTickClickInfo;
43
114
  }> {
44
115
  valueRanges: Map<string, {
45
116
  min: number;
@@ -50,6 +121,8 @@ export declare class TimeSlider extends TypedEventEmitter<{
50
121
  ticksBar: TimeTicksBar;
51
122
  private loaders;
52
123
  private layerUnloaders;
124
+ private layerListenerStoppers;
125
+ private layerLoaders;
53
126
  pressedKeys: Set<string>;
54
127
  protected container: HTMLElement | null;
55
128
  theme: 'dark' | 'light';
@@ -61,6 +134,7 @@ export declare class TimeSlider extends TypedEventEmitter<{
61
134
  private _showCurrent;
62
135
  showTicks: boolean;
63
136
  playSpeed: number | 'auto';
137
+ private _locale;
64
138
  current: number;
65
139
  range: {
66
140
  time: TimeSliderTimeRange;
@@ -76,6 +150,12 @@ export declare class TimeSlider extends TypedEventEmitter<{
76
150
  private toolTip;
77
151
  private selectedLabel;
78
152
  private selectingRangeElement;
153
+ private selectionOverlayContainer;
154
+ private _selectionRanges;
155
+ private selectionRangeElements;
156
+ private shadingElements;
157
+ private columnBandOverlayContainer;
158
+ private columnBandElements;
79
159
  private stopUpdatingLabel?;
80
160
  hoverOptions: TimeSliderHoverOptions;
81
161
  selectionOptions: TimeSliderSelectionOptions;
@@ -84,9 +164,43 @@ export declare class TimeSlider extends TypedEventEmitter<{
84
164
  selectingRange: boolean;
85
165
  selectingRangeVisible: boolean;
86
166
  whenDoneSelectingRange?: () => void;
87
- getLayers(): TimeSliderLayer<TimeSliderElement, import("../style/TimeSliderStyle").TimeSliderStyle>[];
88
- getVisibleLayers(): TimeSliderLayer<TimeSliderElement, import("../style/TimeSliderStyle").TimeSliderStyle>[];
167
+ private _limits?;
168
+ getLayers(): TimeSliderLayer<TimeSliderElement, import("..").TimeSliderStyle>[];
169
+ getVisibleLayers(): TimeSliderLayer<TimeSliderElement, import("..").TimeSliderStyle>[];
89
170
  constructor(options?: TimeSliderOptions);
171
+ get locale(): string;
172
+ /** Sets the locale for this slider's own rendering (ticks, hover tooltip) and for the TimeTools formatters' module-wide default, so code calling them directly (e.g. a custom labeler) stays in sync too. */
173
+ setLocale(locale: string): void;
174
+ /** Switches week ticks between the default date-range label and ISO calendar-week labels (e.g. "KW12"). */
175
+ setWeekLabel(weekLabel: 'default' | 'calendarWeek', weekLabelPrefix?: string): void;
176
+ /** Overrides per-tick label color/opacity, e.g. to fade ticks outside a selection. Pass undefined to clear. */
177
+ setTickLabelStyler(styler: TimeSliderTickLabelStyler | undefined): void;
178
+ get limits(): TimeSliderTimeRange | undefined;
179
+ /** Sets (or with undefined clears) the outer bounds of the visible time range, see TimeSliderOptions.limits. The current range is clamped right away. */
180
+ setLimits(limits: TimeSliderTimeRange | undefined): void;
181
+ /**
182
+ * Sets the draggable, programmatic selection range(s) — distinct from the
183
+ * click-driven element `select()` / `'select'` event, which keeps working
184
+ * independently. A range's startTime/endTime may be -Infinity/Infinity for
185
+ * an open-ended "before X" / "after X" selection, drawn to the slider edge.
186
+ * Fires 'selectionchange' with phase 'end'.
187
+ */
188
+ setSelection(ranges: TimeSliderSelectionRange[]): void;
189
+ getSelection(): TimeSliderSelectionRange[];
190
+ clearSelection(): void;
191
+ /**
192
+ * Switches how hover/click pick elements: 'element' (default) uses cursor
193
+ * time AND height, 'column' uses cursor time only — every visible layer's
194
+ * element(s) at that time, regardless of height. Also updates the hover
195
+ * column-highlight band immediately.
196
+ */
197
+ setPickMode(pick: TimeSliderPickMode): void;
198
+ private selectionTimeToX;
199
+ private renderSelectionOverlay;
200
+ /** Draws the pick-mode 'column' hover highlight: one band per layer with a hovered element, spanning that layer's own y-range and the hovered element(s)' time extent. No-op unless pick is 'column'. */
201
+ private renderColumnHoverBand;
202
+ private createSelectionRangeElements;
203
+ private wireSelectionDrag;
90
204
  startSelectingRange(whenDone: () => void): void;
91
205
  stopSelectingRange(): void;
92
206
  updateValueRangesQueue: Map<string, {
@@ -103,6 +217,11 @@ export declare class TimeSlider extends TypedEventEmitter<{
103
217
  showingStats: boolean;
104
218
  showStats(showingStats: boolean): void;
105
219
  protected engine?: TimeSliderEngine<any>;
220
+ private _engineReady;
221
+ /** True once the current engine's async init() has resolved and layers can actually render — see also the 'ready' event and whenReady(). */
222
+ get engineReady(): boolean;
223
+ /** Resolves once the engine is ready (immediately, if it already is). Layers added before this point are queued and loaded automatically — see loadLayer(). */
224
+ whenReady(): Promise<void>;
106
225
  setEngine(engine: TimeSliderEngine<any>): Promise<void>;
107
226
  initSliderContainer(): void;
108
227
  get showCurrent(): boolean;
@@ -113,7 +232,7 @@ export declare class TimeSlider extends TypedEventEmitter<{
113
232
  private updatingLabel;
114
233
  private selectedLayerId?;
115
234
  getLabel(element: TimeSliderElement, layer: TimeSliderLayer, t: number, v: number): string | null;
116
- getLayerById(id: string): TimeSliderLayer<TimeSliderElement, import("../style/TimeSliderStyle").TimeSliderStyle> | undefined;
235
+ getLayerById(id: string): TimeSliderLayer<TimeSliderElement, import("..").TimeSliderStyle> | undefined;
117
236
  select(mouse: {
118
237
  x: number;
119
238
  y: number;
@@ -151,11 +270,16 @@ export declare class TimeSlider extends TypedEventEmitter<{
151
270
  x: number;
152
271
  y: number;
153
272
  }, pickSize?: number): {
154
- layer: TimeSliderLayer<TimeSliderElement, import("../style/TimeSliderStyle").TimeSliderStyle>;
273
+ layer: TimeSliderLayer<TimeSliderElement, import("..").TimeSliderStyle>;
155
274
  elements: TimeSliderElement[];
156
275
  t: number;
157
276
  v: number;
158
277
  }[];
278
+ /** Pick mode 'column': ignores cursor height entirely — every visible layer's element(s) whose time interval contains the cursor time. */
279
+ private findColumnElements;
280
+ private hoverCleared;
281
+ /** Clears the column band and emits 'hover' null once per hover-to-no-hover change, not on every time-range update while the mouse is away. */
282
+ private clearHoverEvent;
159
283
  updateHover(mouse?: {
160
284
  x: number;
161
285
  y: number;
@@ -200,6 +324,8 @@ export declare class TimeSlider extends TypedEventEmitter<{
200
324
  private loadLayer;
201
325
  private unloadLayer;
202
326
  addLayer(layer: TimeSliderLayer): void;
327
+ /** layer.min / layer.max changed: reload the layer unless its loader follows the band by itself. Unlike toggling visible, this keeps the element selection. */
328
+ private onLayerBandChange;
203
329
  removeLayer(layer: string | {
204
330
  id: string;
205
331
  }): void;
@@ -1 +1 @@
1
- import{v4 as e}from"uuid";import{Disposables as t}from"../common/Disposables";import{animateRangeTransition as i}from"../common/Easing";import{formatDuration as s,getLargeTimeUnitRange as n,getMatchingTimeUnit as l,getTimeUnitRange as a,MONTH_NAMES as o}from"../common/TimeTools";import{TimeSliderDynamicHistogram as h}from"../data/histogram/TimeSliderDynamicHistogram";import{TimeSliderIntervalsModel as r}from"../data/TimeSliderIntervalsModel";import{addDuration as d,addPadding as m,applyTimeRangeUpdate as g,timeRangesOverlap as u,timeRangesUnion as c}from"../data/TimeSliderRange";import{TypedEventEmitter as p}from"../event/TypedEventEmitter";import{TimeSliderHistogramLayer as y}from"../layer/TimeSliderHistogramLayer";import{TimeSliderIntervalsLayer as T}from"../layer/TimeSliderIntervalsLayer";import{CENTURY as v,DECADE as f,MILLENIUM as E,ONE_DAY as L,ONE_HOUR as x,ONE_MINUTE as R,ONE_MONTH as b,ONE_SECOND as w,ONE_WEEK as V,ONE_YEAR as S,TODAY as D}from"../ticks/TimeSliderConstants";import{TimeTicksBar as M}from"../ticks/TimeTicksBar";import{YAxisTicks as k}from"../ticks/YAxisTicks";const $=w,z=10*E;export class TimeSlider extends p{getLayers(){return[...this.layers]}getVisibleLayers(){return this.getLayers().filter(e=>e.visible)}constructor(i){super(),this.valueRanges=new Map,this.layers=[],this.onDestroy=[],this.ticksBar=new M,this.loaders=new Set,this.layerUnloaders=new Map,this.pressedKeys=new Set,this.container=null,this.d=new t,this.id=e(),this.playing=!1,this.live=!1,this._showCurrent=!1,this.current=Date.now(),this.range={time:D,value:{minValue:0,maxValue:100}},this.size={width:100,height:100},this.sliderElement=document.createElement("div"),this.yAxisTicks=new k,this.hoverLine=document.createElement("div"),this.toolTip=document.createElement("div"),this.selectedLabel=document.createElement("div"),this.selectingRangeElement=document.createElement("div"),this.selectingRange=!1,this.selectingRangeVisible=!1,this.updateValueRangesQueue=new Map,this.showingStats=!1,this.mouse=null,this.updatingLabel=!1,this.dragging=!1,this.pinching=!1,this.hoverOptions=i?.hover||{},this.selectionOptions={highlight:"boolean"!=typeof i?.selection?.highlight||i.selection.highlight,label:"boolean"!=typeof i?.selection?.label||i.selection.label},this.showCurrent=i?.showCurrent||!1,this.showTicks=i?.showTicks||!1,this.selectRangeMode=i?.selectRangeMode||"select",this.playSpeed=i?.playSpeed||"auto",this.liveRange=i?.liveRange||10*w,this.theme=i?.theme||"dark",this.syncMaxValues()}startSelectingRange(e){this.selectingRange=!0,this.whenDoneSelectingRange=e}stopSelectingRange(){this.selectingRange=!1,this.whenDoneSelectingRange?.(),this.whenDoneSelectingRange=void 0,this.selectingRangeVisible&&(this.container.removeChild(this.selectingRangeElement),this.selectingRangeVisible=!1)}syncMaxValues(){return this.updateAllValueRanges(),this.on("time",()=>this.updateAllValueRanges())}syncMaxValuesForLayer(e){return this.updateValueRanges(e.yAxisGroup),e.model.on(()=>this.updateValueRanges(e.yAxisGroup))}updateAllValueRanges(){this.layers.filter(e=>e.visible).forEach(e=>{this.updateValueRanges(e.yAxisGroup,!0)}),this.renderYAxis()}updateValueRanges(e,t){this.updateValueRangesQueue.has(e)||this.updateValueRangesQueue.set(e,{lastUpdate:0,pending:void 0});const i=this.updateValueRangesQueue.get(e);if(Date.now()-i.lastUpdate<100)return i.pending&&clearTimeout(i.pending),void(i.pending=setTimeout(()=>{i.pending=void 0,this.updateValueRanges(e)},200));i.lastUpdate=Date.now();const s=new Map,n=new Map;this.layers.filter(e=>e.visible).forEach(e=>{const t=e.yAxis.group||e.id;s.has(t)||(s.set(t,-Number.MAX_VALUE),n.set(t,Number.MAX_VALUE));const i=e.model.getValueRange(this.getTimeRange());i.minValue<n.get(t)&&n.set(t,i.minValue),i.maxValue>s.get(t)&&s.set(t,i.maxValue)}),this.valueRanges.clear(),s.forEach((e,t)=>{this.valueRanges.set(t,{max:e,min:n.get(t)})}),t||this.renderYAxis(),this.emit("valueRanges",e)}renderYAxis(){const e=new Map;this.layers.filter(e=>e.visible).forEach(t=>{const i=t.yAxis.group||t.id;e.has(i)||e.set(i,{min:t.min,max:t.max,group:i}),e.set(i,{...e.get(i),...t.yAxis,min:t.min,max:t.max})});const t=[];e.forEach(e=>{if(e.visible){const i=this.valueRanges.get(e.group);i&&t.push({...e,minValue:i.min,maxValue:i.max})}}),this.yAxisTicks.render(t)}setTheme(e){this.theme=e,this.ticksBar.setDarkMode("dark"===e),this.engine?.setTheme(e)}addLayerLoader(e){this.loaders.add(e)}showStats(e){this.showingStats=e,this.engine?.showStats(e)}async setEngine(e){this.engine&&(this.layerUnloaders.forEach(e=>e()),this.layerUnloaders.clear(),this.engine.dispose()),this.initSliderContainer(),this.engine=e,this.engine.setTheme(this.theme),await this.engine.init(this.sliderElement),this.engine.setTheme(this.theme),this.getVisibleLayers().forEach(e=>this.loadLayer(e)),this.engine.showStats(this.showingStats),this.engine.setTimeRange(this.getTimeRange()),this.engine.setValueRange(this.getValueRange()),this.engine.setSize(this.size.width,this.size.height)}initSliderContainer(){this.stopControls&&this.stopControls(),this.container?.removeChild(this.sliderElement);let e=0;this.showTicks&&(e+=24),this.showCurrent&&(e+=4),this.sliderElement=document.createElement("div"),this.sliderElement.oncontextmenu=()=>!1,this.sliderElement.tabIndex=0,this.sliderElement.style.top="0px",this.sliderElement.style.width="100%",this.sliderElement.style.outline="none",this.sliderElement.style.touchAction="none",this.sliderElement.style.height=`calc(100% - ${0+e}px)`,this.container?.appendChild(this.sliderElement),this.initSelectLabel(),this.stopControls=this.initControls(),this.onDestroy.push(()=>{this.container?.removeChild(this.sliderElement)})}get showCurrent(){return this._showCurrent}set showCurrent(e){if(e!==this._showCurrent){this._showCurrent=e,this.ticksBar.showLine=!this.showCurrent;let t=0,i=0;this.showTicks&&(i+=24),this.showCurrent&&(i+=4),this.sliderElement.style.height=`calc(100% - ${t+i}px)`}}async init(e,t){const i="string"==typeof e?document.getElementById(e):e;if(this.container=i,i){i.oncontextmenu=()=>!1;let e=0,s=0;if(this.showTicks){s+=24;const e=document.createElement("div");e.style.width="100%",e.style.height="24px",e.style.position="absolute",e.style.bottom="0px",e.style.touchAction="none",i.appendChild(e),this.ticksBar.init(e,e=>this.fit({range:e,animate:1e3})),this.ticksBar.showLine=!this.showCurrent}this.showCurrent&&(s+=4),this.sliderElement.oncontextmenu=()=>!1,this.sliderElement.tabIndex=0,this.sliderElement.style.top=`${e}px`,this.sliderElement.style.width="100%",this.sliderElement.style.outline="none",this.sliderElement.style.touchAction="none",this.sliderElement.style.height=`calc(100% - ${e+s}px)`,i.appendChild(this.sliderElement),this.yAxisTicks.canvas.style.top=`${e}px`,this.yAxisTicks.canvas.style.height=`calc(100% - ${e+s}px)`,i.appendChild(this.yAxisTicks.canvas),this.initHoverTooltip(),this.initSelectLabel(),this.setSize(this.sliderElement.clientWidth,this.sliderElement.clientHeight),this.syncSize(),this.setTimeRange(C(t)),this.setValueRange(C(t))}else console.warn(`Element ${e} not found`)}initSelectLabel(){this.selectedLabel.style.position="absolute",this.selectedLabel.style.padding="4px 8px",this.selectedLabel.style.background="rgba(0, 0, 0, 0.75)",this.selectedLabel.style.color="white",this.selectedLabel.style.fontSize="12px",this.selectedLabel.style.maxWidth="200px",this.selectedLabel.style.fontFamily="monospace",this.selectedLabel.style.borderRadius="4px",this.selectedLabel.style.pointerEvents="none",this.selectedLabel.style.display="none",this.selectedLabel.style.zIndex="10",this.sliderElement.appendChild(this.selectedLabel)}getLabel(e,t,i,s){if(t.labeler){const n=t.labeler(e,i,s);return null===n?null:"string"==typeof n?`<div>${n}</div>`:n?n.outerHTML:`<div>${e.name||e.id}</div>`}return`<div>${e.name||e.id}</div>`}getLayerById(e){return this.layers.find(t=>t.id===e)}select(e,t){this.stopSelectingRange(),this.stopUpdatingLabel?.();const i=()=>{this.updatingLabel=!1,this.stopUpdatingLabel?.(),this.stopUpdatingLabel=void 0,this.selectedLabel.style.display="none",this.layers.forEach(e=>e.select([])),this.selectedLayerId=void 0,this.emit("select",[])},s=e=>{this.layers.filter(t=>!e.some(e=>t.id===e.layer.id)).forEach(e=>e.select([])),e.forEach(e=>{e.layer.select(e.elements)}),this.emit("select",e)};if(t){s(this.getVisibleLayers().map(e=>{const i=e.model.dataInTimeRange(t);return{layer:e,elements:i}}).filter(e=>e.elements.length>0))}else if(e){const t=this.findElements(e,24);if(s(t.map(e=>({layer:e.layer,elements:e.elements})).flat()),1===t.length&&t[0].elements.length>0&&this.selectionOptions.label){const e=t[0].elements[0],s=t[0].layer;this.selectedLabel.innerHTML=this.getLabel(e,s,t[0].t,t[0].v)||"",this.selectedLabel.style.display="block";const n=this.selectedLabel.offsetWidth,l=this.selectedLabel.offsetHeight;this.selectedLayerId=s.id;const a=Array.isArray(e.t);this.updatingLabel=!0;const o=()=>{if(!this.updatingLabel)return;const{startTime:i,duration:s,endTime:o}=this.getTimeRange(),h=t[0].layer.model.get(e.id);if(h){const e=u(this.getTimeRange(),h.t);if(e){const o=this.getSliderBounds();let r=(.5*(e.startTime+e.endTime)-i)/s*o.width;const d="number"==typeof h.v?h.v:.5*(h.v[1]+h.v[0]);let m=this.modelValueToPixels(d,t[0].layer);a?m-=.5*l:m+=8;const g=.5*n,u=.5*l,c=o.width-.5*n,p=o.height-.5*l,y=Math.min(c,Math.max(g,r)),T=Math.min(p,Math.max(u,m));this.selectedLabel.style.display="block",this.selectedLabel.style.left=y-.5*n+"px",this.selectedLabel.style.top=`${T}px`}else this.selectedLabel.style.display="none"}else this.selectedLabel.style.display="none"};o();const r=s instanceof y&&s.histogram instanceof h;this.stopUpdatingLabel=this.on("time",r?i:o)}}else i()}listenToClicks(){let e=null;const t=t=>{e={x:t.clientX,y:t.clientY}},i=t=>{if(!e)return;const i=t.clientX-e.x,s=t.clientY-e.y;i*i+s*s<=25&&(this.stopSelectingRange(),this.select(e)),e=null},s=()=>{e=null};return this.sliderElement.addEventListener("pointerdown",t),this.sliderElement.addEventListener("pointerup",i),this.sliderElement.addEventListener("pointercancel",s),()=>{this.sliderElement.removeEventListener("pointerdown",t),this.sliderElement.removeEventListener("pointerup",i),this.sliderElement.removeEventListener("pointercancel",s)}}getSliderBounds(){return this.sliderElement.getBoundingClientRect()}mouseInSlider(e){const t=this.getSliderBounds(),i="x"in e?e:{x:e.clientX,y:e.clientY},s={x:i.x-t.left,y:i.y-t.top},n={x:s.x/t.width,y:-s.y/t.height+1},{startTime:l,duration:a}=this.getTimeRange(),o=l+n.x*a,{minValue:h,maxValue:r}=this.getValueRange();return{absolute:s,normalized:n,t:o,v:h+n.x*(r-h)}}pixelsToLayerValue(e,t){if(!e)return{yInLayer:0,toLayerHeight:1};const i="normalized"in e?e.normalized:this.mouseInSlider(e).normalized;let s=t.min;const n=t.max-s;return{yInLayer:(i.y-s)/n,toLayerHeight:n/this.getSliderBounds().height}}pixelsToModelValue(e,t){const{yInLayer:i,toLayerHeight:s}=this.pixelsToLayerValue(e,t);let n=0,l=100;if(t.model instanceof r){const e=this.valueRanges.get(t.yAxisGroup)||{min:0,max:1e3};n=e.min,l=e.max-n}return{yInModel:n+i*l,toModelHeight:s*l}}layerValueToPixels(e,t){let i=t.min;return(1-(i+(t.max-i)*e))*this.getSliderBounds().height}modelValueToPixels(e,t){let i=0,s=100;if(t.model instanceof r){const e=t.model.getValueRange(this.getTimeRange());i=e.minValue,s=e.maxValue-i}const n=(e-i)/s;return this.layerValueToPixels(n,t)}findElements(e,t){const{width:i,height:s}=this.getSliderBounds(),{normalized:n}=this.mouseInSlider(e),{startTime:l,endTime:a,duration:o}=this.getTimeRange(),h=l+n.x*o,r=t||12,d=r/i*o,m={startTime:h-1,endTime:h+1},g={startTime:h-.5*d,endTime:h+.5*d};return this.getVisibleLayers().map(e=>{const{yInModel:t,toModelHeight:i}=this.pixelsToModelValue({normalized:n},e),s=e instanceof T?0:r*i,l=e instanceof T?m:g,a={minValue:t-.5*s,maxValue:t+.5*s},o=e.model.dataInRange({...l,...a});return{layer:e,elements:o,t:h,v:t}}).filter(e=>e.elements.length>0)}updateHover(e){if(this.dragging)return this.hoverLine.style.display="none",void(this.toolTip.style.display="none");if(void 0!==e&&(this.mouse=e),this.mouse){const e=this.getSliderBounds(),{normalized:t}=this.mouseInSlider(this.mouse),{startTime:i,endTime:s,duration:n}=this.getTimeRange(),l=i+t.x*n,a=this.findElements(this.mouse),h=a.map(e=>e.elements.map(t=>({e:t,l:e.layer,t:e.t,v:e.v}))).flat();let r;if(h.length>0)if(h.length>3){const e=h.slice(0,2).map(e=>this.getLabel(e.e,e.l,e.t,e.v));r=e.flat().filter(e=>null!==e).join(""),r+=`<div>And ${h.length-2} more...</div>`}else{const e=a.map(e=>e.elements.map(t=>this.getLabel(t,e.layer,e.t,e.v)));r=e.flat().filter(e=>null!==e).join("")}const d=new Date(l),m=d.getDate(),g=d.getMonth(),u=d.getFullYear(),c=d.getHours(),p=d.getMinutes(),y=d.getSeconds(),T=`${(m<10?"0":"")+m} ${o[g]} ${u}`,v=`${(c<10?"0":"")+c}:${(p<10?"0":"")+p}:${(y<10?"0":"")+y}`;let f="";const E=this.ticksBar.cache.high.spacing;(void 0===this.hoverOptions.date?E>=x:this.hoverOptions.date)&&(f+=`<div>${T}</div>`),(void 0===this.hoverOptions.time?E<=L:this.hoverOptions.time)&&(f+=`<div>${v}</div>`),r&&(f+=r),this.toolTip.innerHTML=f,this.toolTip.style.display=f.length>0?"block":"none";const R=88,b=36;let w=this.mouse.x+10,V=this.mouse.y+10;const S=e.left+e.width-R-5,D=e.top+e.height-b-5;w>S&&(w=S),V>D&&(V=D),this.toolTip.style.left=`${w}px`,this.toolTip.style.top=`${V}px`}else this.hoverLine.style.display="none",this.toolTip.style.display="none"}initHoverTooltip(){this.toolTip.style.position="absolute",this.toolTip.style.padding="4px 8px",this.toolTip.style.background="rgba(0, 0, 0, 0.75)",this.toolTip.style.color="white",this.toolTip.style.fontSize="12px",this.toolTip.style.fontFamily="monospace",this.toolTip.style.borderRadius="4px",this.toolTip.style.pointerEvents="none",this.toolTip.style.display="none",this.toolTip.style.zIndex="10",this.toolTip.style.overflow="hidden",document.body.appendChild(this.toolTip)}initHoverListener(){const e=()=>{this.updateHover(null)},t=e=>{this.updateHover({x:e.clientX,y:e.clientY})};this.sliderElement.addEventListener("mouseleave",e),this.sliderElement.addEventListener("mousemove",t);const i=this.listenToClicks();return()=>{this.sliderElement.removeEventListener("mouseleave",e),this.sliderElement.removeEventListener("mousemove",t),i()}}syncSize(){const e=()=>{const{offsetWidth:e,offsetHeight:t}=this.sliderElement;this.setSize(e,t)},t=new ResizeObserver(()=>{e()});this.container&&(t.observe(this.container),e()),this.onDestroy.push(()=>{t.disconnect()})}getTimeRange(){return d(this.range.time)}getValueRange(){return this.range.value}setTimeRange(e,t){const i=this.getTimeRange(),s=g(i,e);s.startTime===i.startTime&&s.endTime===i.endTime||(this.range.time=s,this.engine?.setTimeRange(s),this.showTicks&&this.ticksBar.setTimeRange(s),this.emit("time",s),this.updateHover())}setValueRange(e){const t={...this.getValueRange(),...e};this.range.value=t,this.engine?.setValueRange(t),this.emit("value",this.getValueRange()),this.updateHover()}setSize(e,t){this.size={width:e,height:t},this.showTicks&&this.ticksBar.setWidth(e);const i=this.getTimeRange(),s=this.getValueRange();this.engine?.setSize(e,t),this.setTimeRange(i),this.setValueRange(s),this.updateHover(),this.emit("size",{width:e,height:t})}up(e){const{startTime:t,endTime:i,duration:s}=this.getTimeRange();let l={startTime:0,endTime:Date.now()};const o=.5*(t+i);if(s>=.9*E){const e=A(10*s);l=n(o,e)}else{const e=[{threshold:v,unit:"millennium"},{threshold:f,unit:"century"},{threshold:S,unit:"decade"},{threshold:.9*b,unit:"year"},{threshold:V,unit:"month"},{threshold:L,unit:"week"},{threshold:x,unit:"day"},{threshold:R,unit:"hour"},{threshold:w,unit:"minute"},{threshold:-1,unit:"second"}];let t=0;for(;s<.9*e[t].threshold;)t++;const i=e[t].unit;l=a(o,i)}this.fit({...e,range:l})}down(e){const{startTime:t,endTime:i,duration:s}=this.getTimeRange();let l={startTime:0,endTime:Date.now()};const o=t+("number"==typeof e?.xRatio?e.xRatio:.5)*s;if(s>=.9*E){const e=A(s/10);l=n(o,e)}else{let e=0;const t=[{threshold:E,unit:"century"},{threshold:v,unit:"decade"},{threshold:f,unit:"year"},{threshold:S,unit:"month"},{threshold:1.1*b,unit:"week"},{threshold:V,unit:"day"},{threshold:L,unit:"hour"},{threshold:x,unit:"minute"},{threshold:R,unit:"second"}].reverse();for(;s>1.1*t[e].threshold;)e++;const i=t[e].unit;l=a(o,i)}this.fit({...e,range:l})}next(e){this.skip(1,e)}previous(e){this.skip(-1,e)}skip(e,t){let i={startTime:0,endTime:Date.now()};const{startTime:s,endTime:o,duration:h}=this.getTimeRange(),r=.5*(s+o);if(h>=9*E){const e=A(h);i=n(r,e)}else{const t=l(s,o);i=t?a(r,t,Math.round(e)):{startTime:s+e*h,endTime:o+e*h}}this.fit({...t,range:i})}getTimeRangeLabel(){const{startTime:e,endTime:t}=this.getTimeRange(),i=new Date(e),s=new Date(t);if(0===i.getHours()&&0===i.getHours()&&0===i.getMinutes()&&0===i.getMinutes()&&0===i.getSeconds()&&0===i.getSeconds()&&0===i.getMilliseconds()&&0===i.getMilliseconds()){const e=new Date(t-1),n=i.toLocaleString("default",{month:"short"}),l=e.toLocaleString("default",{month:"short"});return i.getFullYear()===e.getFullYear()?i.getMonth()===e.getMonth()?i.getDate()===e.getDate()?`${e.getDate()} ${l} ${e.getFullYear()}`:1===i.getDate()&&1===s.getDate()?`${l} ${e.getFullYear()}`:`${i.getDate()} - ${e.getDate()} ${l} ${e.getFullYear()}`:1===i.getDate()&&1===s.getDate()&&0===i.getMonth()&&0===s.getMonth()?`${e.getFullYear()}`:`${i.getDate()} ${n} - ${e.getDate()} ${l} ${e.getFullYear()}`:1===i.getDate()&&1===s.getDate()&&0===i.getMonth()&&0===s.getMonth()?` ${i.getFullYear()} - ${e.getFullYear()}`:`${i.getDate()} ${n} ${i.getFullYear()} - ${e.getDate()} ${l} ${e.getFullYear()}`}}cancelFit(){this.stopFit?.(),this.stopFit=void 0}fit(e){this.cancelFit();const t=e?.range||this.getLayersTimeRange(),s=e?.padding?m(t,e.padding):t;if(e?.animate){const t=this.getTimeRange();this.stopFit=i(t.startTime,t.endTime,s.startTime,s.endTime,e.animate,(e,t)=>this.setTimeRange({startTime:e,endTime:t}))}else this.setTimeRange(s)}getLayersTimeRange(){if(0===this.getVisibleLayers().length)return D;{let e=this.getVisibleLayers()[0].model.getTimeRange();return this.getVisibleLayers().slice(1).forEach(t=>e=c(e,t.model.getTimeRange())),e}}loadLayer(e){if(e.timeSlider&&e.timeSlider.id!==this.id)console.warn("Layer already has been loaded by another time slider, create a new layer with the same model and style if you want to add it to another time slider");else if(this.engine&&!this.layerUnloaders.has(e.id)){const t=[...this.loaders].filter(e=>this.engine instanceof e.engineClass).find(t=>t.canLoad(e));if(t){const i=Date.now(),n=t.load(e,this.engine.scene,this.engine,this);e.timeSlider=this,e.loaded=!0;const l=e.name||e.constructor.name+"#"+e.id.slice(e.id.length-4).toUpperCase();console.log(`Loaded ${l} in ${s(Date.now()-i)}`);const a=this.syncMaxValuesForLayer(e);this.layerUnloaders.set(e.id,()=>{a(),n(),e.loaded=!1})}else console.warn("No loader found for",{layer:e})}}unloadLayer(e){this.selectedLayerId===e.id&&this.select(null),this.layerUnloaders.has(e.id)&&(this.layerUnloaders.get(e.id)(),this.layerUnloaders.delete(e.id))}addLayer(e){if(this.layers.push(e),e.visible){this.loadLayer(e);const t=e.model.getTimeRange();if(1===this.getVisibleLayers().length)this.setTimeRange(t);else{const e=c(this.getTimeRange(),t);this.setTimeRange(e)}}e.on("visible",t=>{e.visible?this.loadLayer(e):this.unloadLayer(e)})}removeLayer(e){const t="string"==typeof e?e:e.id,i=this.layers.find(e=>e.id===t);i&&(this.unloadLayer(i),this.layerUnloaders.delete(t),this.layers=this.layers.filter(e=>e.id!==t))}destroy(){this.layers.map(e=>e.id).forEach(e=>this.removeLayer(e)),this.onDestroy.forEach(e=>e())}addHorizontalPinchZoom(){let e=null,t=null;const i=()=>{this.pinching=!1,e=null,t=null},s=i=>{if(2===i.touches.length){i.preventDefault(),this.dragging=!1,this.pinching=!0;const s=this.mouseInSlider(i.touches[0]).t,n=this.mouseInSlider(i.touches[1]).t;e=Math.min(s,n),t=Math.max(s,n)}},n=s=>{if(2===s.touches.length){if(null===e||null===t)return;s.preventDefault(),this.dragging=!1;const i=this.mouseInSlider(s.touches[0]).normalized.x,n=this.mouseInSlider(s.touches[1]).normalized.x,l=Math.min(i,n),a=Math.max(i,n),o=(t-e)/(a-l);let h=e-l*o,r=t+(1-a)*o;if(o>z){const e=.5*(h+r);h=e-.5*z,r=e+.5*z}if(o<$){const e=.5*(h+r);h=e-.5*$,r=e+.5*$}this.setTimeRange({startTime:h,endTime:r})}else i()},l=()=>{i()};this.sliderElement.addEventListener("touchstart",s,{passive:!1}),this.sliderElement.addEventListener("touchmove",n,{passive:!1}),this.sliderElement.addEventListener("touchend",l),this.sliderElement.addEventListener("touchcancel",l),this.onDestroy.push(()=>{this.sliderElement.removeEventListener("touchstart",s),this.sliderElement.removeEventListener("touchmove",n),this.sliderElement.removeEventListener("touchend",l),this.sliderElement.removeEventListener("touchcancel",l)})}initControls(){const e=new t;this.dragging=!1;let i,s=0,n=0,l=0;e.add(this.initHoverListener());const a=e=>{this.sliderElement.focus(),e.preventDefault();const t=this.mouseInSlider(e);this.zoom(.001*e.deltaY,{x:t.normalized.x})};let o=0,h=-1;const r=e=>{const t=Date.now(),i=t-o;h>=0&&i<300&&i>0&&(this.select(null),e.preventDefault(),this.zoom(-.75,{animate:1e3,x:h})),o=t},d=e=>{e.preventDefault(),this.select(null);const t=this.mouseInSlider(e);this.zoom(-.75,{animate:1e3,x:t.normalized.x})};this.selectingRangeElement.style.height="calc(100% - 6px)",this.selectingRangeElement.style.pointerEvents="none",this.selectingRangeElement.style.position="absolute",this.selectingRangeElement.style.border="3px solid #df0",this.selectingRangeElement.style.background="#df04",this.selectingRangeElement.style.top="0px";const m=e=>{if(this.sliderElement.focus(),2===e.button||0===e.button){e.preventDefault();const t=this.mouseInSlider(e),i=t.normalized.x,{startTime:a,duration:o}=this.getTimeRange();s=a+i*o,n=Date.now(),l=t.absolute.x,(e.ctrlKey||2===e.button)&&(this.selectingRange=!0),this.selectingRange?(this.selectingRangeElement.style.left=t.absolute.x+"px",this.selectingRangeElement.style.width="0px",this.container.appendChild(this.selectingRangeElement),this.selectingRangeVisible=!0):this.dragging=!0}},g=e=>{const t=this.mouseInSlider(e);return i=t.normalized.x,t},u=e=>{const t=g(e);if(this.selectingRange){const e=Math.abs(l-t.absolute.x),i=Math.min(l,t.absolute.x);this.selectingRangeElement.style.left=i+"px",this.selectingRangeElement.style.width=e-6+"px"}if(!this.dragging||Date.now()-n<100&&Math.abs(l-t.absolute.x)<10)return;e.preventDefault();const i=t.normalized.x,{startTime:a,endTime:o}=this.getTimeRange(),h=a+i*(o-a)-s;this.setTimeRange({startTime:a-h,endTime:o-h})},c=e=>{const t=this.getSliderBounds(),n=t.height-(e.clientY-t.top);if(!this.dragging&&!this.pinching&&n<8)this.ticksBar.click(e);else if(i=void 0,this.dragging=!1,this.selectingRange){const t=this.mouseInSlider(e).normalized.x,{startTime:i,endTime:n}=this.getTimeRange(),l=i+t*(n-i);"zoom"===this.selectRangeMode&&this.fit({range:{startTime:Math.min(s,l),endTime:Math.max(s,l)},animate:1e3}),"select"===this.selectRangeMode&&this.select(null,{startTime:Math.min(s,l),endTime:Math.max(s,l)})}this.stopSelectingRange()},p=e=>{this.pressedKeys.add(e.code)},y=e=>{this.pressedKeys.delete(e.code),"Space"===e.code&&(e.preventDefault(),this.togglePlaying()),"KeyF"===e.code&&(e.preventDefault(),this.fit({animate:3e3}));const t=void 0;"ArrowRight"===e.code&&(e.preventDefault(),this.skip(1,{animate:t})),"ArrowLeft"===e.code&&(e.preventDefault(),this.skip(-1,{animate:t})),"ArrowUp"===e.code&&(e.preventDefault(),this.up({animate:t})),"ArrowDown"===e.code&&(e.preventDefault(),this.down({xRatio:i,animate:t}))};let T=!0;const v=()=>{if(T){const e=this.pressedKeys.has("ShiftLeft")?.05:.01,t=2*e,s=this.pressedKeys.has("KeyD"),n=this.pressedKeys.has("KeyA");s&&this.shift(-e),n&&this.shift(e),this.pressedKeys.has("KeyW")&&this.zoom(-t,{x:s||n?void 0:i}),this.pressedKeys.has("KeyS")&&this.zoom(t,{x:s||n?void 0:i}),requestAnimationFrame(v)}};v(),e.add(()=>T=!1);const f=e=>e.preventDefault();this.sliderElement.addEventListener("contextmenu",f),this.sliderElement.addEventListener("wheel",a),this.sliderElement.addEventListener("pointerdown",m),this.sliderElement.addEventListener("pointermove",u),this.sliderElement.addEventListener("pointerup",c),this.sliderElement.addEventListener("dblclick",d),this.sliderElement.addEventListener("touchend",r),this.sliderElement.addEventListener("touchstart",e=>{if(1===e.touches.length){const t=this.mouseInSlider(e.touches[0]);h=t.normalized.x}else h=-1}),this.sliderElement.addEventListener("keydown",p),this.sliderElement.addEventListener("keyup",y),this.addHorizontalPinchZoom();const E=()=>{this.sliderElement.removeEventListener("contextmenu",f),this.sliderElement.removeEventListener("wheel",a),this.sliderElement.removeEventListener("pointerdown",m),this.sliderElement.removeEventListener("pointermove",u),this.sliderElement.removeEventListener("pointerup",c),this.sliderElement.removeEventListener("dblclick",d),this.sliderElement.removeEventListener("touchend",r),this.sliderElement.removeEventListener("keydown",p),this.sliderElement.removeEventListener("keyup",y)};return this.onDestroy.push(E),e.add(E),e.disposeLater()}shift(e,t){const{startTime:i,endTime:s,duration:n}=this.getTimeRange(),l=t?.absolute?e:e*n;this.fit({...t,range:{startTime:i-l,endTime:s-l}})}zoom(e,t){const i="number"==typeof t?.x?t.x:.5,{startTime:s,endTime:n,duration:l}=this.getTimeRange(),a={startTime:s-e*l*i,endTime:n+e*l*(1-i)},o=a.endTime-a.startTime,h=a.startTime+.5*o;o>z&&(a.startTime=h-.5*z,a.endTime=h+.5*z),o<$&&(a.startTime=h-.5*$,a.endTime=h+.5*$),this.fit({range:a,animate:t?.animate})}togglePlaying(){this.playing?this.pause():this.play()}isPlaying(){return this.playing}play(){if(this.playing)return;this.playing=!0,this.emit("playing",!0);let e=Date.now();const t=()=>{if(this.playing){if(this.live){const{duration:e}=this.getTimeRange(),t=Date.now(),i=10/this.size.width;this.setTimeRange({startTime:t-(1-i)*e,endTime:t+i*e}),this.setCurrent(t)}else if("auto"!==this.playSpeed||this.showCurrent){const t=Date.now(),i=t-e,s=this.current-this.getTimeRange().startTime,n="auto"===this.playSpeed?1:this.playSpeed;this.shift(-n*i,{absolute:!0}),this.setCurrent(this.getTimeRange().startTime+s),e=t}else{const t=Date.now();let i=5e-5*(t-e);this.pressedKeys.has("ShiftLeft")&&(i*=5);const s=this.current-this.getTimeRange().startTime;this.shift(-i),this.setCurrent(this.getTimeRange().startTime+s),e=t}requestAnimationFrame(t)}};t()}setCurrent(e){this.current!==e&&(Math.abs(e-Date.now())>100&&this.live&&(this.pause(),this.setLive(!1)),this.current=e,this.emit("current",e))}pause(){this.playing&&(this.playing=!1,this.emit("playing",!1),this.setLive(!1))}setLive(e){if(this.live!==e){if(this.live=e,e){const e=this.getTimeRange();this.fit({range:{startTime:e.endTime-this.liveRange,endTime:e.endTime},animate:w}),this.play()}this.emit("live",e)}}}function C(e){return{startTime:"number"==typeof e?.startTime?e.startTime:"number"==typeof e?.endTime?e.duration?e.endTime-e.duration:e.endTime-L:e?.duration?Date.now()-.5*e.duration:Date.now()-.5*L,endTime:"number"==typeof e?.endTime?e.endTime:"number"==typeof e?.startTime?e.duration?e.startTime+e.duration:e.startTime+L:e?.duration?Date.now()+.5*e.duration:Date.now()+.5*L,duration:e?.duration?e.duration:"number"==typeof e?.startTime&&"number"==typeof e?.endTime?e.endTime+e.startTime:L,minValue:"number"==typeof e?.minValue?e.minValue:"number"==typeof e?.maxValue?e.maxValue>0?0:e.maxValue-100:0,maxValue:"number"==typeof e?.maxValue?e.maxValue:"number"==typeof e?.minValue?e.minValue<0?0:e.minValue+100:100}}function A(e){const t=e/315576e5,i=Math.log10(t),s=Math.ceil(i);return Math.pow(10,s)}
1
+ import{v4 as e}from"uuid";import{Disposables as t}from"../common/Disposables.js";import{animateRangeTransition as i}from"../common/Easing.js";import{formatDate as s,formatDateRange as n,formatDuration as l,getDefaultLocale as a,getLargeTimeUnitRange as o,getMatchingTimeUnit as r,getTimeUnitRange as h,setDefaultLocale as d}from"../common/TimeTools.js";import{TimeSliderDynamicHistogram as m}from"../data/histogram/TimeSliderDynamicHistogram.js";import{getTimeArray as c}from"../data/TimeSliderElement.js";import{TimeSliderIntervalsModel as g}from"../data/TimeSliderIntervalsModel.js";import{addDuration as u,addPadding as p,applyTimeRangeUpdate as y,clampTimeRange as v,mergeTimeRanges as T,timeRangesOverlap as f,timeRangesUnion as E}from"../data/TimeSliderRange.js";import{TypedEventEmitter as L}from"../event/TypedEventEmitter.js";import{TimeSliderHistogramLayer as x}from"../layer/TimeSliderHistogramLayer.js";import{TimeSliderIntervalsLayer as R}from"../layer/TimeSliderIntervalsLayer.js";import{CENTURY as b,DECADE as w,MILLENIUM as S,ONE_DAY as C,ONE_HOUR as V,ONE_MINUTE as k,ONE_MONTH as M,ONE_SECOND as B,ONE_WEEK as D,ONE_YEAR as z,TODAY as I}from"../ticks/TimeSliderConstants.js";import{TimeTicksBar as O}from"../ticks/TimeTicksBar.js";import{YAxisTicks as A}from"../ticks/YAxisTicks.js";const H=B,_=10*S;export class TimeSlider extends L{getLayers(){return[...this.layers]}getVisibleLayers(){return this.getLayers().filter(e=>e.visible)}constructor(i){super(),this.valueRanges=new Map,this.layers=[],this.onDestroy=[],this.ticksBar=new O,this.loaders=new Set,this.layerUnloaders=new Map,this.layerListenerStoppers=new Map,this.layerLoaders=new Map,this.pressedKeys=new Set,this.container=null,this.d=new t,this.id=e(),this.playing=!1,this.live=!1,this._showCurrent=!1,this.current=Date.now(),this.range={time:I,value:{minValue:0,maxValue:100}},this.size={width:100,height:100},this.sliderElement=document.createElement("div"),this.yAxisTicks=new A,this.hoverLine=document.createElement("div"),this.toolTip=document.createElement("div"),this.selectedLabel=document.createElement("div"),this.selectingRangeElement=document.createElement("div"),this.selectionOverlayContainer=document.createElement("div"),this._selectionRanges=[],this.selectionRangeElements=[],this.shadingElements=[],this.columnBandOverlayContainer=document.createElement("div"),this.columnBandElements=[],this.selectingRange=!1,this.selectingRangeVisible=!1,this.updateValueRangesQueue=new Map,this.showingStats=!1,this._engineReady=!1,this.mouse=null,this.updatingLabel=!1,this.hoverCleared=!0,this.dragging=!1,this.pinching=!1,this.hoverOptions=i?.hover||{},this.selectionOptions={highlight:"boolean"!=typeof i?.selection?.highlight||i.selection.highlight,label:"boolean"!=typeof i?.selection?.label||i.selection.label,shading:"boolean"!=typeof i?.selection?.shading||i.selection.shading,invertShading:"boolean"==typeof i?.selection?.invertShading&&i.selection.invertShading,pick:i?.selection?.pick||"element",columnBand:i?.selection?.columnBand},this.showCurrent=i?.showCurrent||!1,this.showTicks=i?.showTicks||!1,this.selectRangeMode=i?.selectRangeMode||"select",this.playSpeed=i?.playSpeed||"auto",this.liveRange=i?.liveRange||10*B,this.theme=i?.theme||"dark",this._locale=i?.locale||a(),d(this._locale),this.ticksBar.setLocale(this._locale),this.ticksBar.setWeekLabel(i?.weekLabel||"default",i?.weekLabelPrefix),this.ticksBar.setTickLabelStyler(i?.tickLabelStyler),this.setLimits(i?.limits),this.syncMaxValues(),this.on("time",()=>this.renderSelectionOverlay()),this.on("size",()=>this.renderSelectionOverlay())}get locale(){return this._locale}setLocale(e){this._locale=e,d(e),this.ticksBar.setLocale(e),this.emit("locale",e)}setWeekLabel(e,t){this.ticksBar.setWeekLabel(e,t)}setTickLabelStyler(e){this.ticksBar.setTickLabelStyler(e)}get limits(){return this._limits?{...this._limits}:void 0}setLimits(e){!e||e.endTime>e.startTime||(console.warn("Ignoring time slider limits whose endTime is not after startTime",e),e=void 0),this._limits=e?{startTime:e.startTime,endTime:e.endTime}:void 0,this._limits&&this.setTimeRange(this.getTimeRange())}setSelection(e){this._selectionRanges=e.map(e=>({...e})),this.renderSelectionOverlay(!0),this.emit("selectionchange",{ranges:this.getSelection(),phase:"end"})}getSelection(){return this._selectionRanges.map(e=>({...e}))}clearSelection(){this.setSelection([])}setPickMode(e){this.selectionOptions.pick=e,this.updateHover()}selectionTimeToX(e,t,i,s){return e===-1/0?0:e===1/0?s:Math.min(s,Math.max(0,(e-t)/(i-t)*s))}renderSelectionOverlay(e=!1){if(!this.container)return;const t=this.getSliderBounds();if(t.width<=0)return;const{startTime:i,endTime:s}=this.getTimeRange(),n=e=>this.selectionTimeToX(e,i,s,t.width);if((e||this.selectionRangeElements.length!==this._selectionRanges.length||this.selectionRangeElements.some((e,t)=>e.range!==this._selectionRanges[t]))&&(this.selectionRangeElements.forEach(({body:e,startHandle:t,endHandle:i})=>{e.remove(),t?.remove(),i?.remove()}),this.selectionRangeElements=this._selectionRanges.map(e=>this.createSelectionRangeElements(e))),this.selectionRangeElements.forEach(({range:e,body:t,startHandle:i,endHandle:s})=>{const l=n(e.startTime),a=n(e.endTime);t.style.left=l+"px",t.style.width=Math.max(0,a-l)+"px",i&&(i.style.left=l-4+"px"),s&&(s.style.left=a-4+"px")}),this.shadingElements.forEach(e=>e.remove()),this.shadingElements=[],this.selectionOptions.shading&&this._selectionRanges.length>0){const e=T(this._selectionRanges).map(e=>[n(e.startTime),n(e.endTime)]);(this.selectionOptions.invertShading?e:function(e,t){const i=[];let s=0;for(const[t,n]of e)t>s&&i.push([s,t]),s=Math.max(s,n);s<t&&i.push([s,t]);return i}(e,t.width)).forEach(([e,t])=>{if(t<=e)return;const i=document.createElement("div");i.style.position="absolute",i.style.top="0px",i.style.height="100%",i.style.left=e+"px",i.style.width=t-e+"px",i.style.background="rgba(0, 0, 0, 0.5)",i.style.pointerEvents="none",this.selectionOverlayContainer.appendChild(i),this.shadingElements.push(i)})}}renderColumnHoverBand(e){if(this.columnBandElements.forEach(e=>e.remove()),this.columnBandElements=[],"column"!==this.selectionOptions.pick||0===e.length||!this.container)return;const t=this.getSliderBounds();if(t.width<=0)return;const{startTime:i,endTime:s}=this.getTimeRange(),n=e=>Math.min(t.width,Math.max(0,(e-i)/(s-i)*t.width)),l=this.selectionOptions.columnBand?.color??"#fff",a=this.selectionOptions.columnBand?.opacity??.15;e.forEach(({layer:e,elements:t})=>{const i=t.map(c),s=Math.min(...i.map(e=>e[0])),o=Math.max(...i.map(e=>e[1])),r=document.createElement("div");r.style.position="absolute",r.style.left=n(s)+"px",r.style.width=Math.max(1,n(o)-n(s))+"px",r.style.top=100*(1-e.max)+"%",r.style.height=100*(e.max-e.min)+"%",r.style.background=l,r.style.opacity=String(a),r.style.pointerEvents="none",this.columnBandOverlayContainer.appendChild(r),this.columnBandElements.push(r)})}createSelectionRangeElements(e){const t=document.createElement("div");t.style.position="absolute",t.style.top="0px",t.style.height="100%",t.style.background="rgba(100, 180, 255, 0.15)",t.style.borderTop="2px solid rgba(100, 180, 255, 0.8)",t.style.borderBottom="2px solid rgba(100, 180, 255, 0.8)",t.style.boxSizing="border-box",t.style.cursor="grab",t.style.pointerEvents="auto",t.style.touchAction="none",this.selectionOverlayContainer.appendChild(t);const i=()=>{const e=document.createElement("div");return e.style.position="absolute",e.style.top="0px",e.style.height="100%",e.style.width="8px",e.style.cursor="ew-resize",e.style.pointerEvents="auto",e.style.touchAction="none",e.style.background="rgba(100, 180, 255, 0.9)",this.selectionOverlayContainer.appendChild(e),e},s=e.startTime===-1/0?null:i(),n=e.endTime===1/0?null:i();return this.wireSelectionDrag(e,t,s,n),{range:e,body:t,startHandle:s,endHandle:n}}wireSelectionDrag(e,t,i,s){const n=(e,t)=>{e.addEventListener("pointerdown",i=>{i.stopPropagation(),i.preventDefault(),e.setPointerCapture(i.pointerId);const s=t(i),n=e=>{s(e),this.renderSelectionOverlay(),this.emit("selectionchange",{ranges:this.getSelection(),phase:"drag"})};let l=!1;const a=t=>{l||(l=!0,e.hasPointerCapture(t.pointerId)&&e.releasePointerCapture(t.pointerId),e.removeEventListener("pointermove",n),e.removeEventListener("pointerup",a),e.removeEventListener("pointercancel",a),e.removeEventListener("lostpointercapture",a),this.emit("selectionchange",{ranges:this.getSelection(),phase:"end"}))};this.emit("selectionchange",{ranges:this.getSelection(),phase:"start"}),e.addEventListener("pointermove",n),e.addEventListener("pointerup",a),e.addEventListener("pointercancel",a),e.addEventListener("lostpointercapture",a)})};i&&n(i,()=>t=>{const{t:i}=this.mouseInSlider(t);e.startTime=e.endTime===1/0?i:Math.min(i,e.endTime)}),s&&n(s,()=>t=>{const{t:i}=this.mouseInSlider(t);e.endTime=e.startTime===-1/0?i:Math.max(i,e.startTime)}),n(t,t=>{const i=this.mouseInSlider(t).t,s=e.startTime,n=e.endTime;return t=>{const l=this.mouseInSlider(t).t-i;s===-1/0&&n!==1/0?e.endTime=n+l:n===1/0&&s!==-1/0?e.startTime=s+l:s!==-1/0&&n!==1/0&&(e.startTime=s+l,e.endTime=n+l)}})}startSelectingRange(e){this.selectingRange=!0,this.whenDoneSelectingRange=e}stopSelectingRange(){this.selectingRange=!1,this.whenDoneSelectingRange?.(),this.whenDoneSelectingRange=void 0,this.selectingRangeVisible&&(this.container.removeChild(this.selectingRangeElement),this.selectingRangeVisible=!1)}syncMaxValues(){return this.updateAllValueRanges(),this.on("time",()=>this.updateAllValueRanges())}syncMaxValuesForLayer(e){return this.updateValueRanges(e.yAxisGroup),e.model.on(()=>this.updateValueRanges(e.yAxisGroup))}updateAllValueRanges(){this.layers.filter(e=>e.visible).forEach(e=>{this.updateValueRanges(e.yAxisGroup,!0)}),this.renderYAxis()}updateValueRanges(e,t){this.updateValueRangesQueue.has(e)||this.updateValueRangesQueue.set(e,{lastUpdate:0,pending:void 0});const i=this.updateValueRangesQueue.get(e);if(Date.now()-i.lastUpdate<100)return i.pending&&clearTimeout(i.pending),void(i.pending=setTimeout(()=>{i.pending=void 0,this.updateValueRanges(e)},200));i.lastUpdate=Date.now();const s=new Map,n=new Map;this.layers.filter(e=>e.visible).forEach(e=>{const t=e.yAxis.group||e.id;s.has(t)||(s.set(t,-Number.MAX_VALUE),n.set(t,Number.MAX_VALUE));const i=e.model.getValueRange(this.getTimeRange());i.minValue<n.get(t)&&n.set(t,i.minValue),i.maxValue>s.get(t)&&s.set(t,i.maxValue)}),this.valueRanges.clear(),s.forEach((e,t)=>{this.valueRanges.set(t,{max:e,min:n.get(t)})}),t||this.renderYAxis(),this.emit("valueRanges",e)}renderYAxis(){const e=new Map;this.layers.filter(e=>e.visible).forEach(t=>{const i=t.yAxis.group||t.id;e.has(i)||e.set(i,{min:t.min,max:t.max,group:i}),e.set(i,{...e.get(i),...t.yAxis,min:t.min,max:t.max})});const t=[];e.forEach(e=>{if(e.visible){const i=this.valueRanges.get(e.group);i&&t.push({...e,minValue:i.min,maxValue:i.max})}}),this.yAxisTicks.render(t)}setTheme(e){this.theme=e,this.ticksBar.setDarkMode("dark"===e),this.engine?.setTheme(e)}addLayerLoader(e){this.loaders.add(e)}showStats(e){this.showingStats=e,this.engine?.showStats(e)}get engineReady(){return this._engineReady}whenReady(){return this._engineReady?Promise.resolve():new Promise(e=>{const t=this.on("ready",()=>{t(),e()})})}async setEngine(e){this._engineReady=!1,this.engine&&(this.layerUnloaders.forEach(e=>e()),this.layerUnloaders.clear(),this.engine.dispose()),this.initSliderContainer(),this.engine=e,this.engine.setTheme(this.theme),await this.engine.init(this.sliderElement),this.engine.setTheme(this.theme),this._engineReady=!0,this.emit("ready"),this.getVisibleLayers().forEach(e=>this.loadLayer(e)),this.engine.showStats(this.showingStats),this.engine.setTimeRange(this.getTimeRange()),this.engine.setValueRange(this.getValueRange()),this.engine.setSize(this.size.width,this.size.height)}initSliderContainer(){this.stopControls&&this.stopControls(),this.container?.removeChild(this.sliderElement);let e=0;this.showTicks&&(e+=24),this.showCurrent&&(e+=4),this.sliderElement=document.createElement("div"),this.sliderElement.oncontextmenu=()=>!1,this.sliderElement.tabIndex=0,this.sliderElement.style.top="0px",this.sliderElement.style.width="100%",this.sliderElement.style.outline="none",this.sliderElement.style.touchAction="none",this.sliderElement.style.height=`calc(100% - ${0+e}px)`,this.container?.appendChild(this.sliderElement),this.initSelectLabel(),this.stopControls=this.initControls(),this.onDestroy.push(()=>{this.container?.removeChild(this.sliderElement)})}get showCurrent(){return this._showCurrent}set showCurrent(e){if(e!==this._showCurrent){this._showCurrent=e,this.ticksBar.showLine=!this.showCurrent;let t=0,i=0;this.showTicks&&(i+=24),this.showCurrent&&(i+=4),this.sliderElement.style.height=`calc(100% - ${t+i}px)`}}async init(e,t){const i="string"==typeof e?document.getElementById(e):e;if(this.container=i,i){i.oncontextmenu=()=>!1;let e=0,s=0;if(this.showTicks){s+=24;const e=document.createElement("div");e.style.width="100%",e.style.height="24px",e.style.position="absolute",e.style.bottom="0px",e.style.touchAction="none",i.appendChild(e),this.ticksBar.init(e,e=>{const t=r(e.startTime,e.endTime);this.emit("tickclick",{startTime:e.startTime,endTime:e.endTime,unit:t}),this.fit({range:e,animate:1e3})}),this.ticksBar.showLine=!this.showCurrent}this.showCurrent&&(s+=4),this.sliderElement.oncontextmenu=()=>!1,this.sliderElement.tabIndex=0,this.sliderElement.style.top=`${e}px`,this.sliderElement.style.width="100%",this.sliderElement.style.outline="none",this.sliderElement.style.touchAction="none",this.sliderElement.style.height=`calc(100% - ${e+s}px)`,i.appendChild(this.sliderElement),this.yAxisTicks.canvas.style.top=`${e}px`,this.yAxisTicks.canvas.style.height=`calc(100% - ${e+s}px)`,i.appendChild(this.yAxisTicks.canvas),this.selectionOverlayContainer.style.position="absolute",this.selectionOverlayContainer.style.width="100%",this.selectionOverlayContainer.style.overflow="hidden",this.selectionOverlayContainer.style.pointerEvents="none",this.selectionOverlayContainer.style.top=`${e}px`,this.selectionOverlayContainer.style.height=`calc(100% - ${e+s}px)`,i.appendChild(this.selectionOverlayContainer),this.onDestroy.push(()=>i.removeChild(this.selectionOverlayContainer)),this.columnBandOverlayContainer.style.position="absolute",this.columnBandOverlayContainer.style.width="100%",this.columnBandOverlayContainer.style.overflow="hidden",this.columnBandOverlayContainer.style.pointerEvents="none",this.columnBandOverlayContainer.style.top=`${e}px`,this.columnBandOverlayContainer.style.height=`calc(100% - ${e+s}px)`,i.appendChild(this.columnBandOverlayContainer),this.onDestroy.push(()=>i.removeChild(this.columnBandOverlayContainer)),this.initHoverTooltip(),this.initSelectLabel(),this.setSize(this.sliderElement.clientWidth,this.sliderElement.clientHeight),this.syncSize(),this.setTimeRange($(t)),this.setValueRange($(t))}else console.warn(`Element ${e} not found`)}initSelectLabel(){this.selectedLabel.style.position="absolute",this.selectedLabel.style.padding="4px 8px",this.selectedLabel.style.background="rgba(0, 0, 0, 0.75)",this.selectedLabel.style.color="white",this.selectedLabel.style.fontSize="12px",this.selectedLabel.style.maxWidth="200px",this.selectedLabel.style.fontFamily="monospace",this.selectedLabel.style.borderRadius="4px",this.selectedLabel.style.pointerEvents="none",this.selectedLabel.style.display="none",this.selectedLabel.style.zIndex="10",this.sliderElement.appendChild(this.selectedLabel)}getLabel(e,t,i,s){if(t.labeler){const n=t.labeler(e,i,s);return null===n?null:"string"==typeof n?`<div>${n}</div>`:n?n.outerHTML:`<div>${e.name||e.id}</div>`}return`<div>${e.name||e.id}</div>`}getLayerById(e){return this.layers.find(t=>t.id===e)}select(e,t){this.stopSelectingRange(),this.stopUpdatingLabel?.();const i=()=>{this.updatingLabel=!1,this.stopUpdatingLabel?.(),this.stopUpdatingLabel=void 0,this.selectedLabel.style.display="none",this.layers.forEach(e=>e.select([])),this.selectedLayerId=void 0,this.emit("select",[])},s=e=>{this.layers.filter(t=>!e.some(e=>t.id===e.layer.id)).forEach(e=>e.select([])),e.forEach(e=>{e.layer.select(e.elements)}),this.emit("select",e)};if(t){s(this.getVisibleLayers().map(e=>{const i=e.model.dataInTimeRange(t);return{layer:e,elements:i}}).filter(e=>e.elements.length>0))}else if(e){const t=this.findElements(e,24);if(s(t.map(e=>({layer:e.layer,elements:e.elements})).flat()),1===t.length&&t[0].elements.length>0&&this.selectionOptions.label){const e=t[0].elements[0],s=t[0].layer;this.selectedLabel.innerHTML=this.getLabel(e,s,t[0].t,t[0].v)||"",this.selectedLabel.style.display="block";const n=this.selectedLabel.offsetWidth,l=this.selectedLabel.offsetHeight;this.selectedLayerId=s.id;const a=Array.isArray(e.t);this.updatingLabel=!0;const o=()=>{if(!this.updatingLabel)return;const{startTime:i,duration:s,endTime:o}=this.getTimeRange(),r=t[0].layer.model.get(e.id);if(r){const e=f(this.getTimeRange(),r.t);if(e){const o=this.getSliderBounds();let h=(.5*(e.startTime+e.endTime)-i)/s*o.width;const d="number"==typeof r.v?r.v:.5*(r.v[1]+r.v[0]);let m=this.modelValueToPixels(d,t[0].layer);a?m-=.5*l:m+=8;const c=.5*n,g=.5*l,u=o.width-.5*n,p=o.height-.5*l,y=Math.min(u,Math.max(c,h)),v=Math.min(p,Math.max(g,m));this.selectedLabel.style.display="block",this.selectedLabel.style.left=y-.5*n+"px",this.selectedLabel.style.top=`${v}px`}else this.selectedLabel.style.display="none"}else this.selectedLabel.style.display="none"};o();const r=s instanceof x&&s.histogram instanceof m;this.stopUpdatingLabel=this.on("time",r?i:o)}}else i()}listenToClicks(){let e=null;const t=t=>{e={x:t.clientX,y:t.clientY}},i=t=>{if(!e)return;const i=t.clientX-e.x,s=t.clientY-e.y;i*i+s*s<=25&&(this.stopSelectingRange(),this.select(e)),e=null},s=()=>{e=null};return this.sliderElement.addEventListener("pointerdown",t),this.sliderElement.addEventListener("pointerup",i),this.sliderElement.addEventListener("pointercancel",s),()=>{this.sliderElement.removeEventListener("pointerdown",t),this.sliderElement.removeEventListener("pointerup",i),this.sliderElement.removeEventListener("pointercancel",s)}}getSliderBounds(){return this.sliderElement.getBoundingClientRect()}mouseInSlider(e){const t=this.getSliderBounds(),i="x"in e?e:{x:e.clientX,y:e.clientY},s={x:i.x-t.left,y:i.y-t.top},n={x:s.x/t.width,y:-s.y/t.height+1},{startTime:l,duration:a}=this.getTimeRange(),o=l+n.x*a,{minValue:r,maxValue:h}=this.getValueRange();return{absolute:s,normalized:n,t:o,v:r+n.x*(h-r)}}pixelsToLayerValue(e,t){if(!e)return{yInLayer:0,toLayerHeight:1};const i="normalized"in e?e.normalized:this.mouseInSlider(e).normalized;let s=t.min;const n=t.max-s;return{yInLayer:(i.y-s)/n,toLayerHeight:n/this.getSliderBounds().height}}pixelsToModelValue(e,t){const{yInLayer:i,toLayerHeight:s}=this.pixelsToLayerValue(e,t);let n=0,l=100;if(t.model instanceof g){const e=this.valueRanges.get(t.yAxisGroup)||{min:0,max:1e3};n=e.min,l=e.max-n}return{yInModel:n+i*l,toModelHeight:s*l}}layerValueToPixels(e,t){let i=t.min;return(1-(i+(t.max-i)*e))*this.getSliderBounds().height}modelValueToPixels(e,t){let i=0,s=100;if(t.model instanceof g){const e=t.model.getValueRange(this.getTimeRange());i=e.minValue,s=e.maxValue-i}const n=(e-i)/s;return this.layerValueToPixels(n,t)}findElements(e,t){if("column"===this.selectionOptions.pick)return this.findColumnElements(e);const{width:i,height:s}=this.getSliderBounds(),{normalized:n}=this.mouseInSlider(e),{startTime:l,endTime:a,duration:o}=this.getTimeRange(),r=l+n.x*o,h=t||12,d=h/i*o,m={startTime:r-1,endTime:r+1},c={startTime:r-.5*d,endTime:r+.5*d};return this.getVisibleLayers().map(e=>{const{yInModel:t,toModelHeight:i}=this.pixelsToModelValue({normalized:n},e),s=e instanceof R?0:h*i,l=e instanceof R?m:c,a={minValue:t-.5*s,maxValue:t+.5*s},o=e.model.dataInRange({...l,...a});return{layer:e,elements:o,t:r,v:t}}).filter(e=>e.elements.length>0)}findColumnElements(e,t){const{width:i}=this.getSliderBounds(),{normalized:s}=this.mouseInSlider(e),{startTime:n,duration:l}=this.getTimeRange(),a=n+s.x*l,o=(t||12)/i*l,r={startTime:a-1,endTime:a+1},h={startTime:a-.5*o,endTime:a+.5*o};return this.getVisibleLayers().map(e=>{const{yInModel:t}=this.pixelsToModelValue({normalized:s},e),i=e instanceof R?r:h,n=e.model.dataInTimeRange(i);return{layer:e,elements:n,t:a,v:t}}).filter(e=>e.elements.length>0)}clearHoverEvent(){this.hoverCleared||(this.hoverCleared=!0,this.renderColumnHoverBand([]),this.emit("hover",null))}updateHover(e){if(this.dragging)return this.hoverLine.style.display="none",this.toolTip.style.display="none",void this.clearHoverEvent();if(void 0!==e&&(this.mouse=e),this.mouse){const e=this.getSliderBounds(),{normalized:t}=this.mouseInSlider(this.mouse),{startTime:i,endTime:n,duration:l}=this.getTimeRange(),a=i+t.x*l,o=this.findElements(this.mouse);this.renderColumnHoverBand(o),this.hoverCleared=!1,this.emit("hover",{elements:o.map(e=>({layer:e.layer,elements:e.elements})),t:a,clientX:this.mouse.x,clientY:this.mouse.y});const r=o.map(e=>e.elements.map(t=>({e:t,l:e.layer,t:e.t,v:e.v}))).flat();let h;if(r.length>0)if(r.length>3){h=r.slice(0,2).map(e=>this.getLabel(e.e,e.l,e.t,e.v)).flat().filter(e=>null!==e).join(""),h+=`<div>And ${r.length-2} more...</div>`}else{h=o.map(e=>e.elements.map(t=>this.getLabel(t,e.layer,e.t,e.v))).flat().filter(e=>null!==e).join("")}if(!1===this.hoverOptions.tooltip)this.toolTip.style.display="none";else{const t=new Date(a),i=t.getHours(),n=t.getMinutes(),l=t.getSeconds(),o=s(a,!0,this._locale),r=`${(i<10?"0":"")+i}:${(n<10?"0":"")+n}:${(l<10?"0":"")+l}`;let d="";const m=this.ticksBar.cache.high.spacing;(void 0===this.hoverOptions.date?m>=V:this.hoverOptions.date)&&(d+=`<div>${o}</div>`),(void 0===this.hoverOptions.time?m<=C:this.hoverOptions.time)&&(d+=`<div>${r}</div>`),h&&(d+=h),this.toolTip.innerHTML=d,this.toolTip.style.display=d.length>0?"block":"none";const c=88,g=36;let u=this.mouse.x+10,p=this.mouse.y+10;const y=e.left+e.width-c-5,v=e.top+e.height-g-5;u>y&&(u=y),p>v&&(p=v),this.toolTip.style.left=`${u}px`,this.toolTip.style.top=`${p}px`}}else this.hoverLine.style.display="none",this.toolTip.style.display="none",this.clearHoverEvent()}initHoverTooltip(){this.toolTip.style.position="absolute",this.toolTip.style.padding="4px 8px",this.toolTip.style.background="rgba(0, 0, 0, 0.75)",this.toolTip.style.color="white",this.toolTip.style.fontSize="12px",this.toolTip.style.fontFamily="monospace",this.toolTip.style.borderRadius="4px",this.toolTip.style.pointerEvents="none",this.toolTip.style.display="none",this.toolTip.style.zIndex="10",this.toolTip.style.overflow="hidden",document.body.appendChild(this.toolTip)}initHoverListener(){const e=()=>{this.updateHover(null)},t=e=>{this.updateHover({x:e.clientX,y:e.clientY})};this.sliderElement.addEventListener("mouseleave",e),this.sliderElement.addEventListener("mousemove",t);const i=this.listenToClicks();return()=>{this.sliderElement.removeEventListener("mouseleave",e),this.sliderElement.removeEventListener("mousemove",t),i()}}syncSize(){const e=()=>{const{offsetWidth:e,offsetHeight:t}=this.sliderElement;this.setSize(e,t)},t=new ResizeObserver(()=>{e()});this.container&&(t.observe(this.container),e()),this.onDestroy.push(()=>{t.disconnect()})}getTimeRange(){return u(this.range.time)}getValueRange(){return this.range.value}setTimeRange(e,t){const i=this.getTimeRange(),s=y(i,e),n=this._limits?v(s,this._limits):s;n.startTime===i.startTime&&n.endTime===i.endTime||(this.range.time=n,this.engine?.setTimeRange(n),this.showTicks&&this.ticksBar.setTimeRange(n),this.emit("time",n),this.updateHover())}setValueRange(e){const t={...this.getValueRange(),...e};this.range.value=t,this.engine?.setValueRange(t),this.emit("value",this.getValueRange()),this.updateHover()}setSize(e,t){this.size={width:e,height:t},this.showTicks&&this.ticksBar.setWidth(e);const i=this.getTimeRange(),s=this.getValueRange();this.engine?.setSize(e,t),this.setTimeRange(i),this.setValueRange(s),this.updateHover(),this.emit("size",{width:e,height:t})}up(e){const{startTime:t,endTime:i,duration:s}=this.getTimeRange();let n={startTime:0,endTime:Date.now()};const l=.5*(t+i);if(s>=.9*S){const e=U(10*s);n=o(l,e)}else{const e=[{threshold:b,unit:"millennium"},{threshold:w,unit:"century"},{threshold:z,unit:"decade"},{threshold:.9*M,unit:"year"},{threshold:D,unit:"month"},{threshold:C,unit:"week"},{threshold:V,unit:"day"},{threshold:k,unit:"hour"},{threshold:B,unit:"minute"},{threshold:-1,unit:"second"}];let t=0;for(;s<.9*e[t].threshold;)t++;const i=e[t].unit;n=h(l,i)}this.fit({...e,range:n})}down(e){const{startTime:t,endTime:i,duration:s}=this.getTimeRange();let n={startTime:0,endTime:Date.now()};const l=t+("number"==typeof e?.xRatio?e.xRatio:.5)*s;if(s>=.9*S){const e=U(s/10);n=o(l,e)}else{let e=0;const t=[{threshold:S,unit:"century"},{threshold:b,unit:"decade"},{threshold:w,unit:"year"},{threshold:z,unit:"month"},{threshold:1.1*M,unit:"week"},{threshold:D,unit:"day"},{threshold:C,unit:"hour"},{threshold:V,unit:"minute"},{threshold:k,unit:"second"}].reverse();for(;s>1.1*t[e].threshold;)e++;const i=t[e].unit;n=h(l,i)}this.fit({...e,range:n})}next(e){this.skip(1,e)}previous(e){this.skip(-1,e)}skip(e,t){let i={startTime:0,endTime:Date.now()};const{startTime:s,endTime:n,duration:l}=this.getTimeRange(),a=.5*(s+n);if(l>=9*S){const e=U(l);i=o(a,e)}else{const t=r(s,n);i=t?h(a,t,Math.round(e)):{startTime:s+e*l,endTime:n+e*l}}this.fit({...t,range:i})}getTimeRangeLabel(){const{startTime:e,endTime:t}=this.getTimeRange(),i=new Date(e);return 0===i.getHours()&&0===i.getMinutes()&&0===i.getSeconds()&&0===i.getMilliseconds()?n([e,t],this._locale):void 0}cancelFit(){this.stopFit?.(),this.stopFit=void 0}fit(e){this.cancelFit();const t=e?.range||this.getLayersTimeRange(),s=e?.padding?p(t,e.padding):t;if(e?.animate){const t=this.getTimeRange();this.stopFit=i(t.startTime,t.endTime,s.startTime,s.endTime,e.animate,(e,t)=>this.setTimeRange({startTime:e,endTime:t}))}else this.setTimeRange(s)}getLayersTimeRange(){if(0===this.getVisibleLayers().length)return I;{let e=this.getVisibleLayers()[0].model.getTimeRange();return this.getVisibleLayers().slice(1).forEach(t=>e=E(e,t.model.getTimeRange())),e}}loadLayer(e){if(e.timeSlider&&e.timeSlider.id!==this.id)console.warn("Layer already has been loaded by another time slider, create a new layer with the same model and style if you want to add it to another time slider");else if(this.engine&&this._engineReady&&!this.layerUnloaders.has(e.id)){const t=[...this.loaders].filter(e=>this.engine instanceof e.engineClass).find(t=>t.canLoad(e));if(t){const i=Date.now(),s=t.load(e,this.engine.scene,this.engine,this);e.timeSlider=this,e.loaded=!0;const n=e.name||e.constructor.name+"#"+e.id.slice(e.id.length-4).toUpperCase();console.log(`Loaded ${n} in ${l(Date.now()-i)}`);const a=this.syncMaxValuesForLayer(e);this.layerLoaders.set(e.id,t),this.layerUnloaders.set(e.id,()=>{a(),s(),this.layerLoaders.delete(e.id),e.loaded=!1})}else console.warn("No loader found for",{layer:e})}}unloadLayer(e){this.selectedLayerId===e.id&&this.select(null),this.layerUnloaders.has(e.id)&&(this.layerUnloaders.get(e.id)(),this.layerUnloaders.delete(e.id))}addLayer(e){if(this.layers.push(e),e.visible){this.loadLayer(e);const t=e.model.getTimeRange();if(1===this.getVisibleLayers().length)this.setTimeRange(t);else{const e=E(this.getTimeRange(),t);this.setTimeRange(e)}}const t=[e.on("visible",()=>{e.visible?this.loadLayer(e):this.unloadLayer(e),this.updateAllValueRanges()}),e.on("min",()=>this.onLayerBandChange(e)),e.on("max",()=>this.onLayerBandChange(e))];this.layerListenerStoppers.set(e.id,()=>t.forEach(e=>e()))}onLayerBandChange(e){const t=this.layerLoaders.get(e.id);t&&!t.followsLayerBand&&(this.layerUnloaders.get(e.id)?.(),this.layerUnloaders.delete(e.id),this.loadLayer(e)),this.updateAllValueRanges()}removeLayer(e){const t="string"==typeof e?e:e.id,i=this.layers.find(e=>e.id===t);i&&(this.unloadLayer(i),this.layerUnloaders.delete(t),this.layerListenerStoppers.get(t)?.(),this.layerListenerStoppers.delete(t),this.layers=this.layers.filter(e=>e.id!==t))}destroy(){this.layers.map(e=>e.id).forEach(e=>this.removeLayer(e)),this.onDestroy.forEach(e=>e())}addHorizontalPinchZoom(){let e=null,t=null;const i=()=>{this.pinching=!1,e=null,t=null},s=i=>{if(2===i.touches.length){i.preventDefault(),this.dragging=!1,this.pinching=!0;const s=this.mouseInSlider(i.touches[0]).t,n=this.mouseInSlider(i.touches[1]).t;e=Math.min(s,n),t=Math.max(s,n)}},n=s=>{if(2===s.touches.length){if(null===e||null===t)return;s.preventDefault(),this.dragging=!1;const i=this.mouseInSlider(s.touches[0]).normalized.x,n=this.mouseInSlider(s.touches[1]).normalized.x,l=Math.min(i,n),a=Math.max(i,n),o=(t-e)/(a-l);let r=e-l*o,h=t+(1-a)*o;if(o>_){const e=.5*(r+h);r=e-.5*_,h=e+.5*_}if(o<H){const e=.5*(r+h);r=e-.5*H,h=e+.5*H}this.setTimeRange({startTime:r,endTime:h})}else i()},l=()=>{i()};this.sliderElement.addEventListener("touchstart",s,{passive:!1}),this.sliderElement.addEventListener("touchmove",n,{passive:!1}),this.sliderElement.addEventListener("touchend",l),this.sliderElement.addEventListener("touchcancel",l),this.onDestroy.push(()=>{this.sliderElement.removeEventListener("touchstart",s),this.sliderElement.removeEventListener("touchmove",n),this.sliderElement.removeEventListener("touchend",l),this.sliderElement.removeEventListener("touchcancel",l)})}initControls(){const e=new t;this.dragging=!1;let i,s=0,n=0,l=0;e.add(this.initHoverListener());const a=e=>{this.sliderElement.focus(),e.preventDefault();const t=this.mouseInSlider(e);this.zoom(.001*e.deltaY,{x:t.normalized.x})};let o=0,r=-1;const h=e=>{const t=Date.now(),i=t-o;r>=0&&i<300&&i>0&&(this.select(null),e.preventDefault(),this.zoom(-.75,{animate:1e3,x:r})),o=t},d=e=>{e.preventDefault(),this.select(null);const t=this.mouseInSlider(e);this.zoom(-.75,{animate:1e3,x:t.normalized.x})};this.selectingRangeElement.style.height="calc(100% - 6px)",this.selectingRangeElement.style.pointerEvents="none",this.selectingRangeElement.style.position="absolute",this.selectingRangeElement.style.border="3px solid #df0",this.selectingRangeElement.style.background="#df04",this.selectingRangeElement.style.top="0px";const m=e=>{if(this.sliderElement.focus(),2===e.button||0===e.button){e.preventDefault();const t=this.mouseInSlider(e),i=t.normalized.x,{startTime:a,duration:o}=this.getTimeRange();s=a+i*o,n=Date.now(),l=t.absolute.x,(e.ctrlKey||2===e.button)&&(this.selectingRange=!0),this.selectingRange?(this.selectingRangeElement.style.left=t.absolute.x+"px",this.selectingRangeElement.style.width="0px",this.container.appendChild(this.selectingRangeElement),this.selectingRangeVisible=!0):this.dragging=!0}},c=e=>{const t=this.mouseInSlider(e);return i=t.normalized.x,t},g=e=>{const t=c(e);if(this.selectingRange){const e=Math.abs(l-t.absolute.x),i=Math.min(l,t.absolute.x);this.selectingRangeElement.style.left=i+"px",this.selectingRangeElement.style.width=e-6+"px"}if(!this.dragging||Date.now()-n<100&&Math.abs(l-t.absolute.x)<10)return;e.preventDefault();const i=t.normalized.x,{startTime:a,endTime:o}=this.getTimeRange(),r=a+i*(o-a)-s;this.setTimeRange({startTime:a-r,endTime:o-r})},u=e=>{const t=this.getSliderBounds(),n=t.height-(e.clientY-t.top);if(!this.dragging&&!this.pinching&&n<8)this.ticksBar.click(e);else if(i=void 0,this.dragging=!1,this.selectingRange){const t=this.mouseInSlider(e).normalized.x,{startTime:i,endTime:n}=this.getTimeRange(),l=i+t*(n-i);"zoom"===this.selectRangeMode&&this.fit({range:{startTime:Math.min(s,l),endTime:Math.max(s,l)},animate:1e3}),"select"===this.selectRangeMode&&this.select(null,{startTime:Math.min(s,l),endTime:Math.max(s,l)}),"createSelection"===this.selectRangeMode&&this.setSelection([...this.getSelection(),{startTime:Math.min(s,l),endTime:Math.max(s,l)}])}this.stopSelectingRange()},p=e=>{this.pressedKeys.add(e.code)},y=e=>{this.pressedKeys.delete(e.code),"Space"===e.code&&(e.preventDefault(),this.togglePlaying()),"KeyF"===e.code&&(e.preventDefault(),this.fit({animate:3e3}));const t=void 0;"ArrowRight"===e.code&&(e.preventDefault(),this.skip(1,{animate:t})),"ArrowLeft"===e.code&&(e.preventDefault(),this.skip(-1,{animate:t})),"ArrowUp"===e.code&&(e.preventDefault(),this.up({animate:t})),"ArrowDown"===e.code&&(e.preventDefault(),this.down({xRatio:i,animate:t}))};let v=!0;const T=()=>{if(v){const e=this.pressedKeys.has("ShiftLeft")?.05:.01,t=2*e,s=this.pressedKeys.has("KeyD"),n=this.pressedKeys.has("KeyA");s&&this.shift(-e),n&&this.shift(e),this.pressedKeys.has("KeyW")&&this.zoom(-t,{x:s||n?void 0:i}),this.pressedKeys.has("KeyS")&&this.zoom(t,{x:s||n?void 0:i}),requestAnimationFrame(T)}};T(),e.add(()=>v=!1);const f=e=>e.preventDefault();this.sliderElement.addEventListener("contextmenu",f),this.sliderElement.addEventListener("wheel",a),this.sliderElement.addEventListener("pointerdown",m),this.sliderElement.addEventListener("pointermove",g),this.sliderElement.addEventListener("pointerup",u),this.sliderElement.addEventListener("dblclick",d),this.sliderElement.addEventListener("touchend",h),this.sliderElement.addEventListener("touchstart",e=>{if(1===e.touches.length){const t=this.mouseInSlider(e.touches[0]);r=t.normalized.x}else r=-1}),this.sliderElement.addEventListener("keydown",p),this.sliderElement.addEventListener("keyup",y),this.addHorizontalPinchZoom();const E=()=>{this.sliderElement.removeEventListener("contextmenu",f),this.sliderElement.removeEventListener("wheel",a),this.sliderElement.removeEventListener("pointerdown",m),this.sliderElement.removeEventListener("pointermove",g),this.sliderElement.removeEventListener("pointerup",u),this.sliderElement.removeEventListener("dblclick",d),this.sliderElement.removeEventListener("touchend",h),this.sliderElement.removeEventListener("keydown",p),this.sliderElement.removeEventListener("keyup",y)};return this.onDestroy.push(E),e.add(E),e.disposeLater()}shift(e,t){const{startTime:i,endTime:s,duration:n}=this.getTimeRange(),l=t?.absolute?e:e*n;this.fit({...t,range:{startTime:i-l,endTime:s-l}})}zoom(e,t){const i="number"==typeof t?.x?t.x:.5,{startTime:s,endTime:n,duration:l}=this.getTimeRange(),a={startTime:s-e*l*i,endTime:n+e*l*(1-i)},o=a.endTime-a.startTime,r=a.startTime+.5*o;o>_&&(a.startTime=r-.5*_,a.endTime=r+.5*_),o<H&&(a.startTime=r-.5*H,a.endTime=r+.5*H),this.fit({range:a,animate:t?.animate})}togglePlaying(){this.playing?this.pause():this.play()}isPlaying(){return this.playing}play(){if(this.playing)return;this.playing=!0,this.emit("playing",!0);let e=Date.now();const t=()=>{if(this.playing){if(this.live){const{duration:e}=this.getTimeRange(),t=Date.now(),i=10/this.size.width;this.setTimeRange({startTime:t-(1-i)*e,endTime:t+i*e}),this.setCurrent(t)}else if("auto"!==this.playSpeed||this.showCurrent){const t=Date.now(),i=t-e,s=this.current-this.getTimeRange().startTime,n="auto"===this.playSpeed?1:this.playSpeed;this.shift(-n*i,{absolute:!0}),this.setCurrent(this.getTimeRange().startTime+s),e=t}else{const t=Date.now();let i=5e-5*(t-e);this.pressedKeys.has("ShiftLeft")&&(i*=5);const s=this.current-this.getTimeRange().startTime;this.shift(-i),this.setCurrent(this.getTimeRange().startTime+s),e=t}requestAnimationFrame(t)}};t()}setCurrent(e){this.current!==e&&(Math.abs(e-Date.now())>100&&this.live&&(this.pause(),this.setLive(!1)),this.current=e,this.emit("current",e))}pause(){this.playing&&(this.playing=!1,this.emit("playing",!1),this.setLive(!1))}setLive(e){if(this.live!==e){if(this.live=e,e){const e=this.getTimeRange();this.fit({range:{startTime:e.endTime-this.liveRange,endTime:e.endTime},animate:B}),this.play()}this.emit("live",e)}}}function $(e){return{startTime:"number"==typeof e?.startTime?e.startTime:"number"==typeof e?.endTime?e.duration?e.endTime-e.duration:e.endTime-C:e?.duration?Date.now()-.5*e.duration:Date.now()-.5*C,endTime:"number"==typeof e?.endTime?e.endTime:"number"==typeof e?.startTime?e.duration?e.startTime+e.duration:e.startTime+C:e?.duration?Date.now()+.5*e.duration:Date.now()+.5*C,duration:e?.duration?e.duration:"number"==typeof e?.startTime&&"number"==typeof e?.endTime?e.endTime+e.startTime:C,minValue:"number"==typeof e?.minValue?e.minValue:"number"==typeof e?.maxValue?e.maxValue>0?0:e.maxValue-100:0,maxValue:"number"==typeof e?.maxValue?e.maxValue:"number"==typeof e?.minValue?e.minValue<0?0:e.minValue+100:100}}function U(e){const t=e/315576e5,i=Math.log10(t),s=Math.ceil(i);return Math.pow(10,s)}
@@ -1 +1 @@
1
- import{TypedEventEmitter as e}from"../event/TypedEventEmitter";import{TODAY as t}from"../ticks/TimeSliderConstants";import{addDuration as i}from"../data/TimeSliderRange";export class TimeSliderEngine extends e{constructor(e){super(),this.scene=e,this.timeRange=t,this.valueRange={minValue:0,maxValue:100},this.size={width:1e3,height:100},this.theme="dark"}setTheme(e){this.theme=e,this.setTimeRange(this.timeRange)}getTimeRange(){return{...this.timeRange,duration:this.timeRange.endTime-this.timeRange.startTime}}getValueRange(){return this.valueRange}getSize(){return this.size}showStats(e){}dispose(){this.destroy(),this.size={width:1e3,height:100}}setTimeRange(e){if(e.startTime!==this.timeRange.startTime||e.endTime!==this.timeRange.endTime){this.timeRange=e;const t=i(e);this.updateTimeRange(t),this.emit("time",t)}}setValueRange(e){e.minValue===this.valueRange.minValue&&e.maxValue===this.valueRange.maxValue||(this.valueRange=e,this.updateValueRange(e),this.emit("value",e))}setSize(e,t){this.size.width===e&&this.size.height===t||(this.size={width:e,height:t},this.updateSize(e,t),this.emit("size",this.size))}}
1
+ import{TypedEventEmitter as e}from"../event/TypedEventEmitter.js";import{TODAY as t}from"../ticks/TimeSliderConstants.js";import{addDuration as i}from"../data/TimeSliderRange.js";export class TimeSliderEngine extends e{constructor(e){super(),this.scene=e,this.timeRange=t,this.valueRange={minValue:0,maxValue:100},this.size={width:1e3,height:100},this.theme="dark"}setTheme(e){this.theme=e,this.setTimeRange(this.timeRange)}getTimeRange(){return{...this.timeRange,duration:this.timeRange.endTime-this.timeRange.startTime}}getValueRange(){return this.valueRange}getSize(){return this.size}showStats(e){}dispose(){this.destroy(),this.size={width:1e3,height:100}}setTimeRange(e){if(e.startTime!==this.timeRange.startTime||e.endTime!==this.timeRange.endTime){this.timeRange=e;const t=i(e);this.updateTimeRange(t),this.emit("time",t)}}setValueRange(e){e.minValue===this.valueRange.minValue&&e.maxValue===this.valueRange.maxValue||(this.valueRange=e,this.updateValueRange(e),this.emit("value",e))}setSize(e,t){this.size.width===e&&this.size.height===t||(this.size={width:e,height:t},this.updateSize(e,t),this.emit("size",this.size))}}
package/index.d.ts CHANGED
@@ -1 +1,62 @@
1
- import './index.css';
1
+ export * from './engine/TimeSlider';
2
+ export * from './engine/TimeSliderEngine';
3
+ export * from './engine/PinchZoom';
4
+ export * from './engine/HorizontalPinchZoom';
5
+ export * from './three/ThreeTimeSlider';
6
+ export * from './three/ThreeTimeSliderEngine';
7
+ export * from './three/Three3DTimeSliderEngine';
8
+ export * from './three/react/ReactThreeTimeSlider';
9
+ export * from './three/layer/ThreeTimeLayerLoader';
10
+ export * from './three/layer/ThreePointsTimeLayerLoader';
11
+ export * from './three/layer/ThreeIntervalsTimeLayerLoader';
12
+ export * from './three/layer/Three3DPointsTimeLayerLoader';
13
+ export * from './three/layer/Three3DIntervalsTimeLayerLoader';
14
+ export * from './react/ReactTimeSlider';
15
+ export * from './react/ColoredSlider';
16
+ export { ColoredSliderExtendsInput } from './react/ColoredSliderExtendsInput';
17
+ export type { ColoredSliderInputElement } from './react/ColoredSliderExtendsInput';
18
+ export * from './react/FullscreenButton';
19
+ export * from './react/MaterialIconButton';
20
+ export * from './react/MaterialTextButton';
21
+ export * from './react/DateLabelWithPicker';
22
+ export * from './react/TimeLabelWithPicker';
23
+ export * from './react/DateRangeLabelWithPicker';
24
+ export * from './react/YearScroller';
25
+ export * from './react/PointerClick';
26
+ export * from './react/PinchZoomHook';
27
+ export * from './react/DeepMemoHook';
28
+ export * from './data/TimeSliderElement';
29
+ export * from './data/TimeSliderModel';
30
+ export * from './data/TimeSliderPointsModel';
31
+ export * from './data/TimeSliderIntervalsModel';
32
+ export * from './data/CompositeTimeSliderModel';
33
+ export * from './data/TimeSliderRange';
34
+ export * from './data/TimeSliderBush';
35
+ export * from './data/IntervalLaneManager';
36
+ export * from './data/TimeSliderLanesModel';
37
+ export * from './data/histogram/TimeSliderHistogram';
38
+ export * from './data/histogram/TimeSliderFixedHistogram';
39
+ export * from './data/histogram/TimeSliderDynamicHistogram';
40
+ export * from './data/histogram/TimeSliderSplittingFixedHistogram';
41
+ export * from './layer/TimeSliderLayer';
42
+ export * from './layer/TimeSliderLayerLoader';
43
+ export * from './layer/TimeSliderPointsLayer';
44
+ export * from './layer/TimeSliderIntervalsLayer';
45
+ export * from './layer/TimeSliderHistogramLayer';
46
+ export * from './style/TimeSliderStyle';
47
+ export * from './style/TimeSliderStyler';
48
+ export * from './style/TimeSliderColors';
49
+ export * from './style/TimeSliderLabeler';
50
+ export * from './style/TimeSliderPointsStyle';
51
+ export * from './style/TimeSliderIntervalsStyle';
52
+ export * from './style/TimeSliderHistogramStyle';
53
+ export * from './ticks/TimeSliderConstants';
54
+ export * from './ticks/TimeTicksBar';
55
+ export * from './ticks/YAxisTicks';
56
+ export * from './common/TimeTools';
57
+ export * from './common/Easing';
58
+ export * from './common/Clamper';
59
+ export * from './common/Disposables';
60
+ export * from './common/Expand';
61
+ export * from './common/GlslTools';
62
+ export * from './event/TypedEventEmitter';
package/index.js CHANGED
@@ -1 +1 @@
1
- import e from"react";import*as t from"react-dom/client";import{TimeSliderDemo as r}from"./TimeSliderDemo";import"./index.css";t.createRoot(function(){const e=document.createElement("protovice");return document.body.appendChild(e),e}()).render(e.createElement(function(){return e.createElement("div",{id:"app"},e.createElement(r,null))},null));
1
+ export*from"./engine/TimeSlider.js";export*from"./engine/TimeSliderEngine.js";export*from"./engine/PinchZoom.js";export*from"./engine/HorizontalPinchZoom.js";export*from"./three/ThreeTimeSlider.js";export*from"./three/ThreeTimeSliderEngine.js";export*from"./three/Three3DTimeSliderEngine.js";export*from"./three/react/ReactThreeTimeSlider.js";export*from"./three/layer/ThreeTimeLayerLoader.js";export*from"./three/layer/ThreePointsTimeLayerLoader.js";export*from"./three/layer/ThreeIntervalsTimeLayerLoader.js";export*from"./three/layer/Three3DPointsTimeLayerLoader.js";export*from"./three/layer/Three3DIntervalsTimeLayerLoader.js";export*from"./react/ReactTimeSlider.js";export*from"./react/ColoredSlider.js";export{ColoredSliderExtendsInput}from"./react/ColoredSliderExtendsInput.js";export*from"./react/FullscreenButton.js";export*from"./react/MaterialIconButton.js";export*from"./react/MaterialTextButton.js";export*from"./react/DateLabelWithPicker.js";export*from"./react/TimeLabelWithPicker.js";export*from"./react/DateRangeLabelWithPicker.js";export*from"./react/YearScroller.js";export*from"./react/PointerClick.js";export*from"./react/PinchZoomHook.js";export*from"./react/DeepMemoHook.js";export*from"./data/TimeSliderElement.js";export*from"./data/TimeSliderModel.js";export*from"./data/TimeSliderPointsModel.js";export*from"./data/TimeSliderIntervalsModel.js";export*from"./data/CompositeTimeSliderModel.js";export*from"./data/TimeSliderRange.js";export*from"./data/TimeSliderBush.js";export*from"./data/IntervalLaneManager.js";export*from"./data/TimeSliderLanesModel.js";export*from"./data/histogram/TimeSliderHistogram.js";export*from"./data/histogram/TimeSliderFixedHistogram.js";export*from"./data/histogram/TimeSliderDynamicHistogram.js";export*from"./data/histogram/TimeSliderSplittingFixedHistogram.js";export*from"./layer/TimeSliderLayer.js";export*from"./layer/TimeSliderLayerLoader.js";export*from"./layer/TimeSliderPointsLayer.js";export*from"./layer/TimeSliderIntervalsLayer.js";export*from"./layer/TimeSliderHistogramLayer.js";export*from"./style/TimeSliderStyle.js";export*from"./style/TimeSliderStyler.js";export*from"./style/TimeSliderColors.js";export*from"./style/TimeSliderLabeler.js";export*from"./style/TimeSliderPointsStyle.js";export*from"./style/TimeSliderIntervalsStyle.js";export*from"./style/TimeSliderHistogramStyle.js";export*from"./ticks/TimeSliderConstants.js";export*from"./ticks/TimeTicksBar.js";export*from"./ticks/YAxisTicks.js";export*from"./common/TimeTools.js";export*from"./common/Easing.js";export*from"./common/Clamper.js";export*from"./common/Disposables.js";export*from"./common/Expand.js";export*from"./common/GlslTools.js";export*from"./event/TypedEventEmitter.js";
@@ -1 +1 @@
1
- import{Disposables as s}from"../common/Disposables";import{TimeSliderDynamicHistogram as i}from"../data/histogram/TimeSliderDynamicHistogram";import{TimeSliderSplittingFixedHistogram as t}from"../data/histogram/TimeSliderSplittingFixedHistogram";import{TimeSliderIntervalsModel as e}from"../data/TimeSliderIntervalsModel";import{TimeSliderIntervalsLayer as a}from"./TimeSliderIntervalsLayer";export class TimeSliderHistogramLayer extends a{constructor(i,t){super(new e,t),this.content=i,this.d=new s;const a=this.createHistogram({classifier:t?.classifier,...t?.style});this.histogram=a,this.maxClassifications=t?.maxClassifications,this._classificationColors=t?.classificationColors||[],t?.classificationIsColor&&!this.fixedBoxes&&(this.styler=s=>{const i=s.attributes?.classification;return i?{fill:{color:i},border:{color:i}}:void 0}),t?.classifier&&!t.labeler&&(this.fixedBoxes?t.classificationIsColor?this.labeler=(s,i,t)=>Math.abs(s.v[0]-s.v[1])+" TODO use split":this.labeler=s=>{const i=Math.abs(s.v[0]-s.v[1]);return s.attributes?.classification+": "+i+" TODO use split"}:t.classificationIsColor?this.labeler=(s,i,t)=>Math.abs(s.v[0]-s.v[1])+"":this.labeler=s=>{const i=Math.abs(s.v[0]-s.v[1]);return s.attributes?.classification+": "+i}),this.d.add(this.on("loaded",s=>{s?a.start(this.timeSlider):a.stop()})),this.d.add(this.on("invalidateAll",()=>{a.average=!0===this.style.average,a.weighted=!0===this.style.weighted,a.inverted=!0===this.style.inverted,this.style.mode&&(a.mode=this.style.mode),a.classifier=this.style.classifier,this.style.classOrder&&(a.classOrder=this.style.classOrder)}))}getClassification(s,i){const t=s.v[1]-s.v[0],e=s.attributes?.splits||[1],a=i/t;let o=0;for(let s=0;s<e.length;s++)if(o+=e[s],a<o)return this.histogram.classOrder[s]}set classificationColors(s){this._classificationColors=s,this.invalidateAll()}get classificationColors(){return this._classificationColors}createHistogram(s){return this.fixedBoxes?new t(this.model,this.content,s):new i(this.model,this.content,s)}get fixedBoxes(){return void 0!==this.style.mode?.fixed||void 0!==this.style.mode?.fixedUnit}dispose(){this.model.clear(),this.d.dispose()}getDefaultStyle(){return{}}}
1
+ import{Disposables as s}from"../common/Disposables.js";import{TimeSliderDynamicHistogram as i}from"../data/histogram/TimeSliderDynamicHistogram.js";import{TimeSliderSplittingFixedHistogram as t}from"../data/histogram/TimeSliderSplittingFixedHistogram.js";import{TimeSliderIntervalsModel as e}from"../data/TimeSliderIntervalsModel.js";import{TimeSliderIntervalsLayer as a}from"./TimeSliderIntervalsLayer.js";export class TimeSliderHistogramLayer extends a{constructor(i,t){super(new e,t),this.content=i,this.d=new s;const a=this.createHistogram({classifier:t?.classifier,...t?.style});this.histogram=a,this.maxClassifications=t?.maxClassifications,this._classificationColors=t?.classificationColors||[],t?.classificationIsColor&&!this.fixedBoxes&&(this.styler=s=>{const i=s.attributes?.classification;return i?{fill:{color:i},border:{color:i}}:void 0}),t?.classifier&&!t.labeler&&(this.fixedBoxes?t.classificationIsColor?this.labeler=(s,i,t)=>Math.abs(s.v[0]-s.v[1])+" TODO use split":this.labeler=s=>{const i=Math.abs(s.v[0]-s.v[1]);return s.attributes?.classification+": "+i+" TODO use split"}:t.classificationIsColor?this.labeler=(s,i,t)=>Math.abs(s.v[0]-s.v[1])+"":this.labeler=s=>{const i=Math.abs(s.v[0]-s.v[1]);return s.attributes?.classification+": "+i}),this.d.add(this.on("loaded",s=>{s?a.start(this.timeSlider):a.stop()})),this.d.add(this.on("invalidateAll",()=>{a.average=!0===this.style.average,a.weighted=!0===this.style.weighted,a.inverted=!0===this.style.inverted,this.style.mode&&(a.mode=this.style.mode),a.classifier=this.style.classifier,this.style.classOrder&&(a.classOrder=this.style.classOrder)}))}getClassification(s,i){const t=s.v[1]-s.v[0],e=s.attributes?.splits||[1],a=i/t;let o=0;for(let s=0;s<e.length;s++)if(o+=e[s],a<o)return this.histogram.classOrder[s]}set classificationColors(s){this._classificationColors=s,this.invalidateAll()}get classificationColors(){return this._classificationColors}createHistogram(s){return this.fixedBoxes?new t(this.model,this.content,s):new i(this.model,this.content,s)}get fixedBoxes(){return void 0!==this.style.mode?.fixed||void 0!==this.style.mode?.fixedUnit}dispose(){this.model.clear(),this.d.dispose()}getDefaultStyle(){return{}}}
@@ -1 +1 @@
1
- import{Disposables as t}from"../common/Disposables";import{TimeSliderDynamicHistogram as e}from"../data/histogram/TimeSliderDynamicHistogram";import{TimeSliderFixedHistogram as s}from"../data/histogram/TimeSliderFixedHistogram";import{TimeSliderIntervalsModel as i}from"../data/TimeSliderIntervalsModel";import{TimeSliderIntervalsLayer as r}from"./TimeSliderIntervalsLayer";export class TimeSliderHistogramLayerOld extends r{constructor(e,s){super(new i,s),this.content=e,this.d=new t;const r=this.createHistogram({classifier:s?.classifier,...s?.style});this.histogram=r,s?.classifier&&!s.labeler&&(s.classificationIsColor?this.labeler=t=>Math.abs(t.v[0]-t.v[1])+"":this.labeler=t=>{const e=Math.abs(t.v[0]-t.v[1]);return t.attributes?.classification+": "+e}),s?.classificationIsColor&&(this.styler=t=>{const e=t.attributes?.classification;return e?{fill:{color:e},border:{color:e}}:void 0}),this.d.add(this.on("loaded",t=>{t?r.start(this.timeSlider):r.stop()})),this.d.add(this.on("invalidateAll",()=>{r.average=!0===this.style.average,r.weighted=!0===this.style.weighted,r.inverted=!0===this.style.inverted,this.style.mode&&(r.mode=this.style.mode),r.classifier=this.style.classifier,this.style.classOrder&&(r.classOrder=this.style.classOrder)}))}createHistogram(t){return this.fixedBoxes?new s(this.model,this.content,t):new e(this.model,this.content,t)}get fixedBoxes(){return void 0!==this.style.mode?.fixed||void 0!==this.style.mode?.fixedUnit}dispose(){this.model.clear(),this.d.dispose()}getDefaultStyle(){return{}}}
1
+ import{Disposables as s}from"../common/Disposables.js";import{TimeSliderDynamicHistogram as t}from"../data/histogram/TimeSliderDynamicHistogram.js";import{TimeSliderFixedHistogram as e}from"../data/histogram/TimeSliderFixedHistogram.js";import{TimeSliderIntervalsModel as i}from"../data/TimeSliderIntervalsModel.js";import{TimeSliderIntervalsLayer as r}from"./TimeSliderIntervalsLayer.js";export class TimeSliderHistogramLayerOld extends r{constructor(t,e){super(new i,e),this.content=t,this.d=new s;const r=this.createHistogram({classifier:e?.classifier,...e?.style});this.histogram=r,e?.classifier&&!e.labeler&&(e.classificationIsColor?this.labeler=s=>Math.abs(s.v[0]-s.v[1])+"":this.labeler=s=>{const t=Math.abs(s.v[0]-s.v[1]);return s.attributes?.classification+": "+t}),e?.classificationIsColor&&(this.styler=s=>{const t=s.attributes?.classification;return t?{fill:{color:t},border:{color:t}}:void 0}),this.d.add(this.on("loaded",s=>{s?r.start(this.timeSlider):r.stop()})),this.d.add(this.on("invalidateAll",()=>{r.average=!0===this.style.average,r.weighted=!0===this.style.weighted,r.inverted=!0===this.style.inverted,this.style.mode&&(r.mode=this.style.mode),r.classifier=this.style.classifier,this.style.classOrder&&(r.classOrder=this.style.classOrder)}))}createHistogram(s){return this.fixedBoxes?new e(this.model,this.content,s):new t(this.model,this.content,s)}get fixedBoxes(){return void 0!==this.style.mode?.fixed||void 0!==this.style.mode?.fixedUnit}dispose(){this.model.clear(),this.d.dispose()}getDefaultStyle(){return{}}}
@@ -1 +1 @@
1
- import{TimeSliderLayer as e}from"./TimeSliderLayer";export class TimeSliderIntervalsLayer extends e{getDefaultStyle(){return{}}}
1
+ import{TimeSliderLayer as e}from"./TimeSliderLayer.js";export class TimeSliderIntervalsLayer extends e{getDefaultStyle(){return{}}}
@@ -1 +1 @@
1
- import{v4 as i}from"uuid";import{TypedEventEmitter as t}from"../event/TypedEventEmitter";export class TimeSliderLayer extends t{constructor(t,e){super(),this.model=t,this._visible=!0,this._loaded=!1,this.id=e?.id||i(),this.style=e?.style||this.getDefaultStyle(),this._styler=e?.styler,this.labeler=e?.labeler,this.yAxis=e?.yAxis||{},this._name=e?.name||t.name||"Unknown",this._min=e?.min||0,this._max=e?.max||1,this._visible="boolean"!=typeof e?.visible||e.visible}get yAxisGroup(){return this.yAxis.group||this.id}get styler(){return this._styler}set styler(i){this._styler=i,this.invalidateAll()}invalidate(i){const t="string"==typeof i?i:i.id;this.emit("invalidate",t)}invalidateAll(){this.emit("invalidateAll")}select(i){this.emit("selection",i)}get min(){return this._min}set min(i){i!==this._min&&(this._min=i,this.emit("min",i))}get max(){return this._max}set max(i){i!==this._max&&(this._max=i,this.emit("max",i))}get timeSlider(){return this._timeSlider}set timeSlider(i){this._timeSlider=i}get name(){return this._name}set name(i){i!==this._name&&(this._name=i,this.emit("name",i))}get visible(){return this._visible}set visible(i){i!==this._visible&&(this._visible=i,this.emit("visible",i),this.shouldModelLoad())}get loaded(){return this._loaded}set loaded(i){i!==this._loaded&&(this._loaded=i,this.shouldModelLoad(),this.emit("loaded",i))}shouldModelLoad(){const i=this.loaded&&this.visible;this.model.loaded(this.id,i)}}
1
+ import{v4 as i}from"uuid";import{TypedEventEmitter as t}from"../event/TypedEventEmitter.js";export class TimeSliderLayer extends t{constructor(t,e){super(),this.model=t,this._visible=!0,this._loaded=!1,this.id=e?.id||i(),this.style=e?.style||this.getDefaultStyle(),this._styler=e?.styler,this.labeler=e?.labeler,this.yAxis=e?.yAxis||{},this._name=e?.name||t.name||"Unknown",this._min=e?.min||0,this._max=e?.max||1,this._visible="boolean"!=typeof e?.visible||e.visible}get yAxisGroup(){return this.yAxis.group||this.id}get styler(){return this._styler}set styler(i){this._styler=i,this.invalidateAll()}invalidate(i){const t="string"==typeof i?i:i.id;this.emit("invalidate",t)}invalidateAll(){this.emit("invalidateAll")}select(i){this.emit("selection",i)}get min(){return this._min}set min(i){i!==this._min&&(this._min=i,this.emit("min",i))}get max(){return this._max}set max(i){i!==this._max&&(this._max=i,this.emit("max",i))}get timeSlider(){return this._timeSlider}set timeSlider(i){this._timeSlider=i}get name(){return this._name}set name(i){i!==this._name&&(this._name=i,this.emit("name",i))}get visible(){return this._visible}set visible(i){i!==this._visible&&(this._visible=i,this.emit("visible",i),this.shouldModelLoad())}get loaded(){return this._loaded}set loaded(i){i!==this._loaded&&(this._loaded=i,this.shouldModelLoad(),this.emit("loaded",i))}shouldModelLoad(){const i=this.loaded&&this.visible;this.model.loaded(this.id,i)}}
@@ -4,5 +4,7 @@ import { TimeSliderLayer } from "./TimeSliderLayer";
4
4
  export interface TimeSliderLayerLoader<T extends TimeSliderEngine<any>> {
5
5
  engineClass: TimeSliderEngineClass<T>;
6
6
  canLoad(layer: TimeSliderLayer): boolean;
7
+ /** True when a loaded layer follows changes to its band (layer.min / layer.max) by itself. Otherwise the slider reloads the layer on such a change. */
8
+ followsLayerBand?: boolean;
7
9
  load(layer: TimeSliderLayer, scene: TimeSliderEngineScene<T>, engine: T, timeSlider: TimeSlider): () => void;
8
10
  }
@@ -1 +1 @@
1
- import{TimeSliderLayer as e}from"./TimeSliderLayer";export class TimeSliderPointsLayer extends e{getDefaultStyle(){return{}}}
1
+ import{TimeSliderLayer as e}from"./TimeSliderLayer.js";export class TimeSliderPointsLayer extends e{getDefaultStyle(){return{}}}