@internetarchive/histogram-date-range 0.1.3-alpha → 0.1.6
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.
- package/demo/app-root.ts +21 -0
- package/demo/index.html +27 -5
- package/dist/demo/app-root.d.ts +9 -0
- package/dist/demo/app-root.js +25 -0
- package/dist/demo/app-root.js.map +1 -0
- package/dist/src/histogram-date-range.js +15 -10
- package/dist/src/histogram-date-range.js.map +1 -1
- package/dist/test/histogram-date-range.test.js +27 -0
- package/dist/test/histogram-date-range.test.js.map +1 -1
- package/docs/demo/app-root.js +29 -0
- package/docs/demo/index.html +27 -5
- package/docs/dist/src/histogram-date-range.js +11 -10
- package/package.json +2 -2
- package/src/histogram-date-range.ts +16 -12
- package/test/histogram-date-range.test.ts +46 -8
- package/dist/src/HistogramDateRange.d.ts +0 -58
- package/dist/src/HistogramDateRange.js +0 -447
- package/dist/src/HistogramDateRange.js.map +0 -1
|
@@ -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"]}
|