@teipublisher/pb-components 2.26.1-next.2 → 3.0.0-next-4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/docker-cypress.yml +54 -0
- package/.github/workflows/main.yml +6 -4
- package/.github/workflows/node.js.yml +56 -21
- package/.github/workflows/release.js.yml +19 -17
- package/.releaserc.json +1 -1
- package/CHANGELOG.md +351 -9
- package/Dockerfile +78 -70
- package/README.md +112 -4
- package/css/components.css +5 -5
- package/css/gridjs/mermaid.min.css +1 -1
- package/css/leaflet/Control.Geocoder.css +1 -126
- package/css/leaflet/images/layers.png +0 -0
- package/css/tify/tify.css +6 -5
- package/css/tom-select/tom-select.bootstrap4.min.css +1 -1
- package/css/tom-select/tom-select.bootstrap5.min.css +1 -1
- package/css/tom-select/tom-select.default.min.css +1 -1
- package/css/tom-select/tom-select.default.min.css.map +1 -0
- package/css/tom-select/tom-select.min.css +1 -1
- package/cypress.config.js +84 -0
- package/dist/api.html +1 -1
- package/dist/css/design-system.css +607 -0
- package/dist/demo/bundle-test.html +4 -3
- package/dist/demo/components.css +46 -1
- package/dist/demo/design-system.html +710 -0
- package/dist/demo/dts-client.html +2 -2
- package/dist/demo/pb-autocomplete.html +23 -11
- package/dist/demo/pb-autocomplete2.html +66 -55
- package/dist/demo/pb-autocomplete3.html +17 -8
- package/dist/demo/pb-blacklab-highlight.html +28 -11
- package/dist/demo/pb-blacklab-results.html +3 -2
- package/dist/demo/pb-browse-docs.html +24 -24
- package/dist/demo/pb-browse-docs2.html +3 -3
- package/dist/demo/pb-clipboard.html +32 -28
- package/dist/demo/pb-code-editor.html +6 -6
- package/dist/demo/pb-code-highlight.html +63 -63
- package/dist/demo/pb-codepen.html +1 -1
- package/dist/demo/pb-collapse.html +1 -1
- package/dist/demo/pb-collapse2.html +2 -2
- package/dist/demo/pb-combo-box.html +135 -130
- package/dist/demo/pb-custom-form.html +64 -55
- package/dist/demo/pb-dialog.html +12 -6
- package/dist/demo/pb-document.html +1 -1
- package/dist/demo/pb-download.html +68 -59
- package/dist/demo/pb-drawer.html +67 -46
- package/dist/demo/pb-drawer2.html +65 -58
- package/dist/demo/pb-edit-app.html +2 -2
- package/dist/demo/pb-edit-xml.html +1 -1
- package/dist/demo/pb-facsimile-2.html +26 -11
- package/dist/demo/pb-facsimile-3.html +25 -10
- package/dist/demo/pb-facsimile-dedup-test-2.html +48 -0
- package/dist/demo/pb-facsimile-dedup-test.html +48 -0
- package/dist/demo/pb-facsimile.html +4 -4
- package/dist/demo/pb-formula.html +1 -1
- package/dist/demo/pb-grid.html +22 -8
- package/dist/demo/pb-highlight.html +2 -2
- package/dist/demo/pb-i18n-simple.html +1 -0
- package/dist/demo/pb-i18n.html +15 -5
- package/dist/demo/pb-image-strip-standalone.html +2 -2
- package/dist/demo/pb-image-strip-view.html +2 -2
- package/dist/demo/pb-leaflet-map.html +3 -3
- package/dist/demo/pb-leaflet-map2.html +2 -2
- package/dist/demo/pb-leaflet-map3.html +3 -3
- package/dist/demo/pb-link.html +1 -1
- package/dist/demo/pb-load.html +2 -6
- package/dist/demo/pb-login.html +1 -3
- package/dist/demo/pb-manage-odds.html +9 -4
- package/dist/demo/pb-markdown.html +1 -1
- package/dist/demo/pb-media-query.html +2 -2
- package/dist/demo/pb-mei.html +2 -2
- package/dist/demo/pb-mei2.html +2 -2
- package/dist/demo/pb-message.html +2 -3
- package/dist/demo/pb-odd-editor.html +54 -52
- package/dist/demo/pb-page-header.html +27 -0
- package/dist/demo/pb-popover.html +1 -1
- package/dist/demo/pb-print-preview.html +2 -2
- package/dist/demo/pb-progress.html +4 -4
- package/dist/demo/pb-repeat.html +32 -36
- package/dist/demo/pb-search.html +16 -5
- package/dist/demo/pb-search2.html +4 -4
- package/dist/demo/pb-search3.html +3 -3
- package/dist/demo/pb-search4.html +3 -3
- package/dist/demo/pb-select-feature.html +4 -4
- package/dist/demo/pb-select-feature2.html +4 -4
- package/dist/demo/pb-select-feature3.html +2 -2
- package/dist/demo/pb-select-i18n.html +58 -53
- package/dist/demo/pb-select-odd.html +1 -1
- package/dist/demo/pb-select.html +190 -75
- package/dist/demo/pb-select2.html +91 -37
- package/dist/demo/pb-select3.html +109 -41
- package/dist/demo/pb-svg.html +1 -1
- package/dist/demo/pb-table-grid.html +26 -15
- package/dist/demo/pb-tabs.html +15 -7
- package/dist/demo/pb-tify.html +7 -7
- package/dist/demo/pb-timeline.html +1 -1
- package/dist/demo/pb-timeline2.html +1 -1
- package/dist/demo/pb-toggle-feature.html +26 -23
- package/dist/demo/pb-toggle-feature2.html +4 -4
- package/dist/demo/pb-toggle-feature3.html +2 -2
- package/dist/demo/pb-toggle-feature4.html +56 -54
- package/dist/demo/pb-version.html +2 -2
- package/dist/demo/pb-view.html +78 -40
- package/dist/demo/pb-view2.html +69 -46
- package/dist/demo/pb-view3.html +53 -48
- package/dist/demo/pb-view4.html +70 -49
- package/dist/demo/pb-zoom.html +2 -2
- package/dist/{es-global-bridge-d8ce175d.js → es-global-bridge-D8ZcUcx_.js} +0 -4
- package/dist/focus-mixin-VCsFap6b.js +768 -0
- package/dist/images/icons.svg +217 -0
- package/dist/jinn-codemirror-DETLdm08.js +1 -0
- package/dist/lib/openseadragon.min.js +80 -0
- package/dist/lib/openseadragon.min.js.map +1 -0
- package/dist/pb-code-editor.js +25 -20
- package/dist/pb-component-docs.js +414 -3225
- package/dist/pb-components-bundle.js +3046 -4402
- package/dist/pb-dialog-tklYGWfc.js +121 -0
- package/dist/pb-edit-app.js +208 -107
- package/dist/pb-elements.json +716 -249
- package/dist/pb-facsimile.js +46 -0
- package/dist/pb-i18n-C0NDma4h.js +1 -0
- package/dist/pb-leaflet-map.js +23 -23
- package/dist/pb-mei.js +152 -134
- package/dist/pb-mixin-DHoWQheB.js +1 -0
- package/dist/pb-odd-editor.js +1671 -1231
- package/dist/pb-tify.js +1 -27
- package/dist/unsafe-html-D5VGo9Oq.js +1 -0
- package/dist/urls-BEONu_g4.js +1 -0
- package/eslint.config.mjs +92 -0
- package/gh-pages.js +5 -3
- package/i18n/common/en.json +6 -0
- package/i18n/common/pl.json +2 -2
- package/images/icons.svg +217 -0
- package/index.html +0 -5
- package/lib/leaflet-src.js.map +1 -0
- package/lib/leaflet.markercluster-src.js.map +1 -0
- package/lib/openseadragon.min.js +6 -6
- package/package.json +56 -81
- package/pb-elements.json +716 -249
- package/rollup.config.mjs +312 -0
- package/src/assets/components.css +5 -5
- package/src/assets/design-system.css +607 -0
- package/src/authority/airtable.js +20 -21
- package/src/authority/anton.js +129 -129
- package/src/authority/custom.js +70 -27
- package/src/authority/geonames.js +38 -32
- package/src/authority/gnd.js +50 -42
- package/src/authority/kbga.js +136 -134
- package/src/authority/metagrid.js +44 -46
- package/src/authority/reconciliation.js +66 -68
- package/src/authority/registry.js +4 -4
- package/src/docs/demo-utils.js +91 -0
- package/src/docs/pb-component-docs.js +287 -147
- package/src/docs/pb-component-view.js +380 -273
- package/src/docs/pb-components-list.js +115 -51
- package/src/docs/pb-demo-snippet.js +199 -174
- package/src/dts-client.js +306 -303
- package/src/dts-select-endpoint.js +125 -85
- package/src/parse-date-service.js +184 -135
- package/src/pb-ajax.js +175 -173
- package/src/pb-authority-lookup.js +198 -158
- package/src/pb-autocomplete.js +731 -313
- package/src/pb-blacklab-highlight.js +266 -260
- package/src/pb-blacklab-results.js +230 -225
- package/src/pb-browse-docs.js +601 -484
- package/src/pb-browse.js +68 -65
- package/src/pb-clipboard.js +97 -76
- package/src/pb-code-editor.js +111 -103
- package/src/pb-code-highlight.js +234 -204
- package/src/pb-codepen.js +81 -73
- package/src/pb-collapse.js +265 -152
- package/src/pb-combo-box.js +191 -191
- package/src/pb-components-bundle.js +1 -7
- package/src/pb-components.js +2 -6
- package/src/pb-custom-form.js +230 -141
- package/src/pb-dialog.js +99 -63
- package/src/pb-document.js +118 -91
- package/src/pb-download.js +214 -198
- package/src/pb-drawer.js +146 -149
- package/src/pb-edit-app.js +471 -240
- package/src/pb-edit-xml.js +101 -98
- package/src/pb-events.js +126 -107
- package/src/pb-facs-link.js +130 -101
- package/src/pb-facsimile.js +494 -410
- package/src/pb-fetch.js +389 -0
- package/src/pb-formula.js +152 -154
- package/src/pb-geolocation.js +130 -132
- package/src/pb-grid-action.js +59 -56
- package/src/pb-grid.js +388 -228
- package/src/pb-highlight.js +142 -142
- package/src/pb-hotkeys.js +40 -42
- package/src/pb-i18n.js +115 -127
- package/src/pb-icon-button.js +108 -0
- package/src/pb-icon.js +283 -0
- package/src/pb-image-strip.js +85 -79
- package/src/pb-lang.js +142 -57
- package/src/pb-leaflet-map.js +551 -483
- package/src/pb-link.js +132 -126
- package/src/pb-load.js +495 -428
- package/src/pb-login.js +303 -248
- package/src/pb-manage-odds.js +384 -338
- package/src/pb-map-icon.js +90 -90
- package/src/pb-map-layer.js +86 -86
- package/src/pb-markdown.js +107 -110
- package/src/pb-media-query.js +75 -73
- package/src/pb-mei.js +523 -303
- package/src/pb-message.js +144 -98
- package/src/pb-mixin.js +268 -265
- package/src/pb-navigation.js +83 -96
- package/src/pb-observable.js +39 -39
- package/src/pb-odd-editor.js +1209 -948
- package/src/pb-odd-elementspec-editor.js +375 -310
- package/src/pb-odd-model-editor.js +1189 -941
- package/src/pb-odd-parameter-editor.js +269 -170
- package/src/pb-odd-rendition-editor.js +184 -131
- package/src/pb-page.js +451 -422
- package/src/pb-paginate.js +260 -178
- package/src/pb-panel.js +217 -183
- package/src/pb-popover-themes.js +16 -9
- package/src/pb-popover.js +297 -288
- package/src/pb-print-preview.js +128 -128
- package/src/pb-progress.js +52 -52
- package/src/pb-repeat.js +141 -108
- package/src/pb-restricted.js +85 -78
- package/src/pb-search.js +258 -230
- package/src/pb-select-feature.js +210 -126
- package/src/pb-select-odd.js +184 -118
- package/src/pb-select-template.js +113 -78
- package/src/pb-select.js +330 -229
- package/src/pb-split-list.js +181 -176
- package/src/pb-svg.js +81 -80
- package/src/pb-table-column.js +55 -55
- package/src/pb-table-grid.js +334 -205
- package/src/pb-tabs.js +238 -61
- package/src/pb-tify.js +3331 -126
- package/src/pb-timeline.js +394 -255
- package/src/pb-toggle-feature.js +196 -188
- package/src/pb-upload.js +201 -176
- package/src/pb-version.js +22 -34
- package/src/pb-view-annotate.js +138 -102
- package/src/pb-view.js +1722 -1272
- package/src/pb-zoom.js +144 -46
- package/src/search-result-service.js +256 -223
- package/src/seed-element.js +14 -22
- package/src/settings.js +4 -4
- package/src/theming.js +98 -91
- package/src/urls.js +403 -289
- package/src/utils.js +53 -51
- package/vite.config.js +86 -0
- package/css/pb-styles.css +0 -51
- package/dist/iron-form-3b8dcaa7.js +0 -210
- package/dist/jinn-codemirror-da0e2d1f.js +0 -1
- package/dist/paper-checkbox-515a5284.js +0 -1597
- package/dist/paper-icon-button-b1d31571.js +0 -398
- package/dist/paper-listbox-a3b7175c.js +0 -1265
- package/dist/pb-i18n-0611135a.js +0 -1
- package/dist/pb-mixin-b1caa22e.js +0 -158
- package/dist/polymer-hack.js +0 -1
- package/dist/vaadin-element-mixin-6e4cee3a.js +0 -527
- package/lib/Control.Geocoder.min.js +0 -2
- package/lib/Control.Geocoder.min.js.map +0 -1
- package/src/assets/pb-styles.css +0 -51
- package/src/pb-light-dom.js +0 -40
- package/src/polymer-hack.js +0 -6
package/src/pb-timeline.js
CHANGED
|
@@ -1,31 +1,30 @@
|
|
|
1
|
-
import { LitElement, html, css } from 'lit
|
|
2
|
-
import { unsafeHTML } from 'lit
|
|
3
|
-
import { SearchResultService } from
|
|
4
|
-
import { ParseDateService } from
|
|
5
|
-
import { pbMixin } from
|
|
6
|
-
import '
|
|
7
|
-
import '
|
|
8
|
-
import '
|
|
9
|
-
import { translate } from "./pb-i18n.js";
|
|
1
|
+
import { LitElement, html, css } from 'lit';
|
|
2
|
+
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
|
|
3
|
+
import { SearchResultService } from './search-result-service.js';
|
|
4
|
+
import { ParseDateService } from './parse-date-service.js';
|
|
5
|
+
import { pbMixin } from './pb-mixin.js';
|
|
6
|
+
import './pb-fetch.js';
|
|
7
|
+
import { translate } from './pb-i18n.js';
|
|
8
|
+
import { themableMixin } from './theming.js';
|
|
10
9
|
|
|
11
10
|
/**
|
|
12
11
|
* A timeline component to display time series data in a bar chart like view.
|
|
13
12
|
*
|
|
14
13
|
* Time series data can be displayed in one of 6 different scales:
|
|
15
|
-
*
|
|
14
|
+
*
|
|
16
15
|
* - by decade (10Y)
|
|
17
16
|
* - by 5 years (5Y)
|
|
18
17
|
* - by years (Y)
|
|
19
18
|
* - by month (M)
|
|
20
19
|
* - by week (W)
|
|
21
20
|
* - by day (D)
|
|
22
|
-
*
|
|
21
|
+
*
|
|
23
22
|
* The endpoint is expected to return a JSON object. Each property should either be a date or the special
|
|
24
23
|
* marker `?`, which indicates undated resources.
|
|
25
24
|
* The value associated with each entry
|
|
26
|
-
* should either correspond to a count of resources or an object with properties `count` and `info`.
|
|
25
|
+
* should either correspond to a count of resources or an object with properties `count` and `info`.
|
|
27
26
|
* `info` should be an array, containing HTML to be shown in a list within the tooltips.
|
|
28
|
-
* Expected JSON:
|
|
27
|
+
* Expected JSON:
|
|
29
28
|
* ```javascript
|
|
30
29
|
* {
|
|
31
30
|
* "1852-01-14": {
|
|
@@ -52,17 +51,17 @@ import { translate } from "./pb-i18n.js";
|
|
|
52
51
|
* <span slot="label">Angezeigter Zeitraum: </span>
|
|
53
52
|
* </pb-timeline>
|
|
54
53
|
* ```
|
|
55
|
-
* See https://www.briefedition.alfred-escher.ch/briefe/ for a running sample. The source code of the webpage is here: https://github.com/stazh/briefedition-escher. Relevant files are:
|
|
54
|
+
* See https://www.briefedition.alfred-escher.ch/briefe/ for a running sample. The source code of the webpage is here: https://github.com/stazh/briefedition-escher. Relevant files are:
|
|
56
55
|
* - [templates/people.html](https://github.com/stazh/briefedition-escher/blob/master/templates/people.html#L91) - usage of pb-timeline
|
|
57
56
|
* - [modules/custom-api.json](https://github.com/stazh/briefedition-escher/blob/master/modules/custom-api.json#L1080) - `/api/timeline` endpoint delivering required JSON object
|
|
58
|
-
*
|
|
57
|
+
*
|
|
59
58
|
* @slot label - Inserted before the label showing the currently displayed time range
|
|
60
|
-
*
|
|
59
|
+
*
|
|
61
60
|
* @fires pb-timeline-date-changed - Triggered when user clicks on a single entry
|
|
62
61
|
* @fires pb-timeline-daterange-changed - Triggered when user selects a range of entries
|
|
63
62
|
* @fires pb-timeline-reset-selection - Requests that the timeline is reset to initial state
|
|
64
63
|
* @fires pb-timeline-loaded - Timeline was loaded
|
|
65
|
-
*
|
|
64
|
+
*
|
|
66
65
|
* @cssprop --pb-timeline-height
|
|
67
66
|
* @cssprop --pb-timeline-padding
|
|
68
67
|
* @cssprop --pb-timeline-color-highlight
|
|
@@ -72,17 +71,17 @@ import { translate } from "./pb-i18n.js";
|
|
|
72
71
|
* @cssprop --pb-timeline-color-bin
|
|
73
72
|
* @cssprop --pb-timeline-title-font-size
|
|
74
73
|
* @cssprop --pb-timeline-tooltip-font-size
|
|
75
|
-
*
|
|
74
|
+
* @cssprop --pb-timeline-tooltip-min-width
|
|
75
|
+
* @cssprop --pb-timeline-tooltip-max-width
|
|
76
|
+
*
|
|
76
77
|
* @csspart label
|
|
77
78
|
* @csspart tooltip
|
|
78
79
|
* @csspart title
|
|
79
80
|
*/
|
|
80
|
-
export class PbTimeline extends pbMixin(LitElement) {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
static get styles() {
|
|
81
|
+
export class PbTimeline extends themableMixin(pbMixin(LitElement)) {
|
|
82
|
+
static get styles() {
|
|
84
83
|
return css`
|
|
85
|
-
:host{
|
|
84
|
+
:host {
|
|
86
85
|
display: block;
|
|
87
86
|
}
|
|
88
87
|
.hidden {
|
|
@@ -121,8 +120,9 @@ export class PbTimeline extends pbMixin(LitElement) {
|
|
|
121
120
|
// justify-content: center;
|
|
122
121
|
position: relative;
|
|
123
122
|
}
|
|
124
|
-
.bin-container.border-left,
|
|
125
|
-
|
|
123
|
+
.bin-container.border-left,
|
|
124
|
+
.bin-container.unknown {
|
|
125
|
+
border-left: 1px solid rgba(0, 0, 0, 0.4);
|
|
126
126
|
}
|
|
127
127
|
.bin-container.unknown {
|
|
128
128
|
margin-left: 40px;
|
|
@@ -196,10 +196,11 @@ export class PbTimeline extends pbMixin(LitElement) {
|
|
|
196
196
|
}
|
|
197
197
|
|
|
198
198
|
/* TOOLTIP */
|
|
199
|
-
|
|
199
|
+
.tooltip {
|
|
200
200
|
display: inline-block;
|
|
201
201
|
position: absolute;
|
|
202
202
|
min-width: var(--pb-timeline-tooltip-min-width, 200px);
|
|
203
|
+
max-width: var(--pb-timeline-tooltip-max-width, calc(100vw - 40px));
|
|
203
204
|
font-size: var(--pb-timeline-tooltip-font-size, 11px);
|
|
204
205
|
line-height: 1.25;
|
|
205
206
|
background: var(--pb-timeline-background-color-title, #535353);
|
|
@@ -207,36 +208,46 @@ export class PbTimeline extends pbMixin(LitElement) {
|
|
|
207
208
|
text-align: left;
|
|
208
209
|
border-radius: 6px;
|
|
209
210
|
padding: 5px 10px;
|
|
210
|
-
top: var(--pb-timeline-height, 80px);
|
|
211
|
+
top: calc(var(--pb-timeline-height, 80px) + 10px);
|
|
211
212
|
left: 0;
|
|
212
213
|
z-index: 1000;
|
|
214
|
+
word-wrap: break-word;
|
|
215
|
+
overflow-wrap: break-word;
|
|
213
216
|
}
|
|
214
|
-
|
|
217
|
+
.tooltip a:link,
|
|
218
|
+
.tooltip a:visited {
|
|
219
|
+
color: var(--pb-timeline-color-title, #ffffff);
|
|
220
|
+
}
|
|
221
|
+
.tooltip ul {
|
|
215
222
|
list-style: none;
|
|
216
223
|
margin: 0;
|
|
217
224
|
padding: 0;
|
|
218
225
|
}
|
|
219
|
-
|
|
226
|
+
.tooltip-close {
|
|
220
227
|
position: absolute;
|
|
221
228
|
top: -13px;
|
|
222
229
|
right: -10px;
|
|
223
230
|
}
|
|
224
|
-
|
|
225
|
-
|
|
231
|
+
.tooltip::after {
|
|
232
|
+
/* small triangle that points to top */
|
|
233
|
+
content: '';
|
|
226
234
|
position: absolute;
|
|
227
235
|
bottom: 100%;
|
|
228
236
|
left: 10px;
|
|
229
237
|
margin-left: -5px;
|
|
230
238
|
border-width: 5px;
|
|
231
239
|
border-style: solid;
|
|
232
|
-
border-color: transparent transparent
|
|
240
|
+
border-color: transparent transparent var(--pb-timeline-background-color-title, #535353)
|
|
241
|
+
transparent;
|
|
233
242
|
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
243
|
+
.tooltip.chevron-precise::after {
|
|
244
|
+
left: var(--chevron-position, 50%);
|
|
245
|
+
right: auto;
|
|
246
|
+
margin-left: -5px;
|
|
247
|
+
margin-right: 0;
|
|
237
248
|
}
|
|
238
249
|
/* pure css close button for tooltip */
|
|
239
|
-
.close{
|
|
250
|
+
.close {
|
|
240
251
|
position: relative;
|
|
241
252
|
display: inline-block;
|
|
242
253
|
width: 50px;
|
|
@@ -247,7 +258,8 @@ export class PbTimeline extends pbMixin(LitElement) {
|
|
|
247
258
|
.close.rounded.black {
|
|
248
259
|
cursor: pointer;
|
|
249
260
|
}
|
|
250
|
-
.close::before,
|
|
261
|
+
.close::before,
|
|
262
|
+
.close::after {
|
|
251
263
|
content: '';
|
|
252
264
|
position: absolute;
|
|
253
265
|
height: 2px;
|
|
@@ -263,82 +275,99 @@ export class PbTimeline extends pbMixin(LitElement) {
|
|
|
263
275
|
.close::after {
|
|
264
276
|
transform: rotate(-45deg);
|
|
265
277
|
}
|
|
266
|
-
.close.thick::before,
|
|
278
|
+
.close.thick::before,
|
|
279
|
+
.close.thick::after {
|
|
267
280
|
height: 4px;
|
|
268
281
|
margin-top: -2px;
|
|
269
282
|
}
|
|
270
|
-
.close.black::before,
|
|
283
|
+
.close.black::before,
|
|
284
|
+
.close.black::after {
|
|
271
285
|
height: 8px;
|
|
272
286
|
margin-top: -4px;
|
|
273
287
|
}
|
|
274
|
-
.close.rounded::before,
|
|
288
|
+
.close.rounded::before,
|
|
289
|
+
.close.rounded::after {
|
|
275
290
|
border-radius: 5px;
|
|
276
291
|
}
|
|
292
|
+
#clear {
|
|
293
|
+
background-image: var(
|
|
294
|
+
--pb-dialog-background-image,
|
|
295
|
+
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(136, 145, 164)' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='18' y1='6' x2='6' y2='18'%3E%3C/line%3E%3Cline x1='6' y1='6' x2='18' y2='18'%3E%3C/line%3E%3C/svg%3E")
|
|
296
|
+
);
|
|
297
|
+
background-position: center;
|
|
298
|
+
background-size: auto 1rem;
|
|
299
|
+
background-repeat: no-repeat;
|
|
300
|
+
background-color: transparent;
|
|
301
|
+
border: none;
|
|
302
|
+
display: block;
|
|
303
|
+
height: 1rem;
|
|
304
|
+
width: 1rem;
|
|
305
|
+
}
|
|
277
306
|
`;
|
|
278
307
|
}
|
|
279
308
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
309
|
+
static get properties() {
|
|
310
|
+
return {
|
|
311
|
+
...super.properties,
|
|
312
|
+
/**
|
|
313
|
+
* start date for timeline to display
|
|
314
|
+
*/
|
|
315
|
+
startDate: {
|
|
316
|
+
type: String,
|
|
317
|
+
reflect: true,
|
|
318
|
+
attribute: 'start-date',
|
|
319
|
+
},
|
|
320
|
+
/**
|
|
321
|
+
* endDate for timeline to display
|
|
322
|
+
*/
|
|
323
|
+
endDate: {
|
|
324
|
+
type: String,
|
|
325
|
+
reflect: true,
|
|
326
|
+
attribute: 'end-date',
|
|
327
|
+
},
|
|
328
|
+
/**
|
|
329
|
+
* The scope for the timeline. Must be one of the pre-defined scopes.
|
|
330
|
+
* If not set, the component automatically tries to determine the best scope fitting the
|
|
331
|
+
* given time series.
|
|
332
|
+
*/
|
|
333
|
+
scope: {
|
|
334
|
+
type: String,
|
|
335
|
+
},
|
|
336
|
+
/**
|
|
337
|
+
* The scopes to consider for automatic scoping.
|
|
338
|
+
*
|
|
339
|
+
* Defaults to ["D", "W", "M", "Y", "5Y", "10Y"]
|
|
340
|
+
*/
|
|
341
|
+
scopes: {
|
|
342
|
+
type: Array,
|
|
343
|
+
},
|
|
344
|
+
maxInterval: {
|
|
345
|
+
type: Number,
|
|
346
|
+
attribute: 'max-interval',
|
|
347
|
+
},
|
|
348
|
+
/**
|
|
349
|
+
* Endpoint to load timeline data from. Expects response to be an
|
|
350
|
+
* object with key value pairs for (date, hits).
|
|
351
|
+
*
|
|
352
|
+
* Will be reloaded whenever 'start-date' or 'end-date' attributes change.
|
|
353
|
+
*/
|
|
354
|
+
url: {
|
|
355
|
+
type: String,
|
|
356
|
+
},
|
|
357
|
+
/**
|
|
358
|
+
* If set, data will be retrieved automatically on first load.
|
|
359
|
+
*/
|
|
360
|
+
auto: {
|
|
361
|
+
type: Boolean,
|
|
362
|
+
},
|
|
363
|
+
resettable: {
|
|
364
|
+
type: Boolean,
|
|
365
|
+
},
|
|
366
|
+
_language: {
|
|
367
|
+
type: String,
|
|
368
|
+
},
|
|
369
|
+
};
|
|
370
|
+
}
|
|
342
371
|
|
|
343
372
|
constructor() {
|
|
344
373
|
super();
|
|
@@ -348,7 +377,7 @@ export class PbTimeline extends pbMixin(LitElement) {
|
|
|
348
377
|
this.startDate = '';
|
|
349
378
|
this.endDate = '';
|
|
350
379
|
this.scope = '';
|
|
351
|
-
this.scopes = [
|
|
380
|
+
this.scopes = ['D', 'W', 'M', 'Y', '5Y', '10Y'];
|
|
352
381
|
this.maxInterval = 60;
|
|
353
382
|
this.url = '';
|
|
354
383
|
this.auto = false;
|
|
@@ -366,29 +395,29 @@ export class PbTimeline extends pbMixin(LitElement) {
|
|
|
366
395
|
loader.url = url;
|
|
367
396
|
loader.generateRequest();
|
|
368
397
|
});
|
|
369
|
-
this.subscribeTo('pb-i18n-update',
|
|
398
|
+
this.subscribeTo('pb-i18n-update', ev => {
|
|
370
399
|
this._language = ev.detail.language;
|
|
371
400
|
});
|
|
372
401
|
}
|
|
373
402
|
|
|
374
403
|
firstUpdated() {
|
|
375
|
-
this.bins = this.shadowRoot.querySelectorAll(
|
|
376
|
-
this.tooltip = this.shadowRoot.
|
|
404
|
+
this.bins = this.shadowRoot.querySelectorAll('.bin-container');
|
|
405
|
+
this.tooltip = this.shadowRoot.querySelector('.tooltip');
|
|
377
406
|
|
|
378
407
|
// global mouseup event
|
|
379
|
-
document.addEventListener(
|
|
408
|
+
document.addEventListener('mouseup', () => {
|
|
380
409
|
this._mouseUp();
|
|
381
|
-
})
|
|
410
|
+
});
|
|
382
411
|
// pb-timeline-daterange-changed event:
|
|
383
412
|
// changes daterange selection (marks bins on histogram)
|
|
384
413
|
// is triggered by the componeent itself but can be also triggered
|
|
385
414
|
// from outside by another component
|
|
386
|
-
document.addEventListener(
|
|
387
|
-
const startDateStr = event.detail
|
|
388
|
-
const endDateStr = event.detail
|
|
389
|
-
if (this._fullRangeSelected(startDateStr, endDateStr)){
|
|
415
|
+
document.addEventListener('pb-timeline-daterange-changed', event => {
|
|
416
|
+
const { startDateStr } = event.detail;
|
|
417
|
+
const { endDateStr } = event.detail;
|
|
418
|
+
if (this._fullRangeSelected(startDateStr, endDateStr)) {
|
|
390
419
|
// do not mark the whole histogram, reset selection instead
|
|
391
|
-
console.log(
|
|
420
|
+
console.log('_fullRangeSelected() is true');
|
|
392
421
|
this.resetSelection();
|
|
393
422
|
return;
|
|
394
423
|
}
|
|
@@ -398,38 +427,35 @@ export class PbTimeline extends pbMixin(LitElement) {
|
|
|
398
427
|
// resets selection (remove marking of all selected bins)
|
|
399
428
|
// is triggered by the componeent itself but can be also triggered
|
|
400
429
|
// from outside by another component
|
|
401
|
-
document.addEventListener(
|
|
430
|
+
document.addEventListener('pb-timeline-reset-selection', () => {
|
|
402
431
|
this.resetSelection();
|
|
403
432
|
this._hideTooltip();
|
|
404
433
|
});
|
|
405
434
|
}
|
|
406
435
|
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
updated
|
|
413
|
-
if(changedProperties.has('scope')){
|
|
414
|
-
|
|
415
|
-
if(this.
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
console.error('unknown scope ', this.scope);
|
|
420
|
-
}
|
|
436
|
+
/**
|
|
437
|
+
* checks if 'scope' has changed and re-applies dataset accordingly
|
|
438
|
+
*
|
|
439
|
+
* @param changedProperties
|
|
440
|
+
*/
|
|
441
|
+
updated(changedProperties) {
|
|
442
|
+
if (changedProperties.has('scope')) {
|
|
443
|
+
if (this.searchResult) {
|
|
444
|
+
if (this.scopes.includes(this.scope)) {
|
|
445
|
+
this.setData(this.searchResult.export(this.scope));
|
|
446
|
+
} else {
|
|
447
|
+
console.error('unknown scope ', this.scope);
|
|
421
448
|
}
|
|
422
|
-
|
|
449
|
+
}
|
|
423
450
|
}
|
|
424
451
|
}
|
|
425
452
|
|
|
426
|
-
|
|
427
453
|
setData(dataObj) {
|
|
428
454
|
this.dataObj = dataObj;
|
|
429
455
|
this.maxValue = Math.max(...this.dataObj.data.map(binObj => binObj.value));
|
|
430
456
|
this.requestUpdate();
|
|
431
457
|
this.updateComplete.then(() => {
|
|
432
|
-
this.bins = this.shadowRoot.querySelectorAll(
|
|
458
|
+
this.bins = this.shadowRoot.querySelectorAll('.bin-container');
|
|
433
459
|
this.resetSelection();
|
|
434
460
|
this._resetTooltip();
|
|
435
461
|
});
|
|
@@ -442,35 +468,39 @@ export class PbTimeline extends pbMixin(LitElement) {
|
|
|
442
468
|
if (this.dataObj.data.length === 1) {
|
|
443
469
|
return this.dataObj.data[0].category;
|
|
444
470
|
}
|
|
445
|
-
return `${this.dataObj.data[0].selectionStart} – ${
|
|
471
|
+
return `${this.dataObj.data[0].selectionStart} – ${
|
|
472
|
+
this.dataObj.data[this.dataObj.data.length - 1].selectionEnd
|
|
473
|
+
}`;
|
|
446
474
|
}
|
|
447
475
|
|
|
448
476
|
getSelectedStartDateStr() {
|
|
449
|
-
return this.shadowRoot.querySelectorAll(
|
|
477
|
+
return this.shadowRoot.querySelectorAll('.bin-container.selected')[0].dataset.selectionstart;
|
|
450
478
|
}
|
|
451
479
|
|
|
452
480
|
getSelectedEndDateStr() {
|
|
453
|
-
const selectedBins = this.shadowRoot.querySelectorAll(
|
|
481
|
+
const selectedBins = this.shadowRoot.querySelectorAll('.bin-container.selected');
|
|
454
482
|
return selectedBins[selectedBins.length - 1].dataset.selectionend;
|
|
455
483
|
}
|
|
456
484
|
|
|
457
485
|
getSelectedCategories() {
|
|
458
|
-
const selectedBins = this.shadowRoot.querySelectorAll(
|
|
486
|
+
const selectedBins = this.shadowRoot.querySelectorAll('.bin-container.selected');
|
|
459
487
|
const categories = [];
|
|
460
|
-
selectedBins.forEach(
|
|
488
|
+
selectedBins.forEach(bin => categories.push(bin.dataset.category));
|
|
461
489
|
return categories;
|
|
462
490
|
}
|
|
463
491
|
|
|
464
492
|
getSelectedItemCount() {
|
|
465
|
-
const selectedBins = this.shadowRoot.querySelectorAll(
|
|
493
|
+
const selectedBins = this.shadowRoot.querySelectorAll('.bin-container.selected');
|
|
466
494
|
let count = 0;
|
|
467
|
-
selectedBins.forEach(
|
|
495
|
+
selectedBins.forEach(bin => {
|
|
496
|
+
count += parseInt(bin.dataset.value);
|
|
497
|
+
});
|
|
468
498
|
return count;
|
|
469
499
|
}
|
|
470
500
|
|
|
471
501
|
resetSelection() {
|
|
472
502
|
this.bins.forEach(bin => {
|
|
473
|
-
bin.classList.remove(
|
|
503
|
+
bin.classList.remove('selected');
|
|
474
504
|
});
|
|
475
505
|
this._resetSelectionProperty();
|
|
476
506
|
this._hideTooltip();
|
|
@@ -479,8 +509,9 @@ export class PbTimeline extends pbMixin(LitElement) {
|
|
|
479
509
|
select(startDateStr, endDateStr) {
|
|
480
510
|
this.bins.forEach(bin => {
|
|
481
511
|
if (bin.dataset.isodatestr >= startDateStr && bin.dataset.isodatestr <= endDateStr) {
|
|
482
|
-
bin.classList.add(
|
|
483
|
-
} else {
|
|
512
|
+
bin.classList.add('selected');
|
|
513
|
+
} else {
|
|
514
|
+
bin.classList.remove('selected');
|
|
484
515
|
}
|
|
485
516
|
});
|
|
486
517
|
this._displayTooltip();
|
|
@@ -488,7 +519,7 @@ export class PbTimeline extends pbMixin(LitElement) {
|
|
|
488
519
|
}
|
|
489
520
|
|
|
490
521
|
_fullRangeSelected(startDateStr, endDateStr) {
|
|
491
|
-
const matchingStartDate = startDateStr = this.bins[0].dataset.isodatestr;
|
|
522
|
+
const matchingStartDate = (startDateStr = this.bins[0].dataset.isodatestr);
|
|
492
523
|
const matchingEndDate = endDateStr === this.bins[this.bins.length - 1].dataset.isodatestr;
|
|
493
524
|
return matchingStartDate && matchingEndDate;
|
|
494
525
|
}
|
|
@@ -509,7 +540,12 @@ export class PbTimeline extends pbMixin(LitElement) {
|
|
|
509
540
|
const startDateStr = new ParseDateService().run(start);
|
|
510
541
|
const endDateStr = new ParseDateService().run(end);
|
|
511
542
|
const itemCount = this.getSelectedItemCount();
|
|
512
|
-
this._dispatchTimelineDaterangeChangedEvent(
|
|
543
|
+
this._dispatchTimelineDaterangeChangedEvent(
|
|
544
|
+
startDateStr,
|
|
545
|
+
endDateStr,
|
|
546
|
+
this.getSelectedCategories(),
|
|
547
|
+
itemCount,
|
|
548
|
+
);
|
|
513
549
|
}
|
|
514
550
|
}
|
|
515
551
|
}
|
|
@@ -518,22 +554,24 @@ export class PbTimeline extends pbMixin(LitElement) {
|
|
|
518
554
|
if (this.mousedown) {
|
|
519
555
|
this._brushing(event);
|
|
520
556
|
this._showtooltipSelection();
|
|
521
|
-
} else if (this.selection.start === undefined) {
|
|
557
|
+
} else if (this.selection.start === undefined) {
|
|
558
|
+
// no selection currently made
|
|
522
559
|
this._showtooltip(event);
|
|
523
560
|
}
|
|
524
561
|
}
|
|
525
562
|
|
|
526
563
|
_mouseenter() {
|
|
527
|
-
if (this.dataObj) {
|
|
564
|
+
if (this.dataObj) {
|
|
565
|
+
// if data is loaded
|
|
528
566
|
this._displayTooltip();
|
|
529
567
|
}
|
|
530
568
|
}
|
|
531
569
|
|
|
532
570
|
_getMousePosition(mouseEvent) {
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
return { x
|
|
571
|
+
const rect = this.shadowRoot.querySelector('.wrapper').getBoundingClientRect();
|
|
572
|
+
const x = mouseEvent.clientX - rect.left + 1; // x position within the element.
|
|
573
|
+
const y = mouseEvent.clientY - rect.top + 1; // y position within the element.
|
|
574
|
+
return { x, y };
|
|
537
575
|
}
|
|
538
576
|
|
|
539
577
|
_brushing(event) {
|
|
@@ -543,8 +581,13 @@ export class PbTimeline extends pbMixin(LitElement) {
|
|
|
543
581
|
|
|
544
582
|
_dispatchTimelineDaterangeChangedEvent(startDateStr, endDateStr, categories, itemCount) {
|
|
545
583
|
if (startDateStr === '????-??-??') {
|
|
546
|
-
this.emitTo('pb-timeline-date-changed', {
|
|
547
|
-
|
|
584
|
+
this.emitTo('pb-timeline-date-changed', {
|
|
585
|
+
startDateStr: null,
|
|
586
|
+
endDateStr: null,
|
|
587
|
+
categories: ['?'],
|
|
588
|
+
count: itemCount,
|
|
589
|
+
});
|
|
590
|
+
} else if (startDateStr === endDateStr) {
|
|
548
591
|
if (this.dataObj.scope !== 'D') {
|
|
549
592
|
this.emitTo('pb-timeline-daterange-changed', {
|
|
550
593
|
startDateStr,
|
|
@@ -552,16 +595,16 @@ export class PbTimeline extends pbMixin(LitElement) {
|
|
|
552
595
|
scope: this.dataObj.scope,
|
|
553
596
|
categories,
|
|
554
597
|
count: itemCount,
|
|
555
|
-
label: this.label
|
|
598
|
+
label: this.label,
|
|
556
599
|
});
|
|
557
600
|
} else {
|
|
558
|
-
this.emitTo('pb-timeline-date-changed', {
|
|
559
|
-
startDateStr,
|
|
560
|
-
endDateStr: null,
|
|
561
|
-
scope: this.dataObj.scope,
|
|
562
|
-
categories,
|
|
601
|
+
this.emitTo('pb-timeline-date-changed', {
|
|
602
|
+
startDateStr,
|
|
603
|
+
endDateStr: null,
|
|
604
|
+
scope: this.dataObj.scope,
|
|
605
|
+
categories,
|
|
563
606
|
count: itemCount,
|
|
564
|
-
label: this.label
|
|
607
|
+
label: this.label,
|
|
565
608
|
});
|
|
566
609
|
}
|
|
567
610
|
} else {
|
|
@@ -571,7 +614,7 @@ export class PbTimeline extends pbMixin(LitElement) {
|
|
|
571
614
|
categories,
|
|
572
615
|
scope: this.dataObj.scope,
|
|
573
616
|
count: itemCount,
|
|
574
|
-
label: this.label
|
|
617
|
+
label: this.label,
|
|
575
618
|
});
|
|
576
619
|
}
|
|
577
620
|
}
|
|
@@ -582,61 +625,147 @@ export class PbTimeline extends pbMixin(LitElement) {
|
|
|
582
625
|
|
|
583
626
|
_showtooltip(event) {
|
|
584
627
|
const interval = this._getElementInterval(event.currentTarget);
|
|
628
|
+
const datestr = event.currentTarget.dataset.tooltip;
|
|
629
|
+
const value = this._numberWithCommas(event.currentTarget.dataset.value);
|
|
630
|
+
const info = event.currentTarget.querySelector('.info');
|
|
631
|
+
this.tooltip.querySelector(
|
|
632
|
+
'.tooltip-text',
|
|
633
|
+
).innerHTML = `<div><strong>${datestr}</strong>: ${value}</div><ul>${
|
|
634
|
+
info ? info.innerHTML : ''
|
|
635
|
+
}</ul>`;
|
|
636
|
+
|
|
637
|
+
// Force a reflow to get accurate tooltip dimensions
|
|
638
|
+
this.tooltip.style.visibility = 'hidden';
|
|
639
|
+
this.tooltip.style.display = 'block';
|
|
640
|
+
const tooltipWidth = this.tooltip.offsetWidth;
|
|
641
|
+
this.tooltip.style.visibility = '';
|
|
642
|
+
this.tooltip.style.display = '';
|
|
643
|
+
|
|
644
|
+
const wrapper = this.shadowRoot.querySelector('.wrapper');
|
|
645
|
+
const wrapperRect = wrapper.getBoundingClientRect();
|
|
646
|
+
const wrapperWidth = wrapperRect.width;
|
|
647
|
+
|
|
585
648
|
let offset;
|
|
586
|
-
|
|
587
|
-
|
|
649
|
+
const centerPosition = Math.round((interval[0] + interval[1]) / 2);
|
|
650
|
+
|
|
651
|
+
// Clear any existing chevron positioning classes
|
|
652
|
+
this.tooltip.classList.remove('chevron-precise');
|
|
653
|
+
|
|
654
|
+
// Check if tooltip would overflow on the right
|
|
655
|
+
if (centerPosition + tooltipWidth / 2 > wrapperWidth) {
|
|
656
|
+
// Position tooltip to the right of the bin, aligned to the right edge
|
|
657
|
+
offset = Math.max(0, interval[1] - tooltipWidth + 10);
|
|
658
|
+
this.tooltip.classList.add('right');
|
|
659
|
+
} else if (centerPosition - tooltipWidth / 2 < 0) {
|
|
660
|
+
// Position tooltip to the left of the bin, aligned to the left edge
|
|
661
|
+
offset = Math.min(wrapperWidth - tooltipWidth, interval[0] - 10);
|
|
588
662
|
this.tooltip.classList.remove('right');
|
|
589
663
|
} else {
|
|
590
|
-
|
|
591
|
-
|
|
664
|
+
// Center the tooltip
|
|
665
|
+
offset = centerPosition - tooltipWidth / 2;
|
|
666
|
+
this.tooltip.classList.remove('right');
|
|
592
667
|
}
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
668
|
+
|
|
669
|
+
this.tooltip.style.left = `${offset}px`;
|
|
670
|
+
|
|
671
|
+
// Calculate precise chevron position to point to the bin
|
|
672
|
+
const binCenter = centerPosition;
|
|
673
|
+
const tooltipLeft = offset;
|
|
674
|
+
const chevronPosition = Math.max(10, Math.min(tooltipWidth - 10, binCenter - tooltipLeft));
|
|
675
|
+
this.tooltip.style.setProperty('--chevron-position', `${chevronPosition}px`);
|
|
676
|
+
this.tooltip.classList.add('chevron-precise');
|
|
599
677
|
}
|
|
600
678
|
|
|
601
679
|
_showtooltipSelection() {
|
|
602
680
|
const selectedBins = this._getSelectedBins();
|
|
603
681
|
const intervalStart = this._getElementInterval(selectedBins[0])[0]; // get first selected element left boundary
|
|
604
|
-
const intervalEnd = this._getElementInterval(selectedBins[selectedBins.length-1])[1]; // get last selected element right boundary
|
|
682
|
+
const intervalEnd = this._getElementInterval(selectedBins[selectedBins.length - 1])[1]; // get last selected element right boundary
|
|
605
683
|
const interval = [intervalStart, intervalEnd];
|
|
606
|
-
const label = `${selectedBins[0].dataset.selectionstart} - ${
|
|
684
|
+
const label = `${selectedBins[0].dataset.selectionstart} - ${
|
|
685
|
+
selectedBins[selectedBins.length - 1].dataset.selectionend
|
|
686
|
+
}`;
|
|
607
687
|
const value = selectedBins.map(bin => Number(bin.dataset.value)).reduce((a, b) => a + b);
|
|
608
688
|
const valueFormatted = this._numberWithCommas(value);
|
|
609
|
-
this.tooltip.querySelector(
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
this.tooltip.
|
|
689
|
+
this.tooltip.querySelector(
|
|
690
|
+
'.tooltip-text',
|
|
691
|
+
).innerHTML = `<strong>${label}</strong>: ${valueFormatted}`;
|
|
692
|
+
this.tooltip.querySelector('.tooltip-close').classList.remove('hidden');
|
|
693
|
+
this.tooltip.classList.add('draggable');
|
|
694
|
+
|
|
695
|
+
// Force a reflow to get accurate tooltip dimensions
|
|
696
|
+
this.tooltip.style.visibility = 'hidden';
|
|
697
|
+
this.tooltip.style.display = 'block';
|
|
698
|
+
const tooltipWidth = this.tooltip.offsetWidth;
|
|
699
|
+
this.tooltip.style.visibility = '';
|
|
700
|
+
this.tooltip.style.display = '';
|
|
701
|
+
|
|
702
|
+
const wrapper = this.shadowRoot.querySelector('.wrapper');
|
|
703
|
+
const wrapperRect = wrapper.getBoundingClientRect();
|
|
704
|
+
const wrapperWidth = wrapperRect.width;
|
|
705
|
+
|
|
706
|
+
const centerPosition = Math.round((interval[0] + interval[1]) / 2);
|
|
707
|
+
let offset;
|
|
708
|
+
|
|
709
|
+
// Clear any existing chevron positioning classes
|
|
710
|
+
this.tooltip.classList.remove('chevron-precise');
|
|
711
|
+
|
|
712
|
+
// Check if tooltip would overflow on the right
|
|
713
|
+
if (centerPosition + tooltipWidth / 2 > wrapperWidth) {
|
|
714
|
+
// Position tooltip to the right of the selection, aligned to the right edge
|
|
715
|
+
offset = Math.max(0, interval[1] - tooltipWidth + 10);
|
|
716
|
+
this.tooltip.classList.add('right');
|
|
717
|
+
} else if (centerPosition - tooltipWidth / 2 < 0) {
|
|
718
|
+
// Position tooltip to the left of the selection, aligned to the left edge
|
|
719
|
+
offset = Math.min(wrapperWidth - tooltipWidth, interval[0] - 10);
|
|
720
|
+
this.tooltip.classList.remove('right');
|
|
721
|
+
} else {
|
|
722
|
+
// Center the tooltip
|
|
723
|
+
offset = centerPosition - tooltipWidth / 2;
|
|
724
|
+
this.tooltip.classList.remove('right');
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
this.tooltip.style.left = `${offset}px`;
|
|
728
|
+
|
|
729
|
+
// Calculate precise chevron position to point to the center of the selection
|
|
730
|
+
const selectionCenter = centerPosition;
|
|
731
|
+
const tooltipLeft = offset;
|
|
732
|
+
const chevronPosition = Math.max(
|
|
733
|
+
10,
|
|
734
|
+
Math.min(tooltipWidth - 10, selectionCenter - tooltipLeft),
|
|
735
|
+
);
|
|
736
|
+
this.tooltip.style.setProperty('--chevron-position', `${chevronPosition}px`);
|
|
737
|
+
this.tooltip.classList.add('chevron-precise');
|
|
614
738
|
}
|
|
615
739
|
|
|
616
740
|
_resetTooltip() {
|
|
617
741
|
this._hideTooltip();
|
|
618
742
|
this.tooltip.style.left = '-1000px';
|
|
619
|
-
this.tooltip.querySelector(
|
|
743
|
+
this.tooltip.querySelector('.tooltip-text').innerHTML = '';
|
|
620
744
|
}
|
|
621
745
|
|
|
622
746
|
_hideTooltip() {
|
|
623
747
|
if (this.selection.start === undefined) {
|
|
624
|
-
this.tooltip.classList.add(
|
|
625
|
-
this.tooltip.classList.remove(
|
|
626
|
-
this.tooltip.querySelector(
|
|
748
|
+
this.tooltip.classList.add('hidden');
|
|
749
|
+
this.tooltip.classList.remove('draggable');
|
|
750
|
+
this.tooltip.querySelector('.tooltip-close').classList.add('hidden');
|
|
751
|
+
// Clear chevron positioning classes
|
|
752
|
+
this.tooltip.classList.remove('chevron-precise');
|
|
627
753
|
}
|
|
628
754
|
}
|
|
629
755
|
|
|
630
756
|
_displayTooltip() {
|
|
631
|
-
this.tooltip.classList.remove(
|
|
757
|
+
this.tooltip.classList.remove('hidden');
|
|
632
758
|
}
|
|
633
759
|
|
|
634
760
|
_getElementInterval(nodeElement) {
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
761
|
+
const rect = this.shadowRoot.querySelector('.wrapper').getBoundingClientRect();
|
|
762
|
+
const bin = nodeElement;
|
|
763
|
+
const interval = [
|
|
764
|
+
bin.getBoundingClientRect().x,
|
|
765
|
+
bin.getBoundingClientRect().x + bin.getBoundingClientRect().width,
|
|
766
|
+
];
|
|
767
|
+
const x1 = interval[0] - rect.left + 1; // x position within the element.
|
|
768
|
+
const x2 = interval[1] - rect.left + 1; // x position within the element.
|
|
640
769
|
return [x1, x2, rect.width / 2];
|
|
641
770
|
}
|
|
642
771
|
|
|
@@ -645,16 +774,16 @@ export class PbTimeline extends pbMixin(LitElement) {
|
|
|
645
774
|
}
|
|
646
775
|
|
|
647
776
|
_getSelectedBins() {
|
|
648
|
-
return Array.prototype.slice
|
|
649
|
-
|
|
650
|
-
|
|
777
|
+
return Array.prototype.slice
|
|
778
|
+
.call(this.bins)
|
|
779
|
+
.filter(binContainer => binContainer.classList.contains('selected'));
|
|
651
780
|
}
|
|
652
781
|
|
|
653
782
|
_resetSelectionProperty() {
|
|
654
783
|
this.selection = {
|
|
655
784
|
start: undefined,
|
|
656
|
-
end: undefined
|
|
657
|
-
}
|
|
785
|
+
end: undefined,
|
|
786
|
+
};
|
|
658
787
|
}
|
|
659
788
|
|
|
660
789
|
_applySelectionToBins() {
|
|
@@ -663,18 +792,19 @@ export class PbTimeline extends pbMixin(LitElement) {
|
|
|
663
792
|
const elInterval = this._getElementInterval(bin);
|
|
664
793
|
// if (this.intervalsOverlapping(elInterval, selectionInterval)) {
|
|
665
794
|
if (this._areOverlapping(elInterval, selectionInterval)) {
|
|
666
|
-
bin.classList.add(
|
|
795
|
+
bin.classList.add('selected');
|
|
667
796
|
} else {
|
|
668
|
-
bin.classList.remove(
|
|
797
|
+
bin.classList.remove('selected');
|
|
669
798
|
}
|
|
670
|
-
})
|
|
799
|
+
});
|
|
671
800
|
}
|
|
672
801
|
|
|
673
802
|
_numberWithCommas(input) {
|
|
674
|
-
return new Intl.NumberFormat(this._language, {style: 'decimal'}).format(input);
|
|
803
|
+
return new Intl.NumberFormat(this._language, { style: 'decimal' }).format(input);
|
|
675
804
|
}
|
|
676
805
|
|
|
677
|
-
_areOverlapping(A, B) {
|
|
806
|
+
_areOverlapping(A, B) {
|
|
807
|
+
// check if 2 intervals are overlapping
|
|
678
808
|
return B[0] < A[0] ? B[1] > A[0] : B[0] < A[1];
|
|
679
809
|
}
|
|
680
810
|
|
|
@@ -682,40 +812,43 @@ export class PbTimeline extends pbMixin(LitElement) {
|
|
|
682
812
|
return html`
|
|
683
813
|
<div class="label" part="label">
|
|
684
814
|
<span class="label"><slot name="label"></slot>${this.label}</span>
|
|
685
|
-
${
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
815
|
+
${this.resettable
|
|
816
|
+
? html`
|
|
817
|
+
<button
|
|
818
|
+
id="clear"
|
|
819
|
+
title="${translate('timeline.clear')}"
|
|
820
|
+
@click="${this._dispatchPbTimelineResetSelectionEvent}"
|
|
821
|
+
type="button"
|
|
822
|
+
></button>
|
|
823
|
+
`
|
|
824
|
+
: null}
|
|
691
825
|
</div>
|
|
692
|
-
<div
|
|
826
|
+
<div
|
|
827
|
+
class="wrapper ${!this.dataObj || this.dataObj.data.length <= 1 ? 'empty' : ''}"
|
|
693
828
|
@mouseenter="${this._mouseenter}"
|
|
694
|
-
@mouseleave="${this._hideTooltip}"
|
|
695
|
-
|
|
696
|
-
${this.renderTooltip()}
|
|
697
|
-
<
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
829
|
+
@mouseleave="${this._hideTooltip}"
|
|
830
|
+
>
|
|
831
|
+
${this.dataObj ? this.renderBins() : ''} ${this.renderTooltip()}
|
|
832
|
+
<pb-fetch
|
|
833
|
+
id="loadData"
|
|
834
|
+
verbose
|
|
835
|
+
handle-as="json"
|
|
836
|
+
method="get"
|
|
837
|
+
with-credentials
|
|
838
|
+
@response="${this._handleResponse}"
|
|
839
|
+
url="${this.url}?start=${this.startDate}&end=${this.endDate}"
|
|
840
|
+
?auto="${this.auto}"
|
|
841
|
+
></pb-fetch>
|
|
706
842
|
</div>
|
|
707
843
|
`;
|
|
708
844
|
}
|
|
709
845
|
|
|
710
846
|
renderTooltip() {
|
|
711
847
|
return html`
|
|
712
|
-
<div
|
|
713
|
-
<div
|
|
714
|
-
<div
|
|
715
|
-
|
|
716
|
-
class="hidden"
|
|
717
|
-
@click="${this._dispatchPbTimelineResetSelectionEvent}"
|
|
718
|
-
><span class="close rounded black"></span>
|
|
848
|
+
<div class="tooltip hidden" part="tooltip">
|
|
849
|
+
<div class="tooltip-text"></div>
|
|
850
|
+
<div class="tooltip-close hidden" @click="${this._dispatchPbTimelineResetSelectionEvent}">
|
|
851
|
+
<span class="close rounded black"></span>
|
|
719
852
|
</div>
|
|
720
853
|
</div>
|
|
721
854
|
`;
|
|
@@ -723,10 +856,11 @@ export class PbTimeline extends pbMixin(LitElement) {
|
|
|
723
856
|
|
|
724
857
|
renderBins() {
|
|
725
858
|
return html`
|
|
726
|
-
${this.dataObj.data.map(
|
|
727
|
-
|
|
728
|
-
<div
|
|
729
|
-
|
|
859
|
+
${this.dataObj.data.map(
|
|
860
|
+
(binObj, indx) => html`
|
|
861
|
+
<div
|
|
862
|
+
class="bin-container ${binObj.seperator ? 'border-left' : ''}
|
|
863
|
+
${indx % 2 === 0 ? 'grey' : 'white'} ${binObj.category === '?' ? 'unknown' : ''}"
|
|
730
864
|
data-tooltip="${binObj.tooltip}"
|
|
731
865
|
data-category="${binObj.category}"
|
|
732
866
|
data-selectionstart="${binObj.selectionStart}"
|
|
@@ -735,20 +869,24 @@ export class PbTimeline extends pbMixin(LitElement) {
|
|
|
735
869
|
data-datestr="${binObj.dateStr}"
|
|
736
870
|
data-value="${binObj.value}"
|
|
737
871
|
@mousemove="${this._mouseMove}"
|
|
738
|
-
@mousedown="${this._mouseDown}"
|
|
739
|
-
|
|
740
|
-
<
|
|
741
|
-
|
|
872
|
+
@mousedown="${this._mouseDown}"
|
|
873
|
+
>
|
|
874
|
+
<div
|
|
875
|
+
class="bin"
|
|
876
|
+
style="height: ${(binObj.value / this.maxValue) * this.maxHeight * this.multiplier}px"
|
|
877
|
+
></div>
|
|
878
|
+
<p
|
|
879
|
+
class="bin-title
|
|
880
|
+
${this.dataObj.binTitleRotated ? 'rotated' : ''}
|
|
742
881
|
${this.scope}"
|
|
743
|
-
|
|
882
|
+
>
|
|
883
|
+
${binObj.binTitle ? binObj.binTitle : ''}
|
|
744
884
|
</p>
|
|
745
|
-
${binObj.title ? html`
|
|
746
|
-
<p class="bins-title" part="title">${binObj.title}</p>
|
|
747
|
-
` : ""}
|
|
885
|
+
${binObj.title ? html` <p class="bins-title" part="title">${binObj.title}</p> ` : ''}
|
|
748
886
|
${this.renderInfo(binObj)}
|
|
749
887
|
</div>
|
|
750
|
-
|
|
751
|
-
|
|
888
|
+
`,
|
|
889
|
+
)}
|
|
752
890
|
`;
|
|
753
891
|
}
|
|
754
892
|
|
|
@@ -756,34 +894,35 @@ export class PbTimeline extends pbMixin(LitElement) {
|
|
|
756
894
|
if (binObj.info && binObj.info.length > 0 && binObj.info.length <= 10) {
|
|
757
895
|
return html`
|
|
758
896
|
<ul class="info">
|
|
759
|
-
|
|
897
|
+
${binObj.info.map(info => html`<li>${unsafeHTML(info)}</li>`)}
|
|
760
898
|
</ul>
|
|
761
899
|
`;
|
|
762
900
|
}
|
|
763
901
|
return null;
|
|
764
902
|
}
|
|
765
903
|
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
904
|
+
async _handleResponse() {
|
|
905
|
+
await this.updateComplete;
|
|
906
|
+
const loader = this.shadowRoot.getElementById('loadData');
|
|
907
|
+
const data = loader.lastResponse;
|
|
770
908
|
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
newJsonData = data;
|
|
778
|
-
}
|
|
779
|
-
this.searchResult = new SearchResultService(newJsonData, this.maxInterval, this.scopes);
|
|
780
|
-
this.setData(this.searchResult.export(this.scope));
|
|
781
|
-
this.emitTo('pb-timeline-loaded', {
|
|
782
|
-
value: true,
|
|
783
|
-
label: this.label
|
|
909
|
+
let newJsonData = {};
|
|
910
|
+
if (this.startDate && this.endDate) {
|
|
911
|
+
Object.keys(data)
|
|
912
|
+
.filter(key => key >= this.startDate && key < this.endDate)
|
|
913
|
+
.forEach(key => {
|
|
914
|
+
newJsonData[key] = data[key];
|
|
784
915
|
});
|
|
916
|
+
} else {
|
|
917
|
+
newJsonData = data;
|
|
785
918
|
}
|
|
786
|
-
|
|
919
|
+
this.searchResult = new SearchResultService(newJsonData, this.maxInterval, this.scopes);
|
|
920
|
+
this.setData(this.searchResult.export(this.scope));
|
|
921
|
+
this.emitTo('pb-timeline-loaded', {
|
|
922
|
+
value: true,
|
|
923
|
+
label: this.label,
|
|
924
|
+
});
|
|
925
|
+
}
|
|
787
926
|
}
|
|
788
927
|
|
|
789
928
|
customElements.define('pb-timeline', PbTimeline);
|