@internetarchive/histogram-date-range 0.1.3-alpha → 0.1.6-alpha1

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.
@@ -45,9 +45,9 @@ async function createCustomElementInHTMLContainer(): Promise<HistogramDateRange>
45
45
  describe('HistogramDateRange', () => {
46
46
  it('shows scaled histogram bars when provided with data', async () => {
47
47
  const el = await createCustomElementInHTMLContainer();
48
- const bars = el.shadowRoot?.querySelectorAll(
48
+ const bars = (el.shadowRoot?.querySelectorAll(
49
49
  '.bar'
50
- ) as unknown as SVGRectElement[];
50
+ ) as unknown) as SVGRectElement[];
51
51
  const heights = Array.from(bars).map(b => b.height.baseVal.value);
52
52
 
53
53
  expect(heights).to.eql([38, 7, 50]);
@@ -276,9 +276,9 @@ describe('HistogramDateRange', () => {
276
276
  // include a number which will require commas (1,000,000)
277
277
  el.bins = [1000000, 1, 100];
278
278
  await aTimeout(10);
279
- const bars = el.shadowRoot?.querySelectorAll(
279
+ const bars = (el.shadowRoot?.querySelectorAll(
280
280
  '.bar'
281
- ) as unknown as SVGRectElement[];
281
+ ) as unknown) as SVGRectElement[];
282
282
  const tooltip = el.shadowRoot?.querySelector('#tooltip') as HTMLDivElement;
283
283
  expect(tooltip.innerText).to.eq('');
284
284
 
@@ -304,9 +304,9 @@ describe('HistogramDateRange', () => {
304
304
 
305
305
  it('does not show tooltip while dragging', async () => {
306
306
  const el = await createCustomElementInHTMLContainer();
307
- const bars = el.shadowRoot?.querySelectorAll(
307
+ const bars = (el.shadowRoot?.querySelectorAll(
308
308
  '.bar'
309
- ) as unknown as SVGRectElement[];
309
+ ) as unknown) as SVGRectElement[];
310
310
  const tooltip = el.shadowRoot?.querySelector('#tooltip') as HTMLDivElement;
311
311
  expect(tooltip.innerText).to.eq('');
312
312
  const minSlider = el.shadowRoot?.querySelector('#slider-min') as SVGElement;
@@ -492,13 +492,27 @@ describe('HistogramDateRange', () => {
492
492
  </histogram-date-range>
493
493
  `
494
494
  );
495
- const bars = el.shadowRoot?.querySelectorAll(
495
+ const bars = (el.shadowRoot?.querySelectorAll(
496
496
  '.bar'
497
- ) as unknown as SVGRectElement[];
497
+ ) as unknown) as SVGRectElement[];
498
498
  const heights = Array.from(bars).map(b => b.height.baseVal.value);
499
499
  expect(heights).to.eql([157]);
500
500
  });
501
501
 
502
+ it('correctly displays small diff between max and min values', async () => {
503
+ const el = await fixture<HistogramDateRange>(
504
+ html`
505
+ <histogram-date-range bins="[1519,2643,1880,2041,1638,1441]">
506
+ </histogram-date-range>
507
+ `
508
+ );
509
+ const bars = (el.shadowRoot?.querySelectorAll(
510
+ '.bar'
511
+ ) as unknown) as SVGRectElement[];
512
+ const heights = Array.from(bars).map(b => b.height.baseVal.value);
513
+ expect(heights).to.eql([37, 40, 38, 38, 37, 36]);
514
+ });
515
+
502
516
  it('has a disabled state', async () => {
503
517
  const el = await fixture<HistogramDateRange>(
504
518
  html`
@@ -554,4 +568,28 @@ describe('HistogramDateRange', () => {
554
568
  ?.attributes?.getNamedItem('mode')?.value
555
569
  ).to.eq('processing');
556
570
  });
571
+
572
+ it('can use LitElement bound properties', async () => {
573
+ const el = await fixture<HistogramDateRange>(
574
+ html`
575
+ <histogram-date-range
576
+ .minDate=${1900}
577
+ .maxDate=${'Dec 4, 2020'}
578
+ .minSelectedDate=${2012}
579
+ .maxSelectedDate=${2019}
580
+ .bins=${[33, 1, 100]}
581
+ >
582
+ </histogram-date-range>
583
+ `
584
+ );
585
+ const minDateInput = el.shadowRoot?.querySelector(
586
+ '#date-min'
587
+ ) as HTMLInputElement;
588
+ expect(minDateInput.value).to.eq('2012');
589
+
590
+ const maxDateInput = el.shadowRoot?.querySelector(
591
+ '#date-max'
592
+ ) as HTMLInputElement;
593
+ expect(maxDateInput.value).to.eq('2019');
594
+ });
557
595
  });
package/dist/index.d.ts DELETED
@@ -1 +0,0 @@
1
- export { HistogramDateRange } from './src/histogram-date-range';
package/dist/index.js DELETED
@@ -1,2 +0,0 @@
1
- export { HistogramDateRange } from './src/histogram-date-range';
2
- //# sourceMappingURL=index.js.map
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC","sourcesContent":["export { HistogramDateRange } from './src/histogram-date-range';\n"]}
@@ -1,58 +0,0 @@
1
- import { LitElement, TemplateResult, SVGTemplateResult } from 'lit-element';
2
- interface HistogramInputData {
3
- minDate: string;
4
- maxDate: string;
5
- bins: number[];
6
- }
7
- export declare class HistogramDateRange extends LitElement {
8
- width: number;
9
- height: number;
10
- sliderWidth: number;
11
- tooltipWidth: number;
12
- tooltipHeight: number;
13
- dateFormat: string;
14
- data?: HistogramInputData;
15
- minSliderX: number;
16
- maxSliderX: number;
17
- tooltipOffset: number;
18
- tooltipContent: TemplateResult | '';
19
- tooltipDisplay: 'block' | 'none';
20
- tooltip: HTMLDivElement;
21
- container: HTMLDivElement;
22
- private _minDate;
23
- private _maxDate;
24
- private _dragOffset;
25
- private _histWidth;
26
- private _numBins;
27
- private _binWidth;
28
- private _currentSlider?;
29
- private _histData;
30
- firstUpdated(): void;
31
- private generateHistData;
32
- private get dateRange();
33
- private showTooltip;
34
- private hideTooltip;
35
- private drag;
36
- private drop;
37
- private move;
38
- private setDragOffset;
39
- private setMinSlider;
40
- private setMaxSlider;
41
- private translatePositionToDate;
42
- private translateDateToPosition;
43
- private handleMinDateInput;
44
- private handleMaxDateInput;
45
- private get minInputValue();
46
- private get maxInputValue();
47
- private get minSliderTemplate();
48
- private get maxSliderTemplate();
49
- private generateSliderSVG;
50
- get selectedRangeTemplate(): SVGTemplateResult;
51
- get histogramTemplate(): SVGTemplateResult[];
52
- get minInputTemplate(): TemplateResult;
53
- get maxInputTemplate(): TemplateResult;
54
- get tooltipTemplate(): TemplateResult;
55
- static styles: import("lit-element").CSSResult;
56
- render(): TemplateResult;
57
- }
58
- export {};
@@ -1,447 +0,0 @@
1
- import { __decorate } from "tslib";
2
- import { html, svg, css, internalProperty, LitElement, property, query, } from 'lit-element';
3
- import dayjs from 'dayjs/esm/index.js';
4
- // these values can be overridden via the component's HTML (camelCased) attributes
5
- const WIDTH = 180;
6
- const HEIGHT = 40;
7
- const SLIDER_WIDTH = 10;
8
- const TOOLTIP_WIDTH = 125;
9
- const TOOLTIP_HEIGHT = 30;
10
- const DATE_FORMAT = 'M/D/YYYY';
11
- // this constant is not set up to be overridden
12
- const SLIDER_CORNER_SIZE = 4;
13
- // these CSS custom props can be overridden from the HTML that is invoking this component
14
- const sliderFill = 'var(--histogramDateRangeSliderFill, #4B65FE)';
15
- const selectedRangeFill = 'var(--histogramDateRangeSelectedRangeFill, #DBE0FF)';
16
- const barIncludedFill = 'var(--histogramDateRangeBarIncludedFill, #2C2C2C)';
17
- const barExcludedFill = 'var(--histogramDateRangeBarExcludedFill, #CCCCCC)';
18
- const inputBorder = css `var(--histogramDateRangeInputBorder, 0.5px solid #2C2C2C)`;
19
- const inputWidth = css `var(--histogramDateRangeInputWidth, 70px)`;
20
- const inputFontSize = css `var(--histogramDateRangeInputFontSize, 1.2rem)`;
21
- const tooltipBackgroundColor = css `var(--histogramDateRangeTooltipBackgroundColor, #2C2C2C)`;
22
- const tooltipTextColor = css `var(--histogramDateRangeTooltipTextColor, #FFFFFF)`;
23
- const tooltipFontSize = css `var(--histogramDateRangeTooltipFontSize, 1.1rem)`;
24
- export class HistogramDateRange extends LitElement {
25
- constructor() {
26
- /* eslint-disable lines-between-class-members */
27
- super(...arguments);
28
- // these properties are intended to be passed in as attributes
29
- this.width = WIDTH;
30
- this.height = HEIGHT;
31
- this.sliderWidth = SLIDER_WIDTH;
32
- this.tooltipWidth = TOOLTIP_WIDTH;
33
- this.tooltipHeight = TOOLTIP_HEIGHT;
34
- this.dateFormat = DATE_FORMAT;
35
- this.minSliderX = 0;
36
- this.maxSliderX = 0;
37
- this.tooltipOffset = 0;
38
- this.tooltipContent = '';
39
- this.tooltipDisplay = 'none';
40
- // these properties don't need to be tracked for changes
41
- this._minDate = 0;
42
- this._maxDate = 0;
43
- this._dragOffset = 0;
44
- this._histWidth = 0;
45
- this._numBins = 0;
46
- this._binWidth = 0;
47
- this._histData = [];
48
- // use arrow functions (rather than standard JS class instance methods) so
49
- // that `this` is bound to the histogramDateRange object and not the event
50
- // target. for more info see
51
- // https://lit-element.polymer-project.org/guide/events#using-this-in-event-listeners
52
- this.drag = (e) => {
53
- // prevent selecting text or other ranges while dragging, especially in Safari
54
- e.preventDefault();
55
- this.setDragOffset(e);
56
- this.container.classList.add('dragging');
57
- window.addEventListener('pointermove', this.move);
58
- window.addEventListener('pointerup', this.drop);
59
- window.addEventListener('pointercancel', this.drop);
60
- };
61
- this.drop = () => {
62
- this.container.classList.remove('dragging');
63
- window.removeEventListener('pointermove', this.move);
64
- window.removeEventListener('pointerup', this.drop);
65
- window.removeEventListener('pointercancel', this.drop);
66
- };
67
- this.move = (e) => {
68
- const newX = e.offsetX - this._dragOffset;
69
- const slider = this._currentSlider;
70
- return slider.id === 'slider-min'
71
- ? this.setMinSlider(newX)
72
- : this.setMaxSlider(newX);
73
- };
74
- }
75
- /* eslint-enable lines-between-class-members */
76
- firstUpdated() {
77
- var _a, _b, _c, _d, _e;
78
- this.minSliderX = this.sliderWidth;
79
- this.maxSliderX = this.width - this.sliderWidth;
80
- this._minDate = dayjs((_a = this.data) === null || _a === void 0 ? void 0 : _a.minDate).valueOf();
81
- this._maxDate = dayjs((_b = this.data) === null || _b === void 0 ? void 0 : _b.maxDate).valueOf();
82
- this._histWidth = this.width - this.sliderWidth * 2;
83
- this._numBins = (_e = (_d = (_c = this.data) === null || _c === void 0 ? void 0 : _c.bins) === null || _d === void 0 ? void 0 : _d.length) !== null && _e !== void 0 ? _e : 1;
84
- this._binWidth = this._histWidth / this._numBins;
85
- this._histData = this.generateHistData();
86
- }
87
- generateHistData() {
88
- if (!this.data) {
89
- return [];
90
- }
91
- const minValue = Math.min(...this.data.bins);
92
- const maxValue = Math.max(...this.data.bins);
93
- const valueScale = this.height / Math.log1p(maxValue - minValue);
94
- const dateScale = this.dateRange / this._numBins;
95
- return this.data.bins.map((v, i) => {
96
- return {
97
- value: v,
98
- height: Math.floor(Math.log1p(v) * valueScale),
99
- binStart: `${dayjs(i * dateScale + this._minDate).format(this.dateFormat)}`,
100
- binEnd: `${dayjs((i + 1) * dateScale + this._minDate).format(this.dateFormat)}`,
101
- };
102
- });
103
- }
104
- get dateRange() {
105
- return this._maxDate - this._minDate;
106
- }
107
- showTooltip(e) {
108
- if (Array.from(this.container.classList).includes('dragging')) {
109
- return;
110
- }
111
- const target = e.currentTarget;
112
- const x = target.x.baseVal.value + this.sliderWidth / 2;
113
- const data = target.dataset;
114
- const itemsText = `item${data.numItems !== '1' ? 's' : ''}`;
115
- this.tooltipOffset =
116
- x + (this._binWidth - this.sliderWidth - this.tooltipWidth) / 2;
117
- this.tooltipContent = html `
118
- ${data.numItems} ${itemsText}<br />
119
- ${data.binStart} - ${data.binEnd}
120
- `;
121
- this.tooltipDisplay = 'block';
122
- }
123
- hideTooltip() {
124
- this.tooltipContent = '';
125
- this.tooltipDisplay = 'none';
126
- }
127
- // find position of pointer in relation to the current slider
128
- setDragOffset(e) {
129
- this._currentSlider = e.currentTarget;
130
- const sliderX = this._currentSlider.id === 'slider-min'
131
- ? this.minSliderX
132
- : this.maxSliderX;
133
- this._dragOffset = e.offsetX - sliderX;
134
- // work around Firefox issue where e.offsetX seems to be not based on current
135
- // element but on background element
136
- if (this._dragOffset > this.sliderWidth ||
137
- this._dragOffset < -this.sliderWidth) {
138
- this._dragOffset = 0;
139
- }
140
- }
141
- setMinSlider(newX) {
142
- const toSet = Math.max(newX, this.sliderWidth);
143
- this.minSliderX = Math.min(toSet, this.maxSliderX);
144
- }
145
- setMaxSlider(newX) {
146
- const toSet = Math.max(newX, this.minSliderX);
147
- this.maxSliderX = Math.min(toSet, this.width - this.sliderWidth);
148
- }
149
- translatePositionToDate(x) {
150
- const milliseconds = ((x - this.sliderWidth) * this.dateRange) / this._histWidth;
151
- const date = dayjs(this._minDate + milliseconds);
152
- return date.format(this.dateFormat);
153
- }
154
- translateDateToPosition(date) {
155
- const milliseconds = dayjs(date).valueOf();
156
- if (!milliseconds) {
157
- return null;
158
- }
159
- // translate where we are within the date range into what the new x-position
160
- // of the slider should be
161
- return (this.sliderWidth +
162
- ((milliseconds - this._minDate) * this._histWidth) / this.dateRange);
163
- }
164
- handleMinDateInput(e) {
165
- const target = e.currentTarget;
166
- const newX = this.translateDateToPosition(target.value);
167
- if (newX) {
168
- this.setMinSlider(newX);
169
- }
170
- target.value = this.minInputValue;
171
- }
172
- handleMaxDateInput(e) {
173
- const target = e.currentTarget;
174
- const newX = this.translateDateToPosition(target.value);
175
- if (newX) {
176
- this.setMaxSlider(newX);
177
- }
178
- target.value = this.maxInputValue;
179
- }
180
- get minInputValue() {
181
- return this.translatePositionToDate(this.minSliderX);
182
- }
183
- get maxInputValue() {
184
- return this.translatePositionToDate(this.maxSliderX);
185
- }
186
- get minSliderTemplate() {
187
- // width/height in pixels of curved part of the sliders (like
188
- // border-radius); used as part of a SVG quadratic curve. see
189
- // https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths#curve_commands
190
- const c = SLIDER_CORNER_SIZE;
191
- const sliderShape = `
192
- M${this.minSliderX},0
193
- h-${this.sliderWidth - c}
194
- q-${c},0 -${c},${c}
195
- v${this.height - c * 2}
196
- q0,${c} ${c},${c}
197
- h${this.sliderWidth - c}
198
- `;
199
- return this.generateSliderSVG(this.minSliderX, 'slider-min', sliderShape);
200
- }
201
- get maxSliderTemplate() {
202
- const c = SLIDER_CORNER_SIZE;
203
- const sliderShape = `
204
- M${this.maxSliderX},0
205
- h${this.sliderWidth - c}
206
- q${c},0 ${c},${c}
207
- v${this.height - c * 2}
208
- q0,${c} -${c},${c}
209
- h-${this.sliderWidth - c}
210
- `;
211
- return this.generateSliderSVG(this.maxSliderX, 'slider-max', sliderShape);
212
- }
213
- generateSliderSVG(sliderPositionX, id, sliderShape) {
214
- // whether the curved part of the slider is facing towards the left (1), ie
215
- // minimum, or facing towards the right (-1), ie maximum
216
- const k = id === 'slider-min' ? 1 : -1;
217
- return svg `
218
- <svg
219
- id="${id}"
220
- @pointerdown="${this.drag}"
221
- >
222
- <path d="${sliderShape} z" fill="${sliderFill}" />
223
- <rect
224
- x="${sliderPositionX - this.sliderWidth * k + this.sliderWidth * 0.4 * k}"
225
- y="${this.height / 3}"
226
- width="1"
227
- height="${this.height / 3}"
228
- fill="white"
229
- />
230
- <rect
231
- x="${sliderPositionX - this.sliderWidth * k + this.sliderWidth * 0.6 * k}"
232
- y="${this.height / 3}"
233
- width="1"
234
- height="${this.height / 3}"
235
- fill="white"
236
- />
237
- </svg>
238
- `;
239
- }
240
- get selectedRangeTemplate() {
241
- return svg `
242
- <rect
243
- x="${this.minSliderX}"
244
- y="0"
245
- width="${this.maxSliderX - this.minSliderX}"
246
- height="${this.height}"
247
- fill="${selectedRangeFill}"
248
- />`;
249
- }
250
- get histogramTemplate() {
251
- const xScale = this._histWidth / this._numBins;
252
- const barWidth = xScale - 1;
253
- let x = this.sliderWidth; // start at the left edge of the histogram
254
- return this._histData.map(data => {
255
- const bar = svg `
256
- <rect
257
- class="bar"
258
- x="${x}"
259
- y="${this.height - data.height}"
260
- width="${barWidth}"
261
- height="${data.height}"
262
- @pointerenter="${this.showTooltip}"
263
- @pointerleave="${this.hideTooltip}"
264
- fill="${x >= this.minSliderX && x <= this.maxSliderX
265
- ? barIncludedFill
266
- : barExcludedFill}"
267
- data-num-items="${data.value}"
268
- data-bin-start="${data.binStart}"
269
- data-bin-end="${data.binEnd}"
270
- />`;
271
- x += xScale;
272
- return bar;
273
- });
274
- }
275
- get minInputTemplate() {
276
- return html `
277
- <input
278
- id="date-min"
279
- placeholder="${DATE_FORMAT}"
280
- type="text"
281
- @change="${this.handleMinDateInput}"
282
- .value="${this.minInputValue}"
283
- />
284
- `;
285
- }
286
- get maxInputTemplate() {
287
- return html `
288
- <input
289
- id="date-max"
290
- placeholder="${DATE_FORMAT}"
291
- type="text"
292
- @change="${this.handleMaxDateInput}"
293
- .value="${this.maxInputValue}"
294
- />
295
- `;
296
- }
297
- get tooltipTemplate() {
298
- return html `
299
- <style>
300
- #tooltip {
301
- width: ${this.tooltipWidth}px;
302
- height: ${this.tooltipHeight}px;
303
- top: ${-9 - this.tooltipHeight}px;
304
- left: ${this.tooltipOffset}px;
305
- display: ${this.tooltipDisplay};
306
- }
307
- #tooltip:after {
308
- left: ${this.tooltipWidth / 2}px;
309
- }
310
- </style>
311
- <div id="tooltip">${this.tooltipContent}</div>
312
- `;
313
- }
314
- render() {
315
- if (!this.data || !this._histData) {
316
- return html `no data`;
317
- }
318
- return html `
319
- <div id="container" class="noselect" style="width: ${this.width}px">
320
- ${this.tooltipTemplate}
321
- <svg
322
- width="${this.width}"
323
- height="${this.height}"
324
- @pointerleave="${this.drop}"
325
- >
326
- ${this.selectedRangeTemplate}
327
- <svg id="histogram">${this.histogramTemplate}</svg>
328
- ${this.minSliderTemplate} ${this.maxSliderTemplate}
329
- </svg>
330
- <div id="inputs">
331
- ${this.minInputTemplate}
332
- <div class="dash">-</div>
333
- ${this.maxInputTemplate}
334
- </div>
335
- </div>
336
- `;
337
- }
338
- }
339
- HistogramDateRange.styles = css `
340
- #container {
341
- margin: 0;
342
- touch-action: none;
343
- position: relative;
344
- }
345
- /* prevent selection from interfering with tooltip, especially on mobile */
346
- /* https://stackoverflow.com/a/4407335/1163042 */
347
- .noselect {
348
- -webkit-touch-callout: none; /* iOS Safari */
349
- -webkit-user-select: none; /* Safari */
350
- -moz-user-select: none; /* Old versions of Firefox */
351
- -ms-user-select: none; /* Internet Explorer/Edge */
352
- user-select: none; /* current Chrome, Edge, Opera and Firefox */
353
- }
354
- .bar:hover {
355
- fill-opacity: 0.7;
356
- }
357
- /****** histogram ********/
358
- #tooltip {
359
- position: absolute;
360
- background: ${tooltipBackgroundColor};
361
- color: ${tooltipTextColor};
362
- text-align: center;
363
- border-radius: 3px;
364
- padding: 2px;
365
- font-size: ${tooltipFontSize};
366
- font-family: sans-serif;
367
- touch-action: none;
368
- pointer-events: none;
369
- }
370
- #tooltip:after {
371
- content: '';
372
- position: absolute;
373
- margin-left: -5px;
374
- top: 100%;
375
- /* arrow */
376
- border: 5px solid ${tooltipTextColor};
377
- border-color: ${tooltipBackgroundColor} transparent transparent
378
- transparent;
379
- }
380
- /****** slider ********/
381
- .draggable:hover {
382
- cursor: grab;
383
- }
384
- .dragging {
385
- cursor: grabbing !important;
386
- }
387
- /****** inputs ********/
388
- #inputs {
389
- display: flex;
390
- justify-content: center;
391
- }
392
- #inputs .dash {
393
- position: relative;
394
- bottom: -1px;
395
- }
396
- input {
397
- width: ${inputWidth};
398
- margin: 0 3px;
399
- border: ${inputBorder};
400
- border-radius: 2px !important;
401
- text-align: center;
402
- font-size: ${inputFontSize};
403
- }
404
- `;
405
- __decorate([
406
- property({ type: Number })
407
- ], HistogramDateRange.prototype, "width", void 0);
408
- __decorate([
409
- property({ type: Number })
410
- ], HistogramDateRange.prototype, "height", void 0);
411
- __decorate([
412
- property({ type: Number })
413
- ], HistogramDateRange.prototype, "sliderWidth", void 0);
414
- __decorate([
415
- property({ type: Number })
416
- ], HistogramDateRange.prototype, "tooltipWidth", void 0);
417
- __decorate([
418
- property({ type: Number })
419
- ], HistogramDateRange.prototype, "tooltipHeight", void 0);
420
- __decorate([
421
- property({ type: String })
422
- ], HistogramDateRange.prototype, "dateFormat", void 0);
423
- __decorate([
424
- property({ type: Object })
425
- ], HistogramDateRange.prototype, "data", void 0);
426
- __decorate([
427
- internalProperty()
428
- ], HistogramDateRange.prototype, "minSliderX", void 0);
429
- __decorate([
430
- internalProperty()
431
- ], HistogramDateRange.prototype, "maxSliderX", void 0);
432
- __decorate([
433
- internalProperty()
434
- ], HistogramDateRange.prototype, "tooltipOffset", void 0);
435
- __decorate([
436
- internalProperty()
437
- ], HistogramDateRange.prototype, "tooltipContent", void 0);
438
- __decorate([
439
- internalProperty()
440
- ], HistogramDateRange.prototype, "tooltipDisplay", void 0);
441
- __decorate([
442
- query('#tooltip')
443
- ], HistogramDateRange.prototype, "tooltip", void 0);
444
- __decorate([
445
- query('#container')
446
- ], HistogramDateRange.prototype, "container", void 0);
447
- //# sourceMappingURL=HistogramDateRange.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"HistogramDateRange.js","sourceRoot":"","sources":["../../src/HistogramDateRange.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n html,\n svg,\n css,\n internalProperty,\n LitElement,\n TemplateResult,\n SVGTemplateResult,\n property,\n query,\n} from 'lit-element';\nimport dayjs from 'dayjs/esm/index.js';\n\n// these values can be overridden via the component's HTML (camelCased) attributes\nconst WIDTH = 180;\nconst HEIGHT = 40;\nconst SLIDER_WIDTH = 10;\nconst TOOLTIP_WIDTH = 125;\nconst TOOLTIP_HEIGHT = 30;\nconst DATE_FORMAT = 'M/D/YYYY';\n\n// this constant is not set up to be overridden\nconst SLIDER_CORNER_SIZE = 4;\n\n// these CSS custom props can be overridden from the HTML that is invoking this component\nconst sliderFill = 'var(--histogramDateRangeSliderFill, #4B65FE)';\nconst selectedRangeFill = 'var(--histogramDateRangeSelectedRangeFill, #DBE0FF)';\nconst barIncludedFill = 'var(--histogramDateRangeBarIncludedFill, #2C2C2C)';\nconst barExcludedFill = 'var(--histogramDateRangeBarExcludedFill, #CCCCCC)';\nconst inputBorder = css`var(--histogramDateRangeInputBorder, 0.5px solid #2C2C2C)`;\nconst inputWidth = css`var(--histogramDateRangeInputWidth, 70px)`;\nconst inputFontSize = css`var(--histogramDateRangeInputFontSize, 1.2rem)`;\nconst tooltipBackgroundColor = css`var(--histogramDateRangeTooltipBackgroundColor, #2C2C2C)`;\nconst tooltipTextColor = css`var(--histogramDateRangeTooltipTextColor, #FFFFFF)`;\nconst tooltipFontSize = css`var(--histogramDateRangeTooltipFontSize, 1.1rem)`;\n\ntype SliderIds = 'slider-min' | 'slider-max';\n\ninterface HistogramInputData {\n minDate: string;\n maxDate: string;\n bins: number[];\n}\n\ninterface HistogramItem {\n value: number;\n height: number;\n binStart: string;\n binEnd: string;\n}\n\nexport class HistogramDateRange extends LitElement {\n /* eslint-disable lines-between-class-members */\n\n // these properties are intended to be passed in as attributes\n @property({ type: Number }) width = WIDTH;\n @property({ type: Number }) height = HEIGHT;\n @property({ type: Number }) sliderWidth = SLIDER_WIDTH;\n @property({ type: Number }) tooltipWidth = TOOLTIP_WIDTH;\n @property({ type: Number }) tooltipHeight = TOOLTIP_HEIGHT;\n @property({ type: String }) dateFormat = DATE_FORMAT;\n @property({ type: Object }) data?: HistogramInputData;\n\n @internalProperty() minSliderX: number = 0;\n @internalProperty() maxSliderX: number = 0;\n @internalProperty() tooltipOffset = 0;\n @internalProperty() tooltipContent: TemplateResult | '' = '';\n @internalProperty() tooltipDisplay: 'block' | 'none' = 'none';\n\n @query('#tooltip') tooltip!: HTMLDivElement;\n @query('#container') container!: HTMLDivElement;\n\n // these properties don't need to be tracked for changes\n private _minDate: number = 0;\n private _maxDate: number = 0;\n private _dragOffset: number = 0;\n private _histWidth: number = 0;\n private _numBins: number = 0;\n private _binWidth: number = 0;\n private _currentSlider?: SVGRectElement;\n private _histData: HistogramItem[] = [];\n\n /* eslint-enable lines-between-class-members */\n\n firstUpdated(): void {\n this.minSliderX = this.sliderWidth;\n this.maxSliderX = this.width - this.sliderWidth;\n this._minDate = dayjs(this.data?.minDate).valueOf();\n this._maxDate = dayjs(this.data?.maxDate).valueOf();\n this._histWidth = this.width - this.sliderWidth * 2;\n this._numBins = this.data?.bins?.length ?? 1;\n this._binWidth = this._histWidth / this._numBins;\n this._histData = this.generateHistData();\n }\n\n private generateHistData(): HistogramItem[] {\n if (!this.data) {\n return [];\n }\n const minValue = Math.min(...this.data.bins);\n const maxValue = Math.max(...this.data.bins);\n const valueScale = this.height / Math.log1p(maxValue - minValue);\n const dateScale = this.dateRange / this._numBins;\n return this.data.bins.map((v: number, i: number) => {\n return {\n value: v,\n height: Math.floor(Math.log1p(v) * valueScale),\n binStart: `${dayjs(i * dateScale + this._minDate).format(\n this.dateFormat\n )}`,\n binEnd: `${dayjs((i + 1) * dateScale + this._minDate).format(\n this.dateFormat\n )}`,\n };\n });\n }\n\n private get dateRange(): number {\n return this._maxDate - this._minDate;\n }\n\n private showTooltip(e: PointerEvent): void {\n if (Array.from(this.container.classList).includes('dragging')) {\n return;\n }\n const target = e.currentTarget as SVGRectElement;\n const x = target.x.baseVal.value + this.sliderWidth / 2;\n const data = target.dataset;\n const itemsText = `item${data.numItems !== '1' ? 's' : ''}`;\n\n this.tooltipOffset =\n x + (this._binWidth - this.sliderWidth - this.tooltipWidth) / 2;\n\n this.tooltipContent = html`\n ${data.numItems} ${itemsText}<br />\n ${data.binStart} - ${data.binEnd}\n `;\n this.tooltipDisplay = 'block';\n }\n\n private hideTooltip(): void {\n this.tooltipContent = '';\n this.tooltipDisplay = 'none';\n }\n\n // use arrow functions (rather than standard JS class instance methods) so\n // that `this` is bound to the histogramDateRange object and not the event\n // target. for more info see\n // https://lit-element.polymer-project.org/guide/events#using-this-in-event-listeners\n private drag = (e: PointerEvent): void => {\n // prevent selecting text or other ranges while dragging, especially in Safari\n e.preventDefault();\n\n this.setDragOffset(e);\n this.container.classList.add('dragging');\n\n window.addEventListener('pointermove', this.move);\n window.addEventListener('pointerup', this.drop);\n window.addEventListener('pointercancel', this.drop);\n };\n\n private drop = (): void => {\n this.container.classList.remove('dragging');\n\n window.removeEventListener('pointermove', this.move);\n window.removeEventListener('pointerup', this.drop);\n window.removeEventListener('pointercancel', this.drop);\n };\n\n private move = (e: PointerEvent): void => {\n const newX = e.offsetX - this._dragOffset;\n const slider = this._currentSlider as SVGRectElement;\n return (slider.id as SliderIds) === 'slider-min'\n ? this.setMinSlider(newX)\n : this.setMaxSlider(newX);\n };\n\n // find position of pointer in relation to the current slider\n private setDragOffset(e: PointerEvent): void {\n this._currentSlider = e.currentTarget as SVGRectElement;\n const sliderX =\n (this._currentSlider.id as SliderIds) === 'slider-min'\n ? this.minSliderX\n : this.maxSliderX;\n this._dragOffset = e.offsetX - sliderX;\n // work around Firefox issue where e.offsetX seems to be not based on current\n // element but on background element\n if (\n this._dragOffset > this.sliderWidth ||\n this._dragOffset < -this.sliderWidth\n ) {\n this._dragOffset = 0;\n }\n }\n\n private setMinSlider(newX: number): void {\n const toSet = Math.max(newX, this.sliderWidth);\n this.minSliderX = Math.min(toSet, this.maxSliderX);\n }\n\n private setMaxSlider(newX: number): void {\n const toSet = Math.max(newX, this.minSliderX);\n this.maxSliderX = Math.min(toSet, this.width - this.sliderWidth);\n }\n\n private translatePositionToDate(x: number): string {\n const milliseconds =\n ((x - this.sliderWidth) * this.dateRange) / this._histWidth;\n const date = dayjs(this._minDate + milliseconds);\n return date.format(this.dateFormat);\n }\n\n private translateDateToPosition(date: string): number | null {\n const milliseconds: number | undefined = dayjs(date).valueOf();\n if (!milliseconds) {\n return null;\n }\n // translate where we are within the date range into what the new x-position\n // of the slider should be\n return (\n this.sliderWidth +\n ((milliseconds - this._minDate) * this._histWidth) / this.dateRange\n );\n }\n\n private handleMinDateInput(e: InputEvent): void {\n const target = e.currentTarget as HTMLInputElement;\n const newX = this.translateDateToPosition(target.value);\n if (newX) {\n this.setMinSlider(newX);\n }\n target.value = this.minInputValue;\n }\n\n private handleMaxDateInput(e: InputEvent): void {\n const target = e.currentTarget as HTMLInputElement;\n const newX = this.translateDateToPosition(target.value);\n if (newX) {\n this.setMaxSlider(newX);\n }\n target.value = this.maxInputValue;\n }\n\n private get minInputValue() {\n return this.translatePositionToDate(this.minSliderX);\n }\n\n private get maxInputValue() {\n return this.translatePositionToDate(this.maxSliderX);\n }\n\n private get minSliderTemplate(): SVGTemplateResult {\n // width/height in pixels of curved part of the sliders (like\n // border-radius); used as part of a SVG quadratic curve. see\n // https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths#curve_commands\n const c = SLIDER_CORNER_SIZE;\n\n const sliderShape = `\n M${this.minSliderX},0\n h-${this.sliderWidth - c}\n q-${c},0 -${c},${c}\n v${this.height - c * 2}\n q0,${c} ${c},${c}\n h${this.sliderWidth - c}\n `;\n return this.generateSliderSVG(this.minSliderX, 'slider-min', sliderShape);\n }\n\n private get maxSliderTemplate(): SVGTemplateResult {\n const c = SLIDER_CORNER_SIZE;\n const sliderShape = `\n M${this.maxSliderX},0\n h${this.sliderWidth - c}\n q${c},0 ${c},${c}\n v${this.height - c * 2}\n q0,${c} -${c},${c}\n h-${this.sliderWidth - c}\n `;\n return this.generateSliderSVG(this.maxSliderX, 'slider-max', sliderShape);\n }\n\n private generateSliderSVG(\n sliderPositionX: number,\n id: SliderIds,\n sliderShape: string\n ): SVGTemplateResult {\n // whether the curved part of the slider is facing towards the left (1), ie\n // minimum, or facing towards the right (-1), ie maximum\n const k = id === 'slider-min' ? 1 : -1;\n\n return svg`\n <svg\n id=\"${id}\"\n @pointerdown=\"${this.drag}\"\n >\n <path d=\"${sliderShape} z\" fill=\"${sliderFill}\" />\n <rect\n x=\"${\n sliderPositionX - this.sliderWidth * k + this.sliderWidth * 0.4 * k\n }\"\n y=\"${this.height / 3}\"\n width=\"1\"\n height=\"${this.height / 3}\"\n fill=\"white\"\n />\n <rect\n x=\"${\n sliderPositionX - this.sliderWidth * k + this.sliderWidth * 0.6 * k\n }\"\n y=\"${this.height / 3}\"\n width=\"1\"\n height=\"${this.height / 3}\"\n fill=\"white\"\n />\n </svg>\n `;\n }\n\n get selectedRangeTemplate(): SVGTemplateResult {\n return svg`\n <rect\n x=\"${this.minSliderX}\"\n y=\"0\"\n width=\"${this.maxSliderX - this.minSliderX}\"\n height=\"${this.height}\"\n fill=\"${selectedRangeFill}\"\n />`;\n }\n\n get histogramTemplate(): SVGTemplateResult[] {\n const xScale = this._histWidth / this._numBins;\n const barWidth = xScale - 1;\n let x = this.sliderWidth; // start at the left edge of the histogram\n return this._histData.map(data => {\n const bar = svg`\n <rect\n class=\"bar\"\n x=\"${x}\"\n y=\"${this.height - data.height}\"\n width=\"${barWidth}\"\n height=\"${data.height}\"\n @pointerenter=\"${this.showTooltip}\"\n @pointerleave=\"${this.hideTooltip}\"\n fill=\"${\n x >= this.minSliderX && x <= this.maxSliderX\n ? barIncludedFill\n : barExcludedFill\n }\"\n data-num-items=\"${data.value}\"\n data-bin-start=\"${data.binStart}\"\n data-bin-end=\"${data.binEnd}\"\n />`;\n x += xScale;\n return bar;\n });\n }\n\n get minInputTemplate(): TemplateResult {\n return html`\n <input\n id=\"date-min\"\n placeholder=\"${DATE_FORMAT}\"\n type=\"text\"\n @change=\"${this.handleMinDateInput}\"\n .value=\"${this.minInputValue}\"\n />\n `;\n }\n\n get maxInputTemplate(): TemplateResult {\n return html`\n <input\n id=\"date-max\"\n placeholder=\"${DATE_FORMAT}\"\n type=\"text\"\n @change=\"${this.handleMaxDateInput}\"\n .value=\"${this.maxInputValue}\"\n />\n `;\n }\n\n get tooltipTemplate(): TemplateResult {\n return html`\n <style>\n #tooltip {\n width: ${this.tooltipWidth}px;\n height: ${this.tooltipHeight}px;\n top: ${-9 - this.tooltipHeight}px;\n left: ${this.tooltipOffset}px;\n display: ${this.tooltipDisplay};\n }\n #tooltip:after {\n left: ${this.tooltipWidth / 2}px;\n }\n </style>\n <div id=\"tooltip\">${this.tooltipContent}</div>\n `;\n }\n\n static styles = css`\n #container {\n margin: 0;\n touch-action: none;\n position: relative;\n }\n /* prevent selection from interfering with tooltip, especially on mobile */\n /* https://stackoverflow.com/a/4407335/1163042 */\n .noselect {\n -webkit-touch-callout: none; /* iOS Safari */\n -webkit-user-select: none; /* Safari */\n -moz-user-select: none; /* Old versions of Firefox */\n -ms-user-select: none; /* Internet Explorer/Edge */\n user-select: none; /* current Chrome, Edge, Opera and Firefox */\n }\n .bar:hover {\n fill-opacity: 0.7;\n }\n /****** histogram ********/\n #tooltip {\n position: absolute;\n background: ${tooltipBackgroundColor};\n color: ${tooltipTextColor};\n text-align: center;\n border-radius: 3px;\n padding: 2px;\n font-size: ${tooltipFontSize};\n font-family: sans-serif;\n touch-action: none;\n pointer-events: none;\n }\n #tooltip:after {\n content: '';\n position: absolute;\n margin-left: -5px;\n top: 100%;\n /* arrow */\n border: 5px solid ${tooltipTextColor};\n border-color: ${tooltipBackgroundColor} transparent transparent\n transparent;\n }\n /****** slider ********/\n .draggable:hover {\n cursor: grab;\n }\n .dragging {\n cursor: grabbing !important;\n }\n /****** inputs ********/\n #inputs {\n display: flex;\n justify-content: center;\n }\n #inputs .dash {\n position: relative;\n bottom: -1px;\n }\n input {\n width: ${inputWidth};\n margin: 0 3px;\n border: ${inputBorder};\n border-radius: 2px !important;\n text-align: center;\n font-size: ${inputFontSize};\n }\n `;\n\n render(): TemplateResult {\n if (!this.data || !this._histData) {\n return html`no data`;\n }\n return html`\n <div id=\"container\" class=\"noselect\" style=\"width: ${this.width}px\">\n ${this.tooltipTemplate}\n <svg\n width=\"${this.width}\"\n height=\"${this.height}\"\n @pointerleave=\"${this.drop}\"\n >\n ${this.selectedRangeTemplate}\n <svg id=\"histogram\">${this.histogramTemplate}</svg>\n ${this.minSliderTemplate} ${this.maxSliderTemplate}\n </svg>\n <div id=\"inputs\">\n ${this.minInputTemplate}\n <div class=\"dash\">-</div>\n ${this.maxInputTemplate}\n </div>\n </div>\n `;\n }\n}\n"]}