@protomaze/time 1.4.3

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 (152) hide show
  1. package/README.md +1 -0
  2. package/TimeSliderDemo.d.ts +1 -0
  3. package/TimeSliderDemo.js +1 -0
  4. package/common/CaptureConsole.d.ts +5 -0
  5. package/common/CaptureConsole.js +1 -0
  6. package/common/Clamper.d.ts +6 -0
  7. package/common/Clamper.js +1 -0
  8. package/common/Disposables.d.ts +7 -0
  9. package/common/Disposables.js +1 -0
  10. package/common/Easing.d.ts +1 -0
  11. package/common/Easing.js +1 -0
  12. package/common/Expand.d.ts +3 -0
  13. package/common/Expand.js +1 -0
  14. package/common/GlslTools.d.ts +4 -0
  15. package/common/GlslTools.js +1 -0
  16. package/common/TimeTools.d.ts +42 -0
  17. package/common/TimeTools.js +1 -0
  18. package/data/CompositeTimeSliderModel.d.ts +13 -0
  19. package/data/CompositeTimeSliderModel.js +1 -0
  20. package/data/IntervalLaneManager.d.ts +24 -0
  21. package/data/IntervalLaneManager.js +1 -0
  22. package/data/TimeSliderBush.d.ts +23 -0
  23. package/data/TimeSliderBush.js +1 -0
  24. package/data/TimeSliderElement.d.ts +21 -0
  25. package/data/TimeSliderElement.js +1 -0
  26. package/data/TimeSliderIntervalsModel.d.ts +6 -0
  27. package/data/TimeSliderIntervalsModel.js +1 -0
  28. package/data/TimeSliderLanesModel.d.ts +11 -0
  29. package/data/TimeSliderLanesModel.js +1 -0
  30. package/data/TimeSliderModel.d.ts +45 -0
  31. package/data/TimeSliderModel.js +1 -0
  32. package/data/TimeSliderPointsModel.d.ts +6 -0
  33. package/data/TimeSliderPointsModel.js +1 -0
  34. package/data/TimeSliderRange.d.ts +30 -0
  35. package/data/TimeSliderRange.js +1 -0
  36. package/data/histogram/TimeSliderDynamicHistogram.d.ts +21 -0
  37. package/data/histogram/TimeSliderDynamicHistogram.js +1 -0
  38. package/data/histogram/TimeSliderFixedHistogram.d.ts +52 -0
  39. package/data/histogram/TimeSliderFixedHistogram.js +1 -0
  40. package/data/histogram/TimeSliderHistogram.d.ts +68 -0
  41. package/data/histogram/TimeSliderHistogram.js +1 -0
  42. package/data/histogram/TimeSliderSplittingFixedHistogram.d.ts +45 -0
  43. package/data/histogram/TimeSliderSplittingFixedHistogram.js +1 -0
  44. package/demo/Common.d.ts +21 -0
  45. package/demo/Common.js +1 -0
  46. package/demo/Metrics.d.ts +2 -0
  47. package/demo/Metrics.js +1 -0
  48. package/demo/Nasdaq.d.ts +3 -0
  49. package/demo/Nasdaq.js +1 -0
  50. package/demo/Quakes.d.ts +3 -0
  51. package/demo/Quakes.js +1 -0
  52. package/demo/QuakesFilters.d.ts +3 -0
  53. package/demo/QuakesFilters.js +1 -0
  54. package/demo/Random.d.ts +49 -0
  55. package/demo/Random.js +1 -0
  56. package/demo/Test.d.ts +5 -0
  57. package/demo/Test.js +1 -0
  58. package/demo/Wars.d.ts +2 -0
  59. package/demo/Wars.js +1 -0
  60. package/engine/HorizontalPinchZoom.d.ts +3 -0
  61. package/engine/HorizontalPinchZoom.js +1 -0
  62. package/engine/PinchZoom.d.ts +17 -0
  63. package/engine/PinchZoom.js +1 -0
  64. package/engine/TimeSlider.d.ts +225 -0
  65. package/engine/TimeSlider.js +1 -0
  66. package/engine/TimeSliderEngine.d.ts +42 -0
  67. package/engine/TimeSliderEngine.js +1 -0
  68. package/event/TypedEventEmitter.d.ts +13 -0
  69. package/event/TypedEventEmitter.js +1 -0
  70. package/index.d.ts +1 -0
  71. package/index.js +1 -0
  72. package/layer/TimeSliderHistogramLayer.d.ts +27 -0
  73. package/layer/TimeSliderHistogramLayer.js +1 -0
  74. package/layer/TimeSliderHistogramLayerOld.d.ts +20 -0
  75. package/layer/TimeSliderHistogramLayerOld.js +1 -0
  76. package/layer/TimeSliderIntervalsLayer.d.ts +7 -0
  77. package/layer/TimeSliderIntervalsLayer.js +1 -0
  78. package/layer/TimeSliderLayer.d.ts +66 -0
  79. package/layer/TimeSliderLayer.js +1 -0
  80. package/layer/TimeSliderLayerLoader.d.ts +8 -0
  81. package/layer/TimeSliderLayerLoader.js +1 -0
  82. package/layer/TimeSliderPointsLayer.d.ts +7 -0
  83. package/layer/TimeSliderPointsLayer.js +1 -0
  84. package/package.json +58 -0
  85. package/react/ColoredSlider.d.ts +58 -0
  86. package/react/ColoredSlider.js +1 -0
  87. package/react/ColoredSliderExtendsInput.d.ts +31 -0
  88. package/react/ColoredSliderExtendsInput.js +1 -0
  89. package/react/DateLabelWithPicker.d.ts +6 -0
  90. package/react/DateLabelWithPicker.js +1 -0
  91. package/react/DateRangeLabelWithPicker.d.ts +7 -0
  92. package/react/DateRangeLabelWithPicker.js +1 -0
  93. package/react/DeepMemoHook.d.ts +1 -0
  94. package/react/DeepMemoHook.js +1 -0
  95. package/react/FullscreenButton.d.ts +1 -0
  96. package/react/FullscreenButton.js +1 -0
  97. package/react/MaterialIconButton.d.ts +7 -0
  98. package/react/MaterialIconButton.js +1 -0
  99. package/react/MaterialTextButton.d.ts +8 -0
  100. package/react/MaterialTextButton.js +1 -0
  101. package/react/PinchZoomHook.d.ts +10 -0
  102. package/react/PinchZoomHook.js +1 -0
  103. package/react/PointerClick.d.ts +1 -0
  104. package/react/PointerClick.js +1 -0
  105. package/react/ReactTimeSlider.d.ts +52 -0
  106. package/react/ReactTimeSlider.js +1 -0
  107. package/react/TimeLabelWithPicker.d.ts +8 -0
  108. package/react/TimeLabelWithPicker.js +1 -0
  109. package/react/YearScroller.d.ts +13 -0
  110. package/react/YearScroller.js +1 -0
  111. package/style/TimeSliderColors.d.ts +6 -0
  112. package/style/TimeSliderColors.js +1 -0
  113. package/style/TimeSliderHistogramStyle.d.ts +3 -0
  114. package/style/TimeSliderHistogramStyle.js +1 -0
  115. package/style/TimeSliderIntervalsStyle.d.ts +13 -0
  116. package/style/TimeSliderIntervalsStyle.js +1 -0
  117. package/style/TimeSliderLabeler.d.ts +2 -0
  118. package/style/TimeSliderLabeler.js +1 -0
  119. package/style/TimeSliderPointsStyle.d.ts +38 -0
  120. package/style/TimeSliderPointsStyle.js +1 -0
  121. package/style/TimeSliderStyle.d.ts +1 -0
  122. package/style/TimeSliderStyle.js +1 -0
  123. package/style/TimeSliderStyler.d.ts +3 -0
  124. package/style/TimeSliderStyler.js +1 -0
  125. package/three/Three3DTimeSliderEngine.d.ts +27 -0
  126. package/three/Three3DTimeSliderEngine.js +1 -0
  127. package/three/ThreeTimeSlider.d.ts +4 -0
  128. package/three/ThreeTimeSlider.js +1 -0
  129. package/three/ThreeTimeSliderEngine.d.ts +20 -0
  130. package/three/ThreeTimeSliderEngine.js +1 -0
  131. package/three/layer/GrowingBufferGeometry.d.ts +26 -0
  132. package/three/layer/GrowingBufferGeometry.js +1 -0
  133. package/three/layer/GrowingInstanceMatrix.d.ts +43 -0
  134. package/three/layer/GrowingInstanceMatrix.js +1 -0
  135. package/three/layer/Three3DIntervalsTimeLayerLoader.d.ts +11 -0
  136. package/three/layer/Three3DIntervalsTimeLayerLoader.js +1 -0
  137. package/three/layer/Three3DPointsTimeLayerLoader.d.ts +10 -0
  138. package/three/layer/Three3DPointsTimeLayerLoader.js +1 -0
  139. package/three/layer/ThreeIntervalsTimeLayerLoader.d.ts +10 -0
  140. package/three/layer/ThreeIntervalsTimeLayerLoader.js +1 -0
  141. package/three/layer/ThreePointsTimeLayerLoader.d.ts +9 -0
  142. package/three/layer/ThreePointsTimeLayerLoader.js +1 -0
  143. package/three/layer/ThreeTimeLayerLoader.d.ts +10 -0
  144. package/three/layer/ThreeTimeLayerLoader.js +1 -0
  145. package/three/react/ReactThreeTimeSlider.d.ts +2 -0
  146. package/three/react/ReactThreeTimeSlider.js +1 -0
  147. package/ticks/TimeSliderConstants.d.ts +15 -0
  148. package/ticks/TimeSliderConstants.js +1 -0
  149. package/ticks/TimeTicksBar.d.ts +46 -0
  150. package/ticks/TimeTicksBar.js +1 -0
  151. package/ticks/YAxisTicks.d.ts +31 -0
  152. package/ticks/YAxisTicks.js +1 -0
package/README.md ADDED
@@ -0,0 +1 @@
1
+ # Protomaze Timesliders
@@ -0,0 +1 @@
1
+ export declare function TimeSliderDemo(): JSX.Element;
@@ -0,0 +1 @@
1
+ import e,{useEffect as t,useMemo as r,useRef as a,useState as n}from"react";import{setupInPageConsole as o}from"./common/CaptureConsole";import{NASDAQ_MULTI_LAYERS as i,NASDAQ_SINGLE_LAYERS as m}from"./demo/Nasdaq";import{QUAKES_MULTI_LAYERS as l,QUAKES_SINGLE_LAYERS as s}from"./demo/Quakes";import{RANDOM_MULTI_LAYERS as c,RANDOM_SINGLE_LAYERS as d}from"./demo/Random";import{WARS_MULTI_LAYERS as p,WARS_SINGLE_LAYERS as u}from"./demo/Wars";import{FullscreenButton as f}from"./react/FullscreenButton";import{MaterialIconButton as w}from"./react/MaterialIconButton";import{MaterialTextButton as h}from"./react/MaterialTextButton";import{ReactTimeSlider as k}from"./react/ReactTimeSlider";import{Three3DTimeSliderEngine as x}from"./three/Three3DTimeSliderEngine";import{ThreeTimeSliderEngine as E}from"./three/ThreeTimeSliderEngine";import{Three3DIntervalsTimeLayerLoader as g}from"./three/layer/Three3DIntervalsTimeLayerLoader";import{Three3DPointsTimeLayerLoader as y}from"./three/layer/Three3DPointsTimeLayerLoader";import{ThreeIntervalsTimeLayerLoader as T}from"./three/layer/ThreeIntervalsTimeLayerLoader";import{ThreePointsTimeLayerLoader as v}from"./three/layer/ThreePointsTimeLayerLoader";import{ONE_MINUTE as q}from"./ticks/TimeSliderConstants";import{QuakesFilters as C}from"./demo/QuakesFilters";import{TEST_LAYERS as D}from"./demo/Test";const L="development"===process.env.NODE_ENV,S=L;L&&!1&&o();const N=Date.now(),R=N-37*q,b={single:{test:[!1],random:[!0],quakes:[!1],nasdaq:[!1],wars:[!1]},multiple:{test:[!1],random:[!1,!0,!1],quakes:[!1,!1,!1],nasdaq:[!1,!1,!1,!1,!1],wars:[!1,!1]}},I={single:{test:[D],random:[d],quakes:[s],nasdaq:[m],wars:[u]},multiple:{test:[D],random:c,quakes:l,nasdaq:i,wars:p}},_=[new v,new T,new y,new g],B=[new E,new E,new E,new E,new E,new E],F=[new x,new x,new x,new x,new x,new x],M={display:"flex",justifyContent:"center",alignItems:"center",borderRadius:"4px",backgroundColor:"#222"},Q={...M,flexShrink:0},G={...M,flexGrow:1};export function TimeSliderDemo(){const[o,i]=n([R,N]),[m,l]=n(!0),[s,c]=n(!1),[d,p]=n("test"),[u,x]=n(!0),E=a([]),g=r(()=>I[s?"multiple":"single"][d],[d,s]);return t(()=>{E.current.forEach((e,t)=>{e?.timeSlider.pause();const r=b[s?"multiple":"single"][d][t];"random"===d&&r&&setTimeout(()=>{e?.timeSlider.setLive(!0)},200)})},[d,s]),e.createElement(e.Fragment,null,e.createElement("div",{style:{position:"absolute",display:"flex",flexDirection:"column",inset:"0",gap:"8px",padding:"8px",height:"calc(100% - 16px)"}},e.createElement("div",{style:{...Q,height:"22px",gap:"8px",padding:"8px",backgroundColor:u?"#222":"#ddd",display:"flex"}},e.createElement(h,{text:"Random",onClick:()=>p("random"),active:"random"===d}),e.createElement(h,{text:"Quakes",onClick:()=>p("quakes"),active:"quakes"===d}),e.createElement(h,{text:"Nasdaq",onClick:()=>p("nasdaq"),active:"nasdaq"===d}),e.createElement("div",{style:{flexGrow:1}}),e.createElement(w,{iconName:u?"dark_mode":"light_mode",onClick:()=>x(e=>!e)}),e.createElement("div",{style:{width:"0px"}}),e.createElement(w,{iconName:"crop_square",onClick:()=>c(!1),active:!s}),e.createElement(w,{iconName:"splitscreen",onClick:()=>c(!0),active:s}),e.createElement("div",{style:{width:"0px"}}),e.createElement(h,{text:"2D",onClick:()=>l(!1),active:!m}),e.createElement(h,{text:"3D",onClick:()=>l(!0),active:m}),e.createElement("div",{style:{width:"0px"}}),e.createElement(f,null)),"quakes"===d&&e.createElement(C,{darkMode:u}),g.map((t,r)=>e.createElement("div",{key:r,style:G},e.createElement(k,{engine:(m?F:B)[r],theme:u?"dark":"light",ref:e=>{E.current[r]=e},timeRange:o,onTimeRange:i,layers:t,loaders:_,showTicks:!0,showCurrent:b[s?"multiple":"single"][d][r],showStats:S})))))}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Sets up a custom in-page console to capture and display all console messages.
3
+ * This is a singleton; calling it more than once will have no effect.
4
+ */
5
+ export declare function setupInPageConsole(): void;
@@ -0,0 +1 @@
1
+ export function setupInPageConsole(){if(document.getElementById("in-page-console-container"))return;const e=document.createElement("div");e.id="in-page-console-container",e.classList.add("hidden"),e.style.zIndex="99999999",e.style.colorScheme="dark";const n=document.createElement("button");n.id="in-page-console-toggle",n.textContent="Show Console",n.style.zIndex="999999999",document.body.appendChild(e),document.body.appendChild(n),n.addEventListener("click",()=>{e.classList.toggle("hidden");const o=e.classList.contains("hidden");e.style.maxHeight=o?"64px":"50%",n.textContent=o?"Show Console":"Hide Console"});["log","warn","error","info"].forEach(n=>{const o=console[n];console[n]=(...t)=>{o.apply(console,t),((n,o)=>{const t=document.createElement("pre");t.classList.add("console-line",`console-line--${n}`);const l=o.map(e=>{if("object"==typeof e&&null!==e)try{return JSON.stringify(e,null,2)}catch(e){return"[Circular Reference]"}return String(e)}).join(" ");t.textContent=`[${(new Date).toLocaleTimeString("en-BE")}] ${l}`,e.appendChild(t),e.scrollTop=e.scrollHeight})(n,t)}}),console.log("In-page console initialized.")}
@@ -0,0 +1,6 @@
1
+ type Position = {
2
+ top: number;
3
+ left: number;
4
+ };
5
+ export declare function clampLabelPosition(labelElement: HTMLElement, desiredPos: Position): Position;
6
+ export {};
@@ -0,0 +1 @@
1
+ export function clampLabelPosition(t,e){const i=document.body.getBoundingClientRect(),n=t.getBoundingClientRect(),h=n.width/2;let o=e.left,g=e.top;return o-h<4&&(o=4+h),o+h>i.width-4&&(o=i.width-4-h),g<4&&(g=4),g+n.height>i.height-4&&(g=i.height-n.height-4),{top:g,left:o}}
@@ -0,0 +1,7 @@
1
+ export declare class Disposables {
2
+ private disposables;
3
+ private disposed;
4
+ add(disposable: () => void): void;
5
+ dispose(): void;
6
+ disposeLater(): () => void;
7
+ }
@@ -0,0 +1 @@
1
+ export class Disposables{constructor(){this.disposables=[],this.disposed=!1}add(s){this.disposed?s():this.disposables.push(s)}dispose(){this.disposed=!0,this.disposables.forEach(s=>s())}disposeLater(){return()=>{this.dispose()}}}
@@ -0,0 +1 @@
1
+ export declare function animateRangeTransition(fromMin: number, fromMax: number, toMin: number, toMax: number, duration: number, onUpdate: (currentMin: number, currentMax: number) => void, onDone?: () => void): () => void;
@@ -0,0 +1 @@
1
+ export function animateRangeTransition(n,t,e,o,r,a,i){const m=performance.now();let u=!0;return requestAnimationFrame(function c(s){const f=s-m,p=Math.min(f/r,1),h=function(n){return n<.5?4*n*n*n:1-Math.pow(-2*n+2,3)/2}(p);a(n+(e-n)*h,t+(o-t)*h),u&&p<1?requestAnimationFrame(c):i?.()}),()=>{u=!1}}
@@ -0,0 +1,3 @@
1
+ export type Expand<T> = T extends infer O ? {
2
+ [K in keyof O]: O[K];
3
+ } : never;
@@ -0,0 +1 @@
1
+ export{};
@@ -0,0 +1,4 @@
1
+ export declare function toGLSLFloat(n: number): string;
2
+ export declare function toGLSLColor(color: string): string;
3
+ export declare function toGLSLVec3(x: number, y: number, z: number): string;
4
+ export declare function toGLSLVec2(x: number, y: number): string;
@@ -0,0 +1 @@
1
+ import{Color as t}from"three";export function toGLSLFloat(t){return Number.isInteger(t)?t.toFixed(1):t.toString()}export function toGLSLColor(o){const L=new t(o);return`vec3(${toGLSLFloat(L.r)},${toGLSLFloat(L.g)},${toGLSLFloat(L.b)})`}export function toGLSLVec3(t,o,L){return`vec3(${toGLSLFloat(t)},${toGLSLFloat(o)},${toGLSLFloat(L)})`}export function toGLSLVec2(t,o){return`vec2(${toGLSLFloat(t)},${toGLSLFloat(o)})`}
@@ -0,0 +1,42 @@
1
+ import { TimeSliderTimeRange, TimeSliderTimeRangeArray } from "../data/TimeSliderRange";
2
+ export declare const year0Ms: number;
3
+ export declare const year1000Ms: number;
4
+ export declare const SPLIT_PART_2: number;
5
+ export declare const SPLIT_TIME_3: number;
6
+ export declare const SPLIT_TIME_3_POW2: number;
7
+ export declare const MONTH_NAMES: string[];
8
+ export declare function getStartOfSecond(timestamp: number): number;
9
+ export declare function getStartOfMinute(timestamp: number): number;
10
+ export declare function getStartOfHour(timestamp: number): number;
11
+ export declare function getStartOfDay(timestamp: number): number;
12
+ export declare function getStartOfWeek(timestamp: number): number;
13
+ export declare function getStartOfMonth(timestamp: number): number;
14
+ export declare function getStartOfXYears(timestamp: number, interval: number): number;
15
+ export type TimeUnit = 'year' | 'month' | 'week' | 'day' | 'hour' | 'minute' | 'second' | 'decade' | 'century' | 'millennium';
16
+ export declare function getTimeUnitInMs(unit: TimeUnit): number;
17
+ export declare function getTimeUnitRange(time: number, category: TimeUnit, shift?: number): {
18
+ startTime: number;
19
+ endTime: number;
20
+ };
21
+ export declare function getTimeOffset(startTime: number, endTime: number, category: TimeUnit): number;
22
+ /**
23
+ * Given a start and end time, determines which TimeUnit the range most closely represents.
24
+ * A match is found if the provided start and end times are within a 10% tolerance
25
+ * of a standard time unit range calculated from the start time.
26
+ *
27
+ * @param startTime The start of the time range as a Unix timestamp (milliseconds).
28
+ * @param endTime The end of the time range as a Unix timestamp (milliseconds).
29
+ * @returns The matching TimeUnit, or undefined if no unit matches closely enough.
30
+ */
31
+ export declare function getMatchingTimeUnit(startTime: number, endTime: number): TimeUnit | undefined;
32
+ export declare function getLargeTimeUnitRange(time: number, years: number, shift?: number): TimeSliderTimeRange;
33
+ export declare function formatDuration(durationOrRange: number | TimeSliderTimeRange | [start: number, end: number]): string;
34
+ export declare function formatDate(time: number, padding?: boolean): string;
35
+ export declare function formatDateTime(time: number): string;
36
+ export declare function formatDateWithWeekDay(time: number): string;
37
+ export declare function formatDateRange(range: TimeSliderTimeRangeArray): string;
38
+ export declare function formatTime(time: number): string;
39
+ export declare function getTimePartsInHours(time: number): [hoursSinceYear0: number, msSinceHourStart: number];
40
+ export declare function splitTime3(time: number): [t1: number, t2: number, t3: number];
41
+ export declare function splitTime2(time: number): [t1: number, t2: number];
42
+ export declare function getDurationParts(duration: number): [days: number, ms: number];
@@ -0,0 +1 @@
1
+ import{CENTURY as e,DECADE as t,MILLENIUM as r,ONE_DAY as a,ONE_HOUR as o,ONE_MINUTE as n,ONE_MONTH as s,ONE_SECOND as u,ONE_WEEK as l,ONE_YEAR as i}from"../ticks/TimeSliderConstants";const g=new Date;g.setFullYear(0,0,1),g.setHours(0,0,0,0);export const year0Ms=g.getTime();const c=new Date;c.setFullYear(1e3,0,1),c.setHours(0,0,0,0);export const year1000Ms=c.getTime();export const SPLIT_PART_2=Math.pow(2,22);export const SPLIT_TIME_3=Math.pow(2,14);export const SPLIT_TIME_3_POW2=SPLIT_TIME_3*SPLIT_TIME_3;export const MONTH_NAMES=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];export function getStartOfSecond(e){return new Date(e).setMilliseconds(0)}export function getStartOfMinute(e){return new Date(e).setSeconds(0,0)}export function getStartOfHour(e){return new Date(e).setMinutes(0,0,0)}export function getStartOfDay(e){return new Date(e).setHours(0,0,0,0)}export function getStartOfWeek(e){const t=new Date(e),r=t.getDay(),a=t.getDate()-r+(0===r?-6:1);return new Date(t.setDate(a)).setHours(0,0,0,0)}export function getStartOfMonth(e){const t=new Date(e);return t.setDate(1),t.setHours(0,0,0,0)}export function getStartOfXYears(e,t){const r=new Date(e),a=t*Math.floor(r.getFullYear()/t),o=new Date(a,0,1);o.setFullYear(a);return o.setHours(0,0,0,0)}export function getTimeUnitInMs(g){switch(g){case"year":return i;case"month":return s;case"week":return l;case"day":return a;case"hour":return o;case"minute":return n;case"second":return u;case"decade":return t;case"century":return e;case"millennium":return r}}export function getTimeUnitRange(e,t,r=0){const a=new Date(e),o=new Date(a),n=new Date(a);switch(t){case"year":{const e=a.getFullYear()+r;o.setFullYear(e,0,1),o.setHours(0,0,0,0),n.setFullYear(e+1,0,1),n.setHours(0,0,0,0);break}case"month":{const e=a.getFullYear(),t=a.getMonth()+r;o.setFullYear(e,t,1),o.setHours(0,0,0,0),n.setFullYear(e,t+1,1),n.setHours(0,0,0,0);break}case"week":{const e=(a.getDay()+6)%7;o.setDate(a.getDate()-e+7*r),o.setHours(0,0,0,0),n.setTime(o.getTime()),n.setDate(o.getDate()+7);break}case"day":o.setDate(a.getDate()+r),o.setHours(0,0,0,0),n.setTime(o.getTime()),n.setDate(o.getDate()+1);break;case"hour":o.setTime(a.getTime()),o.setHours(a.getHours()+r,0,0,0),n.setTime(o.getTime()),n.setHours(o.getHours()+1);break;case"minute":o.setTime(a.getTime()),o.setMinutes(a.getMinutes()+r,0,0),n.setTime(o.getTime()),n.setMinutes(o.getMinutes()+1);break;case"second":o.setTime(a.getTime()),o.setSeconds(a.getSeconds()+r,0),n.setTime(o.getTime()),n.setSeconds(o.getSeconds()+1);break;case"decade":{const e=10*Math.floor(a.getFullYear()/10)+10*r;o.setFullYear(e,0,1),o.setHours(0,0,0,0),n.setFullYear(e+10,0,1),n.setHours(0,0,0,0);break}case"century":{const e=100*Math.floor(a.getFullYear()/100)+100*r;o.setFullYear(e,0,1),o.setHours(0,0,0,0),n.setFullYear(e+100,0,1),n.setHours(0,0,0,0);break}case"millennium":{const e=1e3*Math.floor(a.getFullYear()/1e3)+1e3*r;o.setFullYear(e,0,1),o.setHours(0,0,0,0),n.setFullYear(e+1e3,0,1),n.setHours(0,0,0,0);break}default:throw new Error("Invalid category")}return{startTime:o.getTime(),endTime:n.getTime()}}export function getTimeOffset(e,t,r){const a=new Date(e),o=new Date(t);switch(r){case"year":return o.getFullYear()-a.getFullYear();case"month":return 12*(o.getFullYear()-a.getFullYear())+(o.getMonth()-a.getMonth());case"week":const e=6048e5;return Math.floor((o.getTime()-a.getTime())/e);case"day":const t=864e5;return Math.floor((o.getTime()-a.getTime())/t);case"hour":const r=36e5;return Math.floor((o.getTime()-a.getTime())/r);case"minute":const n=6e4;return Math.floor((o.getTime()-a.getTime())/n);case"second":const s=1e3;return Math.floor((o.getTime()-a.getTime())/s);case"decade":return Math.floor(o.getFullYear()/10)-Math.floor(a.getFullYear()/10);case"century":return Math.floor(o.getFullYear()/100)-Math.floor(a.getFullYear()/100);case"millennium":return Math.floor(o.getFullYear()/1e3)-Math.floor(a.getFullYear()/1e3);default:throw new Error("Invalid category")}}export function getMatchingTimeUnit(e,t){const r=["millennium","century","decade","year","month","week","day","hour","minute","second"];for(const a of r){const r=getTimeUnitRange(e,a),o=r.endTime-r.startTime;if(0===o)continue;const n=.1*o,s=Math.abs(e-r.startTime)<=n,u=Math.abs(t-r.endTime)<=n;if(s&&u)return a}}export function getLargeTimeUnitRange(e,t,r=0){const a=new Date(e),o=new Date(a),n=new Date(a),s=Math.floor(o.getFullYear()/t)*t+r*t;return o.setFullYear(s,0,1),o.setHours(0,0,0,0),n.setFullYear(s+t-1,11,31),n.setHours(23,59,59,999),{startTime:o.getTime(),endTime:n.getTime()}}export function formatDuration(t){const r="number"==typeof t?t:Array.isArray(t)?t[1]-t[0]:t.endTime-t.startTime,a=Math.floor(r/1e3),n=Math.floor(a/60),s=Math.floor(n/60),g=Math.floor(s/24),c=Math.floor(g/365),m=Math.floor(r%1e3),f=a%60,h=n%60,T=s%24,M=g%365,D=[];if(c>0&&D.push(`${c} year${c>1?"s":""}`),c<1||M>Math.ceil(c/4))if(M%7==0&&0===T&&0===h&&0===f&&M>0&&r<e){const e=Math.floor(M/7);D.push(`${e} week${e>1?"s":""}`)}else M>0&&r<e&&D.push(`${M} day${M>1?"s":""}`),T>0&&r<i&&D.push(`${T}h`),h>0&&r<l&&D.push(`${h}m`),f>0&&r<o&&D.push(`${f}s`),r<5*u&&r>=1&&D.push(`${m}ms`),r<1&&D.push("<1ms");return D.join(" ")}export function formatDate(e,t){const r=new Date(e),a=t?String(r.getFullYear()).padStart(4,"0"):String(r.getFullYear());return`${t?String(r.getDate()).padStart(2,"0"):String(r.getDate())} ${MONTH_NAMES[r.getMonth()]} ${a}`}export function formatDateTime(e){const t="number"==typeof e?new Date(e):e,r=t.getFullYear().toString().padStart(4,"0"),a=t.getDate().toString().padStart(2,"0"),o=t.toLocaleString("default",{month:"short"});return`${t.toLocaleString("default",{weekday:"short"})} ${a} ${o} ${r} ${t.getHours().toString().padStart(2,"0")}:${t.getMinutes().toString().padStart(2,"0")}:${t.getSeconds().toString().padStart(2,"0")}`}export function formatDateWithWeekDay(e){const t="number"==typeof e?new Date(e):e,r=t.getFullYear().toString().padStart(4,"0"),a=t.getDate().toString().padStart(2,"0"),o=t.toLocaleString("default",{month:"short"});return`${t.toLocaleString("default",{weekday:"short"})} ${a} ${o} ${r}`}export function formatDateRange(e){const[t,r]=e,a=new Date(t),o=new Date(r),n=new Date(r-1),s=a.toLocaleString("default",{month:"short"}),u=n.toLocaleString("default",{month:"short"}),l=a.getDate().toString().padStart(2,"0"),i=n.getDate().toString().padStart(2,"0");return a.getFullYear()===n.getFullYear()?a.getMonth()===n.getMonth()?a.getDate()===n.getDate()?`${i} ${u} ${n.getFullYear()}`:1===a.getDate()&&1===o.getDate()?`${u} ${n.getFullYear()}`:`${l} - ${i} ${u} ${n.getFullYear()}`:1===a.getDate()&&1===o.getDate()&&0===a.getMonth()&&0===o.getMonth()?`${n.getFullYear()}`:`${l} ${s} - ${i} ${u} ${n.getFullYear()}`:1===a.getDate()&&1===o.getDate()&&0===a.getMonth()&&0===o.getMonth()?` ${a.getFullYear()} - ${n.getFullYear()}`:`${l} ${s} ${a.getFullYear()} - ${i} ${u} ${n.getFullYear()}`}export function formatTime(e){const t=new Date(e),r=t.getHours(),a=t.getMinutes(),o=t.getSeconds();return(r<10?"0":"")+r+":"+(a<10?"0":"")+a+":"+(o<10?"0":"")+o}export function getTimePartsInHours(e){return[Math.floor(e/o),e%o]}export function splitTime3(e){const t=Math.floor(e/SPLIT_TIME_3_POW2),r=e%SPLIT_TIME_3_POW2;return[t,Math.floor(r/SPLIT_TIME_3),r%SPLIT_TIME_3]}export function splitTime2(e){return[Math.floor(e/SPLIT_PART_2),e%SPLIT_PART_2]}export function getDurationParts(e){return[Math.floor(e/a),e%a]}
@@ -0,0 +1,13 @@
1
+ import { TimeSliderElement } from "./TimeSliderElement";
2
+ import { TimeSliderModel } from "./TimeSliderModel";
3
+ import { TimeSliderRange, TimeSliderTimeRange, TimeSliderTimeRangeArray, TimeSliderTimeRangeWithDuration } from "./TimeSliderRange";
4
+ export declare class CompositeTimeSliderModel extends TimeSliderModel {
5
+ models: TimeSliderModel[];
6
+ constructor(...models: TimeSliderModel[]);
7
+ get data(): TimeSliderElement[];
8
+ get(id: string): TimeSliderElement | undefined;
9
+ dataInTimeRange(range: TimeSliderTimeRange | TimeSliderTimeRangeArray): TimeSliderElement[];
10
+ dataInRange(range: TimeSliderRange): TimeSliderElement[];
11
+ clear(): void;
12
+ getTimeRange(): TimeSliderTimeRangeWithDuration;
13
+ }
@@ -0,0 +1 @@
1
+ import{TimeSliderModel as e}from"./TimeSliderModel";import{timeRangesUnion as t}from"./TimeSliderRange";export class CompositeTimeSliderModel extends e{constructor(...e){super(),this.models=e,this.models.forEach(e=>e.on((e,t)=>{"added"===e&&this.emit("added",t),"updated"===e&&this.emit("updated",t),"removed"===e&&this.emit("removed",t)}))}get data(){return this.models.map(e=>e.data).flat()}get(e){return this.models.find(t=>t.get(e))?.get(e)}dataInTimeRange(e){return this.models.map(t=>t.dataInTimeRange(e)).flat()}dataInRange(e){return this.models.map(t=>t.dataInRange(e)).flat()}clear(){return this.models.forEach(e=>e.clear())}getTimeRange(){return this.models.map(e=>e.getTimeRange()).reduce((e,a)=>t(e,a))}}
@@ -0,0 +1,24 @@
1
+ type Interval = {
2
+ id: string;
3
+ t: [start: number, end: number];
4
+ };
5
+ export declare class IntervalLaneManager {
6
+ private intervals;
7
+ private lanes;
8
+ private intervalToLane;
9
+ private gap;
10
+ constructor(gap?: number);
11
+ add(interval: Interval): void;
12
+ remove(id: string): void;
13
+ update(interval: Interval): void;
14
+ private canInsertIntoLane;
15
+ private canStayInLane;
16
+ overlaps(a: Interval, b: Interval): boolean;
17
+ has(id: string): boolean;
18
+ getLane(id: string): number | undefined;
19
+ getLanes(): string[][];
20
+ getLanesAmount(): number;
21
+ private insertIntoLaneSorted;
22
+ private rebuildIndexMaps;
23
+ }
24
+ export {};
@@ -0,0 +1 @@
1
+ export class IntervalLaneManager{constructor(t){this.intervals=new Map,this.lanes=[],this.intervalToLane=new Map,this.gap=t||500}add(t){if(!this.intervals.has(t.id)){this.intervals.set(t.id,t);for(let e=0;e<this.lanes.length;e++){const n=this.lanes[e];if(this.canInsertIntoLane(n,t))return this.insertIntoLaneSorted(n,t),void this.intervalToLane.set(t.id,e)}this.lanes.push([t.id]),this.intervalToLane.set(t.id,this.lanes.length-1)}}remove(t){const e=this.intervals.get(t),n=this.intervalToLane.get(t);if(e&&void 0!==n){const e=this.lanes[n],s=e.findIndex(e=>e===t);-1!==s&&e.splice(s,1),this.intervalToLane.delete(t)}this.intervals.delete(t)}update(t){const e=this.intervals.get(t.id),n=this.intervalToLane.get(t.id);if(!e||void 0===n)return void this.add(t);this.intervals.set(t.id,t);const s=this.lanes[n];if(this.canStayInLane(s,t)){if(t.t[0]!==e.t[0]){const e=s.findIndex(e=>e===t.id);s.splice(e,1),this.insertIntoLaneSorted(s,t)}return}const i=s.findIndex(e=>e===t.id);-1!==i&&s.splice(i,1);for(let e=0;e<this.lanes.length;e++){if(e===n)continue;const s=this.lanes[e];if(this.canInsertIntoLane(s,t))return this.insertIntoLaneSorted(s,t),void this.intervalToLane.set(t.id,e)}this.lanes.push([t.id]),this.intervalToLane.set(t.id,this.lanes.length-1)}canInsertIntoLane(t,e){for(const n of t){const t=this.intervals.get(n);if(t&&this.overlaps(e,t))return!1}return!0}canStayInLane(t,e){for(const n of t){if(n===e.id)continue;const t=this.intervals.get(n);if(t&&this.overlaps(e,t))return!1}return!0}overlaps(t,e){return t.t[0]<e.t[1]+this.gap&&t.t[1]>e.t[0]-this.gap}has(t){return this.intervals.has(t)}getLane(t){return this.intervalToLane.get(t)}getLanes(){return this.lanes}getLanesAmount(){return this.lanes.length}insertIntoLaneSorted(t,e){let n=0;for(;n<t.length;){const s=this.intervals.get(t[n]);if(s&&s.t[0]<e.t[0])break;n++}t.splice(n,0,e.id)}rebuildIndexMaps(){this.intervalToLane.clear();for(let t=0;t<this.lanes.length;t++)for(const e of this.lanes[t])this.intervalToLane.set(e,t)}}
@@ -0,0 +1,23 @@
1
+ import RBush from "rbush";
2
+ import { TimeSliderElement } from "./TimeSliderElement";
3
+ import { TimeSliderRange, TimeSliderTimeRange, TimeSliderTimeRangeArray } from "./TimeSliderRange";
4
+ export declare class TimeSliderBush<T extends TimeSliderElement = TimeSliderElement> extends RBush<T> {
5
+ private idMap;
6
+ constructor();
7
+ private insertSafely;
8
+ add(element: T): void;
9
+ insert(element: T): this;
10
+ remove(element: T): this;
11
+ has(id: string): boolean;
12
+ get(id: string): T | undefined;
13
+ searchTime(range: TimeSliderTimeRange | TimeSliderTimeRangeArray): T[];
14
+ searchRange(range: TimeSliderRange): T[];
15
+ toBBox(element: T): {
16
+ minX: number;
17
+ maxX: number;
18
+ minY: number;
19
+ maxY: number;
20
+ };
21
+ compareMinX(a: T, b: T): number;
22
+ compareMinY(a: T, b: T): number;
23
+ }
@@ -0,0 +1 @@
1
+ import e from"rbush";import{getTimeArray as r,getValueArray as i}from"./TimeSliderElement";import{timeSliderRangeAsObject as t}from"./TimeSliderRange";export class TimeSliderBush extends e{constructor(){super(),this.idMap=new Map}insertSafely(e){return this.idMap.set(e.id,e),super.insert(e),this}add(e){this.insertSafely(e)}insert(e){return this.insertSafely(e),this}remove(e){return this.idMap.delete(e.id),super.remove(e,(e,r)=>e.id===r.id),this}has(e){return this.idMap.has(e)}get(e){return this.idMap.get(e)}searchTime(e){const r=t(e);return super.search({minX:r.startTime,maxX:r.endTime,minY:Number.MIN_VALUE,maxY:Number.MAX_VALUE})}searchRange(e){return super.search({minX:e.startTime,maxX:e.endTime,minY:e.minValue,maxY:e.maxValue})}toBBox(e){const[t,s]=r(e),[n,m]=i(e);return{minX:t,maxX:s,minY:n,maxY:m}}compareMinX(e,i){const[t]=r(e),[s]=r(i);return t-s}compareMinY(e,r){const[t]=i(e),[s]=i(r);return t-s}}
@@ -0,0 +1,21 @@
1
+ import { TimeSliderRange, TimeSliderTimeRangeWithDuration, TimeSliderValueRange } from "./TimeSliderRange";
2
+ export type TimeSliderElement<T = any> = {
3
+ id: string;
4
+ name?: string;
5
+ attributes?: T;
6
+ t: number | [start: number, end: number];
7
+ v: number | [min: number, max: number];
8
+ };
9
+ export type TimeSliderPoint<T = any> = TimeSliderElement<T> & {
10
+ t: number;
11
+ v: number;
12
+ };
13
+ export type TimeSliderInterval<T = any> = TimeSliderElement<T> & {
14
+ t: [start: number, end: number];
15
+ v: [min: number, max: number];
16
+ };
17
+ export declare function toTimeRange(element: TimeSliderElement): TimeSliderTimeRangeWithDuration;
18
+ export declare function toValueRange(element: TimeSliderElement): TimeSliderValueRange;
19
+ export declare function toRange(element: TimeSliderElement): TimeSliderRange;
20
+ export declare function getTimeArray(element: TimeSliderElement): [startTime: number, endTime: number];
21
+ export declare function getValueArray(element: TimeSliderElement): [minValue: number, maxValue: number];
@@ -0,0 +1 @@
1
+ export function toTimeRange(t){return"number"==typeof t.t?{startTime:t.t,endTime:t.t,duration:0}:{startTime:t.t[0],endTime:t.t[1],duration:t.t[1]-t.t[0]}}export function toValueRange(t){return"number"==typeof t.v?{minValue:t.v,maxValue:t.v}:{minValue:t.v[0],maxValue:t.v[1]}}export function toRange(t){return{...toTimeRange(t),...toValueRange(t)}}export function getTimeArray(t){const e=t.t;return[e[0]??e,e[1]??e]}export function getValueArray(t){const e=t.v;return[e[0]??e,e[1]??e]}
@@ -0,0 +1,6 @@
1
+ import { TimeSliderElement, TimeSliderInterval } from "./TimeSliderElement";
2
+ import { TimeSliderModel } from "./TimeSliderModel";
3
+ export declare class TimeSliderIntervalsModel<T = any> extends TimeSliderModel<TimeSliderInterval<T>> {
4
+ constructor(initial?: TimeSliderInterval<T>[]);
5
+ }
6
+ export declare function isTimeInterval(element: TimeSliderElement): element is TimeSliderInterval;
@@ -0,0 +1 @@
1
+ import{TimeSliderModel as r}from"./TimeSliderModel";export class TimeSliderIntervalsModel extends r{constructor(r){super(r)}}export function isTimeInterval(r){return Array.isArray(r.t)&&Array.isArray(r.v)}
@@ -0,0 +1,11 @@
1
+ import { Expand } from "../common/Expand";
2
+ import { TimeSliderInterval } from "./TimeSliderElement";
3
+ import { TimeSliderIntervalsModel } from "./TimeSliderIntervalsModel";
4
+ export type TimeSliderLaneElement<T = any> = Expand<Omit<TimeSliderInterval<T>, 'v'>>;
5
+ export declare class TimeSliderLanesModel<T = any> extends TimeSliderIntervalsModel<T> {
6
+ private laneManager;
7
+ minMax: number;
8
+ constructor(initial?: (TimeSliderLaneElement<T> | TimeSliderInterval<T>)[]);
9
+ add(interval: TimeSliderLaneElement<T> | TimeSliderInterval<T>): void;
10
+ update(intervalOrId: TimeSliderLaneElement<T> | TimeSliderInterval<T> | string, update: Partial<TimeSliderLaneElement<T> | TimeSliderInterval<T>>): void;
11
+ }
@@ -0,0 +1 @@
1
+ import{IntervalLaneManager as e}from"./IntervalLaneManager";import{TimeSliderIntervalsModel as a}from"./TimeSliderIntervalsModel";export class TimeSliderLanesModel extends a{constructor(a){const n=new e;super(a?.map(e=>{n.add(e);const a=n.getLane(e.id)||0;return{...e,v:[a,a+1]}})),this.minMax=4,this.laneManager=n,this.on("removed",e=>this.laneManager.remove(e))}add(e){this.laneManager.add(e);const a=this.laneManager.getLane(e.id)||0,n={...e,v:[a,a+1]};super.add(n)}update(e,a){const n="string"==typeof e?e:e.id,t=this.get(n);if(t){this.laneManager.update({...t,...a});const e=this.laneManager.getLane(t.id)||0,r={...a};Array.isArray(t.v)&&e===t.v[0]||(r.v=[e,e+1]),super.update(n,r)}}}
@@ -0,0 +1,45 @@
1
+ import { TypedEventEmitter } from "../event/TypedEventEmitter";
2
+ import { TimeSliderElement } from "./TimeSliderElement";
3
+ import { TimeSliderRange, TimeSliderTimeRange, TimeSliderTimeRangeArray, TimeSliderTimeRangeWithDuration, TimeSliderValueRange } from "./TimeSliderRange";
4
+ export type TimeSliderElementUpdateEvent<T extends TimeSliderElement = TimeSliderElement> = {
5
+ id: string;
6
+ update: Partial<T>;
7
+ previous: T;
8
+ updated: T;
9
+ };
10
+ export declare abstract class TimeSliderModel<T extends TimeSliderElement = TimeSliderElement> extends TypedEventEmitter<{
11
+ cleared: void;
12
+ loaded: boolean;
13
+ added: T;
14
+ updated: TimeSliderElementUpdateEvent<T>;
15
+ removed: string;
16
+ }> {
17
+ name?: string;
18
+ id: string;
19
+ minMax?: number;
20
+ maxMin?: number;
21
+ private bush;
22
+ private sortedCache;
23
+ private idToIndex;
24
+ private searchCacheRange;
25
+ private searchCache;
26
+ constructor(initial?: T[]);
27
+ get data(): T[];
28
+ clear(): void;
29
+ getNeightbor(elementOrId: string | {
30
+ id: string;
31
+ }, shift: number): T | undefined;
32
+ dataInTimeRange(range: TimeSliderTimeRange | TimeSliderTimeRangeArray | number): T[];
33
+ dataInRange(range: TimeSliderRange): T[];
34
+ toJSON(): any;
35
+ add(element: T): void;
36
+ remove(elementOrId: T | string): void;
37
+ has(id: string): boolean;
38
+ get(id: string): T | undefined;
39
+ update(elementOrId: T | string, update: Partial<T>): void;
40
+ getTimeRange(): TimeSliderTimeRangeWithDuration;
41
+ getValueRange(range?: TimeSliderTimeRange | TimeSliderTimeRangeArray): TimeSliderValueRange;
42
+ private visibleLayers;
43
+ get shouldLoad(): boolean;
44
+ loaded(layerId: string, shouldLoad: boolean): void;
45
+ }
@@ -0,0 +1 @@
1
+ import{v4 as e}from"uuid";import{TypedEventEmitter as t}from"../event/TypedEventEmitter";import{TODAY as s}from"../ticks/TimeSliderConstants";import{TimeSliderBush as i}from"./TimeSliderBush";import{getTimeArray as h}from"./TimeSliderElement";import{timeSliderRangeAsObject as a}from"./TimeSliderRange";export class TimeSliderModel extends t{constructor(t){super(),this.id=e(),this.bush=new i,this.sortedCache=null,this.idToIndex=new Map,this.searchCacheRange=null,this.searchCache=null,this.visibleLayers=new Set,this.bush.load(t||[])}get data(){if(this.sortedCache)return this.sortedCache;{const e=this.bush.all().sort((e,t)=>{const[s]=h(e),[i]=h(t);return s-i});return this.sortedCache=e,this.idToIndex.clear(),e.forEach((e,t)=>this.idToIndex.set(e.id,t)),e}}clear(){this.bush.clear(),this.idToIndex.clear(),this.sortedCache=null,this.searchCache=null,this.emit("cleared")}getNeightbor(e,t){const s=this.data,i="string"==typeof e?e:e.id;if(s&&this.idToIndex.has(i)){const e=this.idToIndex.get(i)+Math.round(t);if(e>0&&e<s.length)return s[e]}}dataInTimeRange(e){const t="number"==typeof e?[e,e]:e,{startTime:s,endTime:i}=a(t);return this.searchCache&&this.searchCacheRange&&this.searchCacheRange.startTime==s&&this.searchCacheRange.endTime==i||(this.searchCache=this.bush.searchTime(t)),this.searchCache}dataInRange(e){return this.bush.searchRange(e)}toJSON(){return this.bush.toJSON()}add(e){Array.isArray(e.v)&&e.v[0]===e.v[1]&&e.v[0]>0&&console.warn(e),this.bush.add(e),this.sortedCache=null,this.searchCache=null,this.emit("added",e);const t=this.bush.get(e.id);Array.isArray(t.v)&&t.v[0]===t.v[1]&&t.v[0]>0&&console.warn({element:e,added:t})}remove(e){const t="string"==typeof e?e:e.id,s=this.bush.get(t);s&&(this.bush.remove(s),this.sortedCache=null,this.searchCache=null,this.emit("removed",s.id))}has(e){return this.bush.has(e)}get(e){return this.bush.get(e)}update(e,t){const s="string"==typeof e?e:e.id,i=this.bush.get(s);if(i){const e={...i};if("t"in t||"v"in t){this.bush.remove(i);const s={...i,...t};this.bush.add(s),this.sortedCache=null,this.searchCache=null,this.emit("updated",{id:i.id,update:t,previous:e,updated:s})}else{for(const e in t)i[e]=t[e];this.emit("updated",{id:i.id,update:t,previous:e,updated:i})}}}getTimeRange(){const e=this.data;if(0===e.length)return s;const t=h(e[0])[0],i=e[e.length-1],a=h(i)[1];return{startTime:t,endTime:a,duration:a-t}}getValueRange(e){if(e){let t=1/0,s=-1/0;const i=this.dataInTimeRange(e);for(const e of i)t=Math.min(t,"number"==typeof e.v?e.v:e.v[0]),s=Math.max(s,"number"==typeof e.v?e.v:e.v[1]);return"number"==typeof this.minMax&&s<this.minMax&&(s=this.minMax),"number"==typeof this.maxMin&&t>this.maxMin&&(t=this.maxMin),{minValue:t,maxValue:s}}{const e=this.bush.toJSON();return{minValue:e.minY,maxValue:e.maxY}}}get shouldLoad(){return this.visibleLayers.size>0}loaded(e,t){t&&!this.visibleLayers.has(e)?(this.visibleLayers.add(e),1===this.visibleLayers.size&&this.emit("loaded",!0)):this.visibleLayers.has(e)&&(this.visibleLayers.delete(e),0===this.visibleLayers.size&&this.emit("loaded",!1))}}
@@ -0,0 +1,6 @@
1
+ import { TimeSliderElement, TimeSliderPoint } from "./TimeSliderElement";
2
+ import { TimeSliderModel } from "./TimeSliderModel";
3
+ export declare class TimeSliderPointsModel<T = any> extends TimeSliderModel<TimeSliderPoint<T>> {
4
+ constructor(initial?: TimeSliderPoint[]);
5
+ }
6
+ export declare function isTimePoint(element: TimeSliderElement): element is TimeSliderPoint;
@@ -0,0 +1 @@
1
+ import{TimeSliderModel as e}from"./TimeSliderModel";export class TimeSliderPointsModel extends e{constructor(e){super(e)}}export function isTimePoint(e){return"number"==typeof e.t&&"number"==typeof e.v}
@@ -0,0 +1,30 @@
1
+ import { Expand } from "../common/Expand";
2
+ export type TimeSliderTimeRange = {
3
+ startTime: number;
4
+ endTime: number;
5
+ };
6
+ export type TimeSliderTimeRangeArray = [
7
+ startTime: number,
8
+ endTime: number
9
+ ];
10
+ export declare function timeSliderRangeAsObject(range: TimeSliderTimeRange | TimeSliderTimeRangeArray): TimeSliderTimeRange;
11
+ export type TimeSliderTimeRangeWithDuration = TimeSliderTimeRange & {
12
+ duration: number;
13
+ };
14
+ export type TimeSliderValueRange = {
15
+ minValue: number;
16
+ maxValue: number;
17
+ };
18
+ export type TimeSliderRange = Expand<TimeSliderTimeRange & TimeSliderValueRange>;
19
+ export type TimeSliderRangeWithDuration = Expand<TimeSliderTimeRangeWithDuration & TimeSliderValueRange>;
20
+ export declare function timeRangesUnion(range1: TimeSliderTimeRange, range2: TimeSliderTimeRange): TimeSliderTimeRangeWithDuration;
21
+ export declare function timeRangesOverlap(range1: TimeSliderTimeRange, target: TimeSliderTimeRange | TimeSliderTimeRangeArray | number): TimeSliderTimeRangeWithDuration | undefined;
22
+ export declare function timeRangeOverlaps(range: TimeSliderTimeRange, target: TimeSliderTimeRange | TimeSliderTimeRangeArray | number): boolean;
23
+ export declare function addPadding(range: TimeSliderTimeRange, padding: number): TimeSliderTimeRangeWithDuration;
24
+ export declare function formatRange(range: TimeSliderTimeRange | TimeSliderTimeRangeWithDuration | [startTime: number, endTime: number]): string[];
25
+ export declare function addDuration(range: TimeSliderTimeRange): {
26
+ duration: number;
27
+ startTime: number;
28
+ endTime: number;
29
+ };
30
+ export declare function applyTimeRangeUpdate(current: TimeSliderTimeRange, update: Partial<TimeSliderTimeRangeWithDuration>): TimeSliderTimeRangeWithDuration;
@@ -0,0 +1 @@
1
+ import{formatDuration as e}from"../common/TimeTools";export function timeSliderRangeAsObject(e){return Array.isArray(e)?{startTime:e[0],endTime:e[1]}:e}export function timeRangesUnion(e,t){const n=Math.min(e.startTime,t.startTime),r=Math.max(e.endTime,t.endTime);return{startTime:n,endTime:r,duration:r-n}}export function timeRangesOverlap(e,t){if("number"==typeof t)return timeRangeOverlaps(e,t)?{startTime:t,endTime:t,duration:0}:void 0;{const n=timeSliderRangeAsObject(t);if(timeRangeOverlaps(e,n)){const t=Math.max(e.startTime,n.startTime),r=Math.min(e.endTime,n.endTime);return{startTime:t,endTime:r,duration:r-t}}return}}export function timeRangeOverlaps(e,t){if("number"==typeof t)return e.startTime<=t&&t<=e.endTime;{const n=timeSliderRangeAsObject(t);return e.startTime<n.endTime&&n.startTime<e.endTime}}export function addPadding(e,t){const n=Math.min(1,Math.max(t,0)),r=e.endTime-e.startTime;return{startTime:e.startTime-n*r,endTime:e.endTime+n*r,duration:(1+2*n)*r}}export function formatRange(t){const n=Array.isArray(t)?t[0]:t.startTime,r=Array.isArray(t)?t[1]:t.endTime,i=r-n;return[new Date(n).toISOString(),e(i),new Date(r).toISOString()]}export function addDuration(e){const t=e.endTime-e.startTime;return{...e,duration:t}}export function applyTimeRangeUpdate(e,t){let n,r;const i=e.endTime-e.startTime;return"number"!=typeof t.duration||"number"==typeof t.startTime&&"number"==typeof t.endTime?(n="number"==typeof t.startTime?t.startTime:e.startTime,r="number"==typeof t.endTime?t.endTime:e.endTime):"number"==typeof t.startTime?(n=t.startTime,r=t.startTime+t.duration):"number"==typeof t.endTime?(n=t.endTime-t.duration,r=t.endTime):(n=e.startTime-.5*(t.duration-i),r=e.endTime+.5*(t.duration-i)),{startTime:n,endTime:r,duration:r-n}}
@@ -0,0 +1,21 @@
1
+ import { TimeSlider } from "../../engine/TimeSlider";
2
+ import { TimeSliderIntervalsModel } from "../TimeSliderIntervalsModel";
3
+ import { TimeSliderModel } from "../TimeSliderModel";
4
+ import { TimeSliderHistogram, TimeSliderHistogramOptions } from "./TimeSliderHistogram";
5
+ export declare class TimeSliderDynamicHistogram<M extends TimeSliderModel = TimeSliderModel> extends TimeSliderHistogram<M> {
6
+ protected model: TimeSliderIntervalsModel;
7
+ protected content: M;
8
+ private prevUpdateLength;
9
+ private needsUpdate;
10
+ private animationFrameId?;
11
+ private maxEncountered;
12
+ constructor(model: TimeSliderIntervalsModel, content: M, options?: TimeSliderHistogramOptions<M>);
13
+ protected startUpdating(timeSlider: TimeSlider): void;
14
+ private invalidate;
15
+ protected stopUpdating(): void;
16
+ protected onOptionsChanged(): void;
17
+ private getAmountOfBoxes;
18
+ private getSegments;
19
+ private calculate;
20
+ private updateBoxes;
21
+ }
@@ -0,0 +1 @@
1
+ import{getTimeUnitInMs as t}from"../../common/TimeTools";import{TimeTicksBar as e}from"../../ticks/TimeTicksBar";import{timeRangeOverlaps as i}from"../TimeSliderRange";import{TimeSliderHistogram as s}from"./TimeSliderHistogram";export class TimeSliderDynamicHistogram extends s{constructor(t,e,i){super(t,e,i),this.model=t,this.content=e,this.prevUpdateLength=0,this.needsUpdate=!1,this.maxEncountered=1e3}startUpdating(t){this.invalidate();const e=e=>{e&&i(t.getTimeRange(),e.t)&&this.invalidate()};this.d.add(this.content.on("added",t=>e(t))),this.d.add(this.content.on("updated",t=>e(t.updated))),this.d.add(this.content.on("removed",()=>this.invalidate())),this.d.add(t.on("time",()=>this.invalidate())),this.d.add(t.on("size",()=>this.invalidate()));const s=()=>{this.needsUpdate&&(this.calculate(),this.needsUpdate=!1),this.animationFrameId=requestAnimationFrame(s)};this.animationFrameId=requestAnimationFrame(s)}invalidate(){this.needsUpdate=!0}stopUpdating(){this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=void 0),this.model.clear()}onOptionsChanged(){this.invalidate()}getAmountOfBoxes(){return this.mode?.amount?this.mode?.amount:Math.round(this.timeSlider.size.width/(this.mode?.pixels||12))}getSegments(){const i=this.timeSlider.getTimeRange(),s=i.startTime,n=i.endTime;if(this.mode?.autoUnits){const i=this.timeSlider.ticksBar.cache.medium.spacing,s=this.timeSlider?.getTimeRange().duration/i,n=this.timeSlider?.size.width/s<(this.mode.autoUnitsMinPixels||8)?this.timeSlider.ticksBar.cache.high:this.timeSlider.ticksBar.cache.medium,a=this.mode.minUnit?t(this.mode.minUnit):0,o=this.mode.maxUnit?t(this.mode.maxUnit):Number.MAX_VALUE;return n.spacing>=a&&n.spacing<=o?n.segments:this.mode.minUnit&&n.spacing<a?e.splitInTimeUnits(this.timeSlider,this.mode.minUnit):this.mode.maxUnit&&n.spacing>o?e.splitInTimeUnits(this.timeSlider,this.mode.maxUnit):[]}{const t=i.duration/this.getAmountOfBoxes(),e=[];for(let i=s;i<n-.5*t;i+=t)e.push({start:i,end:i+t});return e}}calculate(){let t=0;const e=[],i=this.weighted?t=>"number"==typeof t.v?t.v:.5*(t.v[1]+t.v[0]):t=>1,s=new Map,n=this.getSegments();n.forEach((e,n)=>{const a=this.content.dataInTimeRange([e.start,e.end]);let o=0;const h=new Map,d=new Map;if(a.forEach(t=>{const e=this.classifier?this.classifier(t):void 0;if(null!==e){const s=e||"#888",n=i(t);o+=n,this.registerClassification(s),h.has(s)?(h.set(s,h.get(s)+n),d.set(s,d.get(s)+1)):(h.set(s,n),d.set(s,1))}}),this.average){o=0;for(const[t,e]of h){const i=e/d.get(t);o+=i,h.set(t,i)}}s.set(n,h),o>t&&(t=o)});const a=new Map,o=new Map,h=new Set,d=Array.from(this.classOrder);s.forEach((t,i)=>{const m=n[i];let r=0;const c=[];d.forEach(d=>{let l=t.get(d);if(l)a.set(d,{index:i,height:l});else if(this.average&&!h.has(d)&&a.has(d)){let t;if(o.has(d))t=o.get(d);else{for(let e=i;e<n.length;e++){const i=s.get(e);i&&i.has(d)&&(t={index:e,height:i.get(d)})}t&&o.set(d,t)}if(t){const e=a.get(d),i=n[e.index],s=n[t.index],o=(m.start-i.start)/(s.start-i.start);l=e.height+o*(t.height-e.height)}else h.add(d)}if(l){const t={height:l,...m,bottom:r,classification:d};e.push(t),c.push(t),r+=l}}),c.forEach(t=>t.percentage=t.height/r)}),this.updateBoxes(e,t)}updateBoxes(t,e){if(e>this.maxEncountered&&(this.maxEncountered=e+100),this.maxValue=e,t.forEach((t,e)=>{const i=e+"",s=this.model.has(i),n={attributes:{classification:t.classification,percentage:t.percentage},t:[t.start,t.end],v:this.inverted?[this.maxEncountered-t.bottom-t.height,this.maxEncountered-t.bottom]:[t.bottom,t.bottom+t.height]};n.v[0]===n.v[1]&&console.warn(n),s?this.model.update(i,n):this.model.add({id:i,...n})}),this.prevUpdateLength>t.length)for(let e=t.length;e<this.prevUpdateLength;e++){const t=e+"";this.model.update(t,{v:[0,0]})}this.prevUpdateLength=t.length}}
@@ -0,0 +1,52 @@
1
+ import { TimeSlider } from "../../engine/TimeSlider";
2
+ import { TimeSliderModelElement } from "../../layer/TimeSliderLayer";
3
+ import { TimeSliderIntervalsModel } from "../TimeSliderIntervalsModel";
4
+ import { TimeSliderModel } from "../TimeSliderModel";
5
+ import { TimeSliderHistogram, TimeSliderHistogramOptions } from "./TimeSliderHistogram";
6
+ type Box = {
7
+ index: number;
8
+ classification?: string;
9
+ start: number;
10
+ end: number;
11
+ values: Map<string, number>;
12
+ };
13
+ export declare class TimeSliderFixedHistogram<M extends TimeSliderModel = TimeSliderModel> extends TimeSliderHistogram<M> {
14
+ protected model: TimeSliderIntervalsModel;
15
+ protected content: M;
16
+ private time0;
17
+ private duration;
18
+ private elementClasifications;
19
+ private elementBoxRanges;
20
+ private classificationIndices;
21
+ private boxes;
22
+ private currentIntervals;
23
+ private maxValueCheckingInterval?;
24
+ private maxEncountered;
25
+ loggin: boolean;
26
+ constructor(model: TimeSliderIntervalsModel, content: M, options?: TimeSliderHistogramOptions<M>);
27
+ protected startUpdating(timeSlider: TimeSlider): void;
28
+ protected stopUpdating(): void;
29
+ protected onOptionsChanged(changedOption: keyof TimeSliderHistogramOptions<M>): void;
30
+ populate(): void;
31
+ addElement(added: TimeSliderModelElement<M>): void;
32
+ updateElement(updated: TimeSliderModelElement<M>): void;
33
+ removeElement(id: string): void;
34
+ requireClassificationIndex(classification?: string): number;
35
+ getBox(index: number, classification?: string): Box | undefined;
36
+ getBoxIndex(time: number): number;
37
+ getIntervalId(box: {
38
+ index: number;
39
+ classification?: string;
40
+ }): string;
41
+ getBoxRange(time: number | [start: number, end: number]): [number, number];
42
+ createBox(index: number, classification?: string): Box;
43
+ requireBox(index: number, classification?: string): Box;
44
+ forBoxRange(range: [number, number], callback: (box: Box) => void, options?: {
45
+ create?: boolean;
46
+ classification?: string;
47
+ }): void;
48
+ getBoxValue(box: Box): number;
49
+ updateBoxInterval(box: Box): void;
50
+ toSingleValue(value: number | [number, number]): number;
51
+ }
52
+ export {};
@@ -0,0 +1 @@
1
+ import{getTimeOffset as t,getTimeUnitRange as e}from"../../common/TimeTools";import{ONE_HOUR as i}from"../../ticks/TimeSliderConstants";import{TimeSliderHistogram as s}from"./TimeSliderHistogram";export class TimeSliderFixedHistogram extends s{constructor(t,e,s){super(t,e,s),this.model=t,this.content=e,this.elementClasifications=new Map,this.elementBoxRanges=new Map,this.classificationIndices=new Map,this.boxes=new Map,this.currentIntervals=new Set,this.maxEncountered=1e3,this.loggin=!1,this.loggin=s?.loggin||!1,this.time0=this.mode?.fixed?.start||Date.UTC(0,0,1,0,0,0,0),this.duration=this.mode?.fixed?.duration||i,this.populate(),this.content.on("added",t=>{t&&this.addElement(t)}),this.content.on("updated",t=>{const e=t.updated;e&&this.updateElement(e)}),this.content.on("removed",t=>{this.elementBoxRanges.get(t)&&this.removeElement(t)})}startUpdating(t){this.maxValueCheckingInterval=setInterval(()=>{this.checkMaxValue()},1e3)}stopUpdating(){clearInterval(this.maxValueCheckingInterval),this.maxValueCheckingInterval=void 0}onOptionsChanged(t){if("classifier"===t){this.elementClasifications.clear(),this.classificationIndices.clear(),this.boxes.clear();const t=new Set(this.currentIntervals);this.currentIntervals.clear(),this.populate(),t.forEach(t=>{this.currentIntervals.has(t)||(this.loggin&&console.log("Turning invisible",t),this.model.update(t,{v:[0,0]}))})}}populate(){this.classOrder.forEach((t,e)=>this.classificationIndices.set(t,e)),this.time0=this.mode?.fixed?.start||Date.UTC(0,0,1,0,0,0,0),this.duration=this.mode?.fixed?.duration||i;this.content.data.forEach(t=>this.addElement(t))}addElement(t){const e=this.getBoxRange(t.t);this.elementBoxRanges.set(t.id,e);const i=this.weighted?this.toSingleValue(t.v):1,s=this.classifier?this.classifier(t):void 0;null!==s&&(this.elementClasifications.set(t.id,s),this.forBoxRange(e,e=>{e.values.set(t.id,i),this.updateBoxInterval(e)},{create:!0,classification:s}))}updateElement(t){const e=this.classifier?this.classifier(t):void 0;if(null===e)this.removeElement(t.id);else{this.elementClasifications.set(t.id,e);const i=this.elementBoxRanges.get(t.id);if(i){const s=this.getBoxRange(t.t);this.elementBoxRanges.set(t.id,s);const n=[];for(let s=i[0];s<=i[1];s++){const i=this.getBox(s,e);i&&(i.values.delete(t.id),n.push(s))}const a=this.weighted?this.toSingleValue(t.v):1;for(let i=s[0];i<=s[1];i++){this.requireBox(i,e).values.set(t.id,a),n.push(i)}n.forEach(t=>{const i=this.getBox(t,e);i&&this.updateBoxInterval(i)})}else this.addElement(t)}}removeElement(t){const e=this.elementBoxRanges.get(t),i=this.elementClasifications.get(t);if(this.elementBoxRanges.delete(t),e)for(let s=e[0];s<=e[1];s++){const e=this.getBox(s,i);e&&(e.values.delete(t),this.updateBoxInterval(e))}}requireClassificationIndex(t){return this.classificationIndices.has(t||null)||this.classificationIndices.set(t||null,this.classificationIndices.size),this.classificationIndices.get(t||null)}getBox(t,e){if(this.boxes.has(t)){return this.boxes.get(t).get(this.requireClassificationIndex(e))}}getBoxIndex(e){return this.mode?.fixedUnit?t(this.time0,e,this.mode?.fixedUnit):Math.floor((e-this.time0)/this.duration)}getIntervalId(t){const e=this.requireClassificationIndex(t.classification);return t.index+"#"+e}getBoxRange(t){if("number"==typeof t){const e=this.getBoxIndex(t);return[e,e]}return t.map(this.getBoxIndex)}createBox(t,i){let s,n;if(this.mode?.fixedUnit){const{startTime:i,endTime:a}=e(this.time0,this.mode?.fixedUnit,t);s=i,n=a}else s=this.time0+t*this.duration,n=this.time0+t*this.duration+this.duration;const a=this.requireClassificationIndex(i),o=this.getIntervalId({index:t,classification:i});this.boxes.has(t)||this.boxes.set(t,new Map);const l=this.boxes.get(t);l.has(a)&&console.warn("Box already exists..");const r={index:t,classification:i,start:s,end:n,values:new Map};return l.set(a,r),i&&this.registerClassification(i),this.currentIntervals.add(o),this.model.has(o)?(this.loggin&&console.log("Reusing",o),this.model.update(o,{attributes:{classification:i}})):(this.loggin&&console.log("Creating",o),this.model.add({id:o,attributes:{classification:i},t:[s,n],v:[0,0]})),r}requireBox(t,e){const i=this.getBox(t,e);return i||this.createBox(t,e)}forBoxRange(t,e,i){const s=i?.classification;for(let n=t[0];n<=t[1];n++){const t=i?.create?this.requireBox(n,s):this.getBox(n,s);t&&e(t)}}getBoxValue(t){return this.weighted?Array.from(t.values.values()).reduce((t,e)=>t+e):t.values.size}updateBoxInterval(t){const e=this.getIntervalId(t),i=this.model.get(e),s=this.getBoxValue(t);if(i)if(this.classifier){let i=0;const n=this.classOrder.map(e=>{const i=this.getIntervalId({index:t.index,classification:e});if(this.currentIntervals.has(i)){const t=this.model.get(i);return{classification:e,value:t?t.v[1]-t.v[0]:void 0,id:i}}return null}).filter(t=>null!==t);n.forEach(e=>{e.classification===t.classification?i+=s:i+=e.value||0}),i>this.maxEncountered&&(this.maxEncountered=i+100);let a=0,o=!1;n.forEach(n=>{o?n.value&&(this.loggin&&console.log("- Shifting",n.id),this.model.update(n.id,{v:this.inverted?[this.maxEncountered-a-n.value,this.maxEncountered-a]:[a,a+n.value],attributes:{classification:n.classification,percentage:n.value/i}}),a+=n.value):n.classification===t.classification?(this.loggin&&console.log("- Setting value",e),this.model.update(e,{v:this.inverted?[this.maxEncountered-a-s,this.maxEncountered-a]:[a,a+s],attributes:{classification:n.classification,percentage:s/i}}),o=!0,a+=s):n.value&&(this.loggin&&console.log("- Percentage",n.id),this.model.update(n.id,{attributes:{classification:n.classification,percentage:n.value/i}}),a+=n.value)})}else this.loggin&&console.log("- Setting value (no classification)",e),this.model.update(e,{v:this.inverted?[this.maxEncountered-s,0]:[0,s]})}toSingleValue(t){return"number"==typeof t?t:.5*(t[0]+t[1])}}
@@ -0,0 +1,68 @@
1
+ import { Disposables } from "../../common/Disposables";
2
+ import { TimeUnit } from "../../common/TimeTools";
3
+ import { TimeSlider } from "../../engine/TimeSlider";
4
+ import { TimeSliderModelElement } from "../../layer/TimeSliderLayer";
5
+ import { TimeSliderIntervalsModel } from "../TimeSliderIntervalsModel";
6
+ import { TimeSliderModel } from "../TimeSliderModel";
7
+ export type TimeSliderHistogramAttributes = {
8
+ classification?: string;
9
+ percentage?: number;
10
+ splits?: number[];
11
+ };
12
+ export type TimeSliderHistogramClassifier<M extends TimeSliderModel = TimeSliderModel> = (element: TimeSliderModelElement<M>) => string | null | undefined;
13
+ export type TimeSliderHistogramMode = {
14
+ fixed?: {
15
+ start?: number;
16
+ duration?: number;
17
+ };
18
+ fixedUnit?: TimeUnit;
19
+ pixels?: number;
20
+ amount?: number;
21
+ autoUnits?: boolean;
22
+ autoUnitsMinPixels?: number;
23
+ minUnit?: TimeUnit;
24
+ maxUnit?: TimeUnit;
25
+ };
26
+ export type TimeSliderHistogramOptions<M extends TimeSliderModel = TimeSliderModel> = {
27
+ classOrder?: string[];
28
+ classifier?: TimeSliderHistogramClassifier<M>;
29
+ mode?: TimeSliderHistogramMode;
30
+ average?: boolean;
31
+ weighted?: boolean;
32
+ loggin?: boolean;
33
+ inverted?: boolean;
34
+ };
35
+ export declare abstract class TimeSliderHistogram<M extends TimeSliderModel = TimeSliderModel> {
36
+ protected model: TimeSliderIntervalsModel;
37
+ protected content: M;
38
+ protected d: Disposables;
39
+ private _classifier?;
40
+ private _average;
41
+ private _weighted;
42
+ private _inverted;
43
+ private _mode;
44
+ protected classOrderSet: Set<string>;
45
+ protected timeSlider?: TimeSlider;
46
+ protected started: boolean;
47
+ maxValue: number;
48
+ constructor(model: TimeSliderIntervalsModel, content: M, options?: TimeSliderHistogramOptions<M>);
49
+ protected abstract startUpdating(timeSlider: TimeSlider): void;
50
+ protected abstract stopUpdating(): void;
51
+ protected abstract onOptionsChanged(changedOption: keyof TimeSliderHistogramOptions<M>): void;
52
+ start(timeSlider: TimeSlider): void;
53
+ stop(): void;
54
+ get classOrder(): string[];
55
+ set classOrder(newOrder: string[]);
56
+ protected registerClassification(classification: string): void;
57
+ get classifier(): TimeSliderHistogramClassifier<M> | undefined;
58
+ set classifier(newClassifier: TimeSliderHistogramClassifier<M> | undefined);
59
+ get mode(): TimeSliderHistogramMode;
60
+ set mode(newMode: TimeSliderHistogramMode);
61
+ get average(): boolean;
62
+ set average(newValue: boolean);
63
+ get inverted(): boolean;
64
+ set inverted(newValue: boolean);
65
+ get weighted(): boolean;
66
+ set weighted(newValue: boolean);
67
+ checkMaxValue(): void;
68
+ }
@@ -0,0 +1 @@
1
+ import{Disposables as e}from"../../common/Disposables";export class TimeSliderHistogram{constructor(t,s,i){this.model=t,this.content=s,this.d=new e,this.classOrderSet=new Set,this.started=!1,this.maxValue=1,this._classifier=i?.classifier,this.classOrderSet=new Set(i?.classOrder),this._average=!0===i?.average,this._weighted=!0===i?.weighted,this._inverted=!0===i?.inverted,this._mode=i?.mode||{pixels:12}}start(e){this.started||(this.started=!0,this.timeSlider=e,this.startUpdating(e))}stop(){this.started&&(this.started=!1,this.d.dispose(),this.d=new e,this.stopUpdating())}get classOrder(){return Array.from(this.classOrderSet)}set classOrder(e){this.classOrderSet=new Set(e),this.onOptionsChanged("classOrder")}registerClassification(e){this.classOrderSet.add(e)}get classifier(){return this._classifier}set classifier(e){this._classifier=e,this.onOptionsChanged("classifier")}get mode(){return this._mode}set mode(e){JSON.stringify(e)!==JSON.stringify(this._mode)&&(this._mode=e,this.onOptionsChanged("mode"))}get average(){return this._average}set average(e){e!==this._average&&(this._average=e,this.onOptionsChanged("average"))}get inverted(){return this._inverted}set inverted(e){e!==this._inverted&&(this._inverted=e,this.onOptionsChanged("inverted"))}get weighted(){return this._weighted}set weighted(e){e!==this._weighted&&(this._weighted=e,this.onOptionsChanged("weighted"))}checkMaxValue(){if(this.timeSlider){let e=0;this.model.dataInTimeRange(this.timeSlider.getTimeRange()).forEach(t=>{t.v[1]>e&&(e=t.v[1])}),this.maxValue=e}}}
@@ -0,0 +1,45 @@
1
+ import { TimeSlider } from "../../engine/TimeSlider";
2
+ import { TimeSliderModelElement } from "../../layer/TimeSliderLayer";
3
+ import { TimeSliderIntervalsModel } from "../TimeSliderIntervalsModel";
4
+ import { TimeSliderModel } from "../TimeSliderModel";
5
+ import { TimeSliderHistogram, TimeSliderHistogramOptions } from "./TimeSliderHistogram";
6
+ type Box = {
7
+ index: number;
8
+ start: number;
9
+ end: number;
10
+ values: {
11
+ [classification: string]: Map<string, number>;
12
+ };
13
+ };
14
+ export declare class TimeSliderSplittingFixedHistogram<M extends TimeSliderModel = TimeSliderModel> extends TimeSliderHistogram<M> {
15
+ protected model: TimeSliderIntervalsModel;
16
+ protected content: M;
17
+ private time0;
18
+ private duration;
19
+ private elementClasifications;
20
+ private elementBoxRanges;
21
+ private classificationIndices;
22
+ private boxes;
23
+ private maxEncountered;
24
+ loggin: boolean;
25
+ constructor(model: TimeSliderIntervalsModel, content: M, options?: TimeSliderHistogramOptions<M>);
26
+ protected startUpdating(timeSlider: TimeSlider): void;
27
+ protected stopUpdating(): void;
28
+ protected onOptionsChanged(changedOption: keyof TimeSliderHistogramOptions<M>): void;
29
+ populate(): void;
30
+ addElement(added: TimeSliderModelElement<M>, willAddInterval?: boolean): void;
31
+ updateElement(updated: TimeSliderModelElement<M>): void;
32
+ removeElement(id: string): void;
33
+ getBox(index: number): Box | undefined;
34
+ getBoxIndex(time: number): number;
35
+ getBoxRange(time: number | [start: number, end: number]): [number, number];
36
+ createBox(index: number): Box;
37
+ requireBox(index: number): Box;
38
+ forBoxRange(range: [number, number], callback: (box: Box) => void, options?: {
39
+ create?: boolean;
40
+ }): void;
41
+ getBoxValue(box: Box): number;
42
+ updateBoxInterval(box: Box): void;
43
+ toSingleValue(value: number | [number, number]): number;
44
+ }
45
+ export {};