@protomaze/time 1.4.3 → 1.5.1

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 (66) 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 +128 -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/TimeSliderPointsLayer.js +1 -1
  43. package/package.json +60 -58
  44. package/react/DateLabelWithPicker.js +1 -1
  45. package/react/DateRangeLabelWithPicker.js +1 -1
  46. package/react/FullscreenButton.js +1 -1
  47. package/react/ReactTimeSlider.js +1 -1
  48. package/react/TimeLabelWithPicker.js +1 -1
  49. package/style/TimeSliderIntervalsStyle.d.ts +4 -0
  50. package/three/Three3DTimeSliderEngine.js +1 -1
  51. package/three/ThreeTimeSlider.js +1 -1
  52. package/three/ThreeTimeSliderEngine.js +1 -1
  53. package/three/layer/GrowingBufferGeometry.js +1 -1
  54. package/three/layer/GrowingInstanceMatrix.js +1 -1
  55. package/three/layer/Three3DIntervalsTimeLayerLoader.d.ts +1 -2
  56. package/three/layer/Three3DIntervalsTimeLayerLoader.js +1 -1
  57. package/three/layer/Three3DPointsTimeLayerLoader.d.ts +1 -2
  58. package/three/layer/Three3DPointsTimeLayerLoader.js +1 -1
  59. package/three/layer/ThreeIntervalsTimeLayerLoader.d.ts +1 -2
  60. package/three/layer/ThreeIntervalsTimeLayerLoader.js +1 -1
  61. package/three/layer/ThreePointsTimeLayerLoader.d.ts +1 -2
  62. package/three/layer/ThreePointsTimeLayerLoader.js +1 -1
  63. package/three/layer/ThreeTimeLayerLoader.js +1 -1
  64. package/three/react/ReactThreeTimeSlider.js +1 -1
  65. package/ticks/TimeTicksBar.d.ts +14 -1
  66. 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,7 @@ export declare class TimeSlider extends TypedEventEmitter<{
50
121
  ticksBar: TimeTicksBar;
51
122
  private loaders;
52
123
  private layerUnloaders;
124
+ private layerListenerStoppers;
53
125
  pressedKeys: Set<string>;
54
126
  protected container: HTMLElement | null;
55
127
  theme: 'dark' | 'light';
@@ -61,6 +133,7 @@ export declare class TimeSlider extends TypedEventEmitter<{
61
133
  private _showCurrent;
62
134
  showTicks: boolean;
63
135
  playSpeed: number | 'auto';
136
+ private _locale;
64
137
  current: number;
65
138
  range: {
66
139
  time: TimeSliderTimeRange;
@@ -76,6 +149,12 @@ export declare class TimeSlider extends TypedEventEmitter<{
76
149
  private toolTip;
77
150
  private selectedLabel;
78
151
  private selectingRangeElement;
152
+ private selectionOverlayContainer;
153
+ private _selectionRanges;
154
+ private selectionRangeElements;
155
+ private shadingElements;
156
+ private columnBandOverlayContainer;
157
+ private columnBandElements;
79
158
  private stopUpdatingLabel?;
80
159
  hoverOptions: TimeSliderHoverOptions;
81
160
  selectionOptions: TimeSliderSelectionOptions;
@@ -84,9 +163,43 @@ export declare class TimeSlider extends TypedEventEmitter<{
84
163
  selectingRange: boolean;
85
164
  selectingRangeVisible: boolean;
86
165
  whenDoneSelectingRange?: () => void;
87
- getLayers(): TimeSliderLayer<TimeSliderElement, import("../style/TimeSliderStyle").TimeSliderStyle>[];
88
- getVisibleLayers(): TimeSliderLayer<TimeSliderElement, import("../style/TimeSliderStyle").TimeSliderStyle>[];
166
+ private _limits?;
167
+ getLayers(): TimeSliderLayer<TimeSliderElement, import("..").TimeSliderStyle>[];
168
+ getVisibleLayers(): TimeSliderLayer<TimeSliderElement, import("..").TimeSliderStyle>[];
89
169
  constructor(options?: TimeSliderOptions);
170
+ get locale(): string;
171
+ /** 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. */
172
+ setLocale(locale: string): void;
173
+ /** Switches week ticks between the default date-range label and ISO calendar-week labels (e.g. "KW12"). */
174
+ setWeekLabel(weekLabel: 'default' | 'calendarWeek', weekLabelPrefix?: string): void;
175
+ /** Overrides per-tick label color/opacity, e.g. to fade ticks outside a selection. Pass undefined to clear. */
176
+ setTickLabelStyler(styler: TimeSliderTickLabelStyler | undefined): void;
177
+ get limits(): TimeSliderTimeRange | undefined;
178
+ /** Sets (or with undefined clears) the outer bounds of the visible time range, see TimeSliderOptions.limits. The current range is clamped right away. */
179
+ setLimits(limits: TimeSliderTimeRange | undefined): void;
180
+ /**
181
+ * Sets the draggable, programmatic selection range(s) — distinct from the
182
+ * click-driven element `select()` / `'select'` event, which keeps working
183
+ * independently. A range's startTime/endTime may be -Infinity/Infinity for
184
+ * an open-ended "before X" / "after X" selection, drawn to the slider edge.
185
+ * Fires 'selectionchange' with phase 'end'.
186
+ */
187
+ setSelection(ranges: TimeSliderSelectionRange[]): void;
188
+ getSelection(): TimeSliderSelectionRange[];
189
+ clearSelection(): void;
190
+ /**
191
+ * Switches how hover/click pick elements: 'element' (default) uses cursor
192
+ * time AND height, 'column' uses cursor time only — every visible layer's
193
+ * element(s) at that time, regardless of height. Also updates the hover
194
+ * column-highlight band immediately.
195
+ */
196
+ setPickMode(pick: TimeSliderPickMode): void;
197
+ private selectionTimeToX;
198
+ private renderSelectionOverlay;
199
+ /** 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'. */
200
+ private renderColumnHoverBand;
201
+ private createSelectionRangeElements;
202
+ private wireSelectionDrag;
90
203
  startSelectingRange(whenDone: () => void): void;
91
204
  stopSelectingRange(): void;
92
205
  updateValueRangesQueue: Map<string, {
@@ -103,6 +216,11 @@ export declare class TimeSlider extends TypedEventEmitter<{
103
216
  showingStats: boolean;
104
217
  showStats(showingStats: boolean): void;
105
218
  protected engine?: TimeSliderEngine<any>;
219
+ private _engineReady;
220
+ /** True once the current engine's async init() has resolved and layers can actually render — see also the 'ready' event and whenReady(). */
221
+ get engineReady(): boolean;
222
+ /** Resolves once the engine is ready (immediately, if it already is). Layers added before this point are queued and loaded automatically — see loadLayer(). */
223
+ whenReady(): Promise<void>;
106
224
  setEngine(engine: TimeSliderEngine<any>): Promise<void>;
107
225
  initSliderContainer(): void;
108
226
  get showCurrent(): boolean;
@@ -113,7 +231,7 @@ export declare class TimeSlider extends TypedEventEmitter<{
113
231
  private updatingLabel;
114
232
  private selectedLayerId?;
115
233
  getLabel(element: TimeSliderElement, layer: TimeSliderLayer, t: number, v: number): string | null;
116
- getLayerById(id: string): TimeSliderLayer<TimeSliderElement, import("../style/TimeSliderStyle").TimeSliderStyle> | undefined;
234
+ getLayerById(id: string): TimeSliderLayer<TimeSliderElement, import("..").TimeSliderStyle> | undefined;
117
235
  select(mouse: {
118
236
  x: number;
119
237
  y: number;
@@ -151,11 +269,16 @@ export declare class TimeSlider extends TypedEventEmitter<{
151
269
  x: number;
152
270
  y: number;
153
271
  }, pickSize?: number): {
154
- layer: TimeSliderLayer<TimeSliderElement, import("../style/TimeSliderStyle").TimeSliderStyle>;
272
+ layer: TimeSliderLayer<TimeSliderElement, import("..").TimeSliderStyle>;
155
273
  elements: TimeSliderElement[];
156
274
  t: number;
157
275
  v: number;
158
276
  }[];
277
+ /** Pick mode 'column': ignores cursor height entirely — every visible layer's element(s) whose time interval contains the cursor time. */
278
+ private findColumnElements;
279
+ private hoverCleared;
280
+ /** 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. */
281
+ private clearHoverEvent;
159
282
  updateHover(mouse?: {
160
283
  x: number;
161
284
  y: number;
@@ -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 u}from"../data/TimeSliderIntervalsModel.js";import{addDuration as g,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 x}from"../event/TypedEventEmitter.js";import{TimeSliderHistogramLayer as L}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 D,ONE_WEEK as B,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=D,_=10*S;export class TimeSlider extends x{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.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*D,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,u=.5*l,g=o.width-.5*n,p=o.height-.5*l,y=Math.min(g,Math.max(c,h)),v=Math.min(p,Math.max(u,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 L&&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 u){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 u){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,u=36;let g=this.mouse.x+10,p=this.mouse.y+10;const y=e.left+e.width-c-5,v=e.top+e.height-u-5;g>y&&(g=y),p>v&&(p=v),this.toolTip.style.left=`${g}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 g(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:B,unit:"month"},{threshold:C,unit:"week"},{threshold:V,unit:"day"},{threshold:k,unit:"hour"},{threshold:D,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:B,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.layerUnloaders.set(e.id,()=>{a(),s(),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.updateAllValueRanges()),e.on("max",()=>this.updateAllValueRanges())];this.layerListenerStoppers.set(e.id,()=>t.forEach(e=>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.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},u=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})},g=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",u),this.sliderElement.addEventListener("pointerup",g),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",u),this.sliderElement.removeEventListener("pointerup",g),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:D}),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)}}
@@ -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{}}}