@inb/oeb_visualizations 0.0.6-beta → 0.0.7

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.
@@ -0,0 +1,825 @@
1
+ 'use strict';Object.defineProperty(exports,'__esModule',{value:true});var Plotly=require('plotly.js-dist');function _interopDefaultLegacy(e){return e&&typeof e==='object'&&'default'in e?e:{'default':e}}var Plotly__default=/*#__PURE__*/_interopDefaultLegacy(Plotly);function randstr(prefix) {
2
+ return Math.random().toString(36).replace('0.', prefix || '');
3
+ }//
4
+ var script$1 = {
5
+ name: 'accessibilityPlot',
6
+ data: () => ({
7
+ divId: randstr('acc_plot'),
8
+ max_access_time: 0
9
+ }),
10
+ props: {
11
+ dtick: {
12
+ /*
13
+ dtick is the interval between ticks on the x axis in ms.
14
+ */
15
+ type: Number,
16
+ required: false,
17
+ default: 86400000.0
18
+ },
19
+ xaxisTitle: {
20
+ /*
21
+ xaxisTitle is the title of the x axis.
22
+ */
23
+ type: String,
24
+ required: false,
25
+ default: 'Date'
26
+ },
27
+ yaxisTitle: {
28
+ /*
29
+ yaxisTitle is the title of the y axis.
30
+ */
31
+ type: String,
32
+ required: false,
33
+ default: 'Access time (ms)'
34
+ },
35
+ colorOnline: {
36
+ /*
37
+ colorOnline is the color of the online line.
38
+ format: "<R>, <G>, <B>"
39
+ */
40
+ type: String,
41
+ required: false,
42
+ default: '111, 176, 129'
43
+ },
44
+ colorOffline: {
45
+ /*
46
+ colorOffline is the color of the offline bars.
47
+ format: "<R>, <G>, <B>"
48
+ */
49
+ type: String,
50
+ required: false,
51
+ default: '255, 153, 145'
52
+ },
53
+ colorNA: {
54
+ /*
55
+ colorNA is the color of the NA bars.
56
+ format: "<R>, <G>, <B>"
57
+ */
58
+ type: String,
59
+ required: false,
60
+ default: '204,204,204'
61
+ },
62
+ height: {
63
+ /*
64
+ height is the height of the plot in px.
65
+ */
66
+ type: Number,
67
+ required: false,
68
+ default: 350
69
+ },
70
+ week: {
71
+ /*
72
+ whether the plot is used to show data of one week
73
+ If true, days of the week are shown on the x axis
74
+ */
75
+ type: Boolean,
76
+ required: false,
77
+ default: false
78
+ },
79
+ dataItems: {
80
+ /*
81
+ dataItems is an array of objects with keys "access_time", "date" and "code".
82
+ - access_time is the time it took to access the server in ms.
83
+ - date is the date of the access.
84
+ - code is the HTTP code returned by the server.
85
+ Each object represents an access to the server.
86
+ */
87
+ type: Array,
88
+ required: true,
89
+ validator: function (value) {
90
+ /*
91
+ This function validates the dataItems prop. It throws a console error if the prop is not valid.
92
+ TODO: apply vue-types to define the prop.
93
+ https://github.com/dwightjack/vue-types
94
+ */
95
+ for (let i = 0; i < value.length; i++) {
96
+ // The value must be an array of objects with keys "access_time", "date" and "code"
97
+ if (!value[i].hasOwnProperty('access_time')) {
98
+ console.error(`[oeb-visualizations warn] access_time key is missing in dataItems prop item (at position ${i})`);
99
+ } else if (!value[i].hasOwnProperty('date')) {
100
+ console.error(`[oeb-visualizations warn] date key is missing in dataItems prop item (at position ${i})`);
101
+ } else if (!value[i].hasOwnProperty('code')) {
102
+ console.error(`[oeb-visualizations warn] code key is missing in dataItems prop item (at position ${i})`);
103
+ }
104
+ // Access time must be null or a number
105
+ if (value[i].access_time !== null && typeof value[i].access_time !== 'number') {
106
+ console.error(`[oeb-visualizations warn] access_time must be null or a number in dataItems prop item (at position ${i})`);
107
+ }
108
+ // Code must be null or a number
109
+ if (value[i].code !== null && typeof value[i].code !== 'number') {
110
+ console.error(`[oeb-visualizations warn] code must be null or a number in dataItems prop item (at position ${i})`);
111
+ }
112
+ // Date must be a string containing a date
113
+ if (typeof value[i].date !== 'string' || isNaN(Date.parse(value[i].date))) {
114
+ console.error(`[oeb-visualizations warn] date must be a string containing a date in dataItems prop item (at position ${i})`);
115
+ }
116
+
117
+ // And date cannot be null
118
+ if (value[i].date === null) {
119
+ console.error(`[oeb-visualizations warn] date cannot be null in dataItems prop item (at position ${i})`);
120
+ }
121
+ }
122
+ return true;
123
+ }
124
+ }
125
+ },
126
+ mounted() {
127
+ this.max_access_time = Math.max(...this.dataItems.map(item => item.access_time));
128
+ var traces = this.buildOnlineTraces(this.dataItems); // generate line traces
129
+
130
+ traces = traces.concat(this.buildOfflineNATraces(this.dataItems)); // generate bar traces
131
+
132
+ const layout = {
133
+ bargap: 0.0,
134
+ barmode: 'stack',
135
+ showlegend: true,
136
+ autosize: true,
137
+ height: this.height,
138
+ margin: {
139
+ l: 50,
140
+ r: 50,
141
+ b: 70,
142
+ t: 70,
143
+ pad: 4
144
+ },
145
+ xaxis: {
146
+ type: 'date',
147
+ title: this.xaxisTitle,
148
+ font: {
149
+ size: 10
150
+ },
151
+ tickfont: {
152
+ size: 10
153
+ },
154
+ showgrid: this.week ? true : false,
155
+ griddash: "dot",
156
+ gridwidth: 1,
157
+ showspikes: true,
158
+ spikedash: "4px",
159
+ spikethickness: 1,
160
+ tick0: this.dataItems[0].date,
161
+ dtick: this.dtick,
162
+ tickangle: this.xaxesTickAngle(),
163
+ tickformat: this.xaxesTickFormat()
164
+ },
165
+ yaxis: {
166
+ title: this.yaxisTitle,
167
+ titlefont: {
168
+ size: 10
169
+ },
170
+ tickfont: {
171
+ size: 10
172
+ }
173
+ },
174
+ template: 'plotly_white',
175
+ legend: {
176
+ orientation: 'h',
177
+ yanchor: 'bottom',
178
+ y: 1.02,
179
+ xanchor: 'right',
180
+ x: 1,
181
+ font: {
182
+ size: 8
183
+ }
184
+ },
185
+ hoverlabel: {
186
+ bgcolor: "#FFF"
187
+ },
188
+ hovermode: 'closest'
189
+ };
190
+ Plotly__default["default"].newPlot(this.divId, traces, layout);
191
+ },
192
+ methods: {
193
+ generateColor(values, transparency) {
194
+ /*
195
+ Parameters:
196
+ - values: array of values. Values must be in ["up", "down", "NA"]
197
+ - transparency: float between 0 and 1
198
+ Returns an array of colors in the form "rgba(255, 153, 145,0.8)"
199
+ */
200
+ let colors = [];
201
+ for (let i = 0; i < 30; i++) {
202
+ switch (values[i]) {
203
+ case "up":
204
+ colors.push(`rgba(${this.colorOnline},0)`);
205
+ break;
206
+ case "down":
207
+ colors.push(`rgba(${this.colorOffline},${transparency})`);
208
+ break;
209
+ case "NA":
210
+ colors.push(`rgba(${this.colorNA},${transparency})`);
211
+ }
212
+ }
213
+ return colors;
214
+ },
215
+ extractSubarraysBetweenNullValues(data) {
216
+ /*
217
+ This function extracts subarrays of access_time between null values.
218
+ This is, consecutive access_time values that are not null and separated by null values.
219
+ It also creates the subarrays of dates for those access_time values.
220
+ It also computes the average access time of the whole data.
221
+ Parameters:
222
+ - data: array of objects with keys "access_time" and "date". access_time can be null
223
+ Returns an object with keys:
224
+ - access_time: array of arrays of access_time values
225
+ - date: array of arrays of dates
226
+ - average_access_time: average access time of the whole data
227
+ */
228
+
229
+ var subarrays = {
230
+ access_time: [],
231
+ date: [],
232
+ average_access_time: 0
233
+ };
234
+ var subarrayTime = [];
235
+ var subarrayDate = [];
236
+ var sum = 0;
237
+ var nonNullValues = 0;
238
+ for (let i = 0; i < data.length; i++) {
239
+ if (data[i].access_time !== null) {
240
+ // keep adding to subarray
241
+ subarrayTime.push(data[i].access_time);
242
+ subarrayDate.push(data[i].date);
243
+ sum += data[i].access_time;
244
+ nonNullValues += 1;
245
+ } else {
246
+ // Push subarray to subarrays and reset subarray
247
+ if (subarrayTime.length > 0) {
248
+ subarrays.access_time.push(subarrayTime);
249
+ subarrays.date.push(subarrayDate);
250
+ subarrayTime = [];
251
+ subarrayDate = [];
252
+ }
253
+ }
254
+ }
255
+ // push last subarray
256
+ subarrays.access_time.push(subarrayTime);
257
+ subarrays.date.push(subarrayDate);
258
+
259
+ // compute average access time
260
+ subarrays.average_access_time = sum / nonNullValues;
261
+ return subarrays;
262
+ },
263
+ buildAccessTimeTraces(subarrays) {
264
+ /*
265
+ This function builds the line traces of access time between null values.
266
+
267
+ Arguments:
268
+ - subarrays: object with keys "access_time" and "date".
269
+ - access_time is an array of arrays of access_time values.
270
+ - date is an array of arrays of dates.
271
+ Returns an array of line traces
272
+ */
273
+
274
+ var traces = []; // stores resulting traces
275
+
276
+ // iterate over subarrays and build line traces
277
+ for (let i = 0; i < subarrays.access_time.length; i++) {
278
+ const subarray = subarrays.access_time[i];
279
+ const subarrayDate = subarrays.date[i];
280
+ const showlegend = i === 0 ? true : false;
281
+ const trace = {
282
+ x: subarrayDate,
283
+ y: subarray,
284
+ name: 'Online',
285
+ legendgroup: 'up',
286
+ showlegend: showlegend,
287
+ mode: 'markers+lines',
288
+ type: 'scatter',
289
+ fill: 'tozeroy',
290
+ fillcolor: `rgba(${this.colorOnline},.2)`,
291
+ connectgaps: false,
292
+ line: {
293
+ color: `rgba(${this.colorOnline},.8)`,
294
+ width: 1.5
295
+ },
296
+ marker: {
297
+ size: 5
298
+ },
299
+ hovertemplate: '<b>Online</b><br>%{x|%d %b %Y}<br>%{y} ms <extra></extra>',
300
+ hoveron: 'points+fills'
301
+ };
302
+ traces.push(trace);
303
+ }
304
+ return traces;
305
+ },
306
+ buildAvgAccessTimeTrace(avgAccessTime) {
307
+ /*
308
+ This function builds the line trace of the average access time of the whole data.
309
+ The trace is an horizontal line at y=average access time.
310
+ Arguments:
311
+ - avgAccessTime: average access time of the whole data
312
+ Returns a line trace
313
+ */
314
+
315
+ // set start and end dates so that the line spands the whole plot
316
+ const firstDate = new Date(this.dataItems[0].date);
317
+ if (this.week) {
318
+ firstDate.setDate(firstDate.getDate() - 0.1); // one day before the first date in data
319
+ } else {
320
+ firstDate.setDate(firstDate.getDate() - 1); // one month before the first date in data
321
+ }
322
+
323
+ const lastDate = new Date(this.dataItems[this.dataItems.length - 1].date);
324
+ if (this.week) {
325
+ lastDate.setDate(lastDate.getDate() + 0.3);
326
+ } else {
327
+ lastDate.setDate(lastDate.getDate() + 1); // one month after the last date in data
328
+ }
329
+
330
+ const trace = {
331
+ x: [firstDate, lastDate],
332
+ y: [avgAccessTime, avgAccessTime],
333
+ name: 'Average access time',
334
+ showlegend: true,
335
+ mode: 'lines',
336
+ type: 'scatter',
337
+ line: {
338
+ color: `rgba(${this.colorOnline},.6)`,
339
+ width: 1.5,
340
+ dash: '4px'
341
+ },
342
+ marker: {
343
+ size: 5
344
+ },
345
+ // avg access time with 2 decimals
346
+ hovertemplate: '<b>Average access time</b><br>%{y:.2f} ms <extra></extra>'
347
+ };
348
+ return trace;
349
+ },
350
+ buildOnlineTraces(data) {
351
+ /*
352
+ This function builds one trace per subarray of access_time between null values.
353
+ It also builds the trace of the average access time of the whole data.
354
+ [i] Why not just one trace for access_time?
355
+ [i] Because if we do that, the area under null values is filled too.
356
+ Arguments:
357
+ - data: array of objects with keys "access_time" and "date". access_time can be null
358
+ Returns an array of traces
359
+ */
360
+
361
+ const subarrays = this.extractSubarraysBetweenNullValues(data);
362
+ var traces = this.buildAccessTimeTraces(subarrays);
363
+ traces.push(this.buildAvgAccessTimeTrace(subarrays.average_access_time));
364
+ return traces;
365
+ },
366
+ extractOfflineNADates(data) {
367
+ const resultNA = [];
368
+ const resultOffline = [];
369
+ for (let i = 0; i < data.length; i++) {
370
+ // if the access_time is null and the code is null, it means that the monitoring was down
371
+ if (data[i].access_time === null && data[i].code === null) {
372
+ resultNA.push(data[i].date);
373
+ // if the access_time is null and the code is in errorCodes, it means that the server is offline
374
+ } else if (data[i].access_time === null) {
375
+ resultOffline.push(data[i].date);
376
+ }
377
+ }
378
+ return {
379
+ NA: resultNA,
380
+ down: resultOffline
381
+ };
382
+ },
383
+ barTrace(data, name, showlegend, hoverinfo, hovertemplate, group) {
384
+ /*
385
+ This function builds a bar trace.
386
+ Arguments:
387
+ - data: object with keys "dates" and "access_times"
388
+ - dates: array of dates
389
+ - access_times: array of access_times
390
+ - colors: array of colors in rgba format (eg:"rgba(255, 153, 145,0.8)")
391
+ - name: name of the trace
392
+ */
393
+ const trace = {
394
+ x: data.dates,
395
+ y: data.access_times,
396
+ marker: {
397
+ color: data.colors
398
+ },
399
+ name: name,
400
+ type: "bar",
401
+ legendgroup: group,
402
+ showlegend: showlegend,
403
+ hoverinfo: hoverinfo,
404
+ hovertemplate: hovertemplate,
405
+ width: 1000 * 3600 * 24 * 1 // 100% of the space between two dates
406
+ };
407
+
408
+ console.log(trace);
409
+ return trace;
410
+ },
411
+ buildBarTraces(dates, color, label, group) {
412
+ /*
413
+ This function builds the series used to display the offline/NA bars.
414
+ For each date, two columns are created: one very short and one tall.
415
+ These columns cover the whole plot height.
416
+ The tall column is colored with colorStrong and the short one with colorLight.
417
+ Arguments:
418
+ - dates: array of dates
419
+ - color: color of the bars
420
+ Returns array with offline and NA traces
421
+ */
422
+
423
+ const colorStrong = `rgba(${color},.8)`;
424
+ const colorLight = `rgba(${color},.2)`;
425
+ const dataShort = {
426
+ dates: dates,
427
+ access_times: Array(dates.length).fill(2),
428
+ colors: Array(dates.length).fill(colorStrong)
429
+ };
430
+ const dataTall = {
431
+ dates: dates,
432
+ access_times: Array(dates.length).fill(this.max_access_time * 1.1),
433
+ colors: Array(dates.length).fill(colorLight)
434
+ };
435
+ const hovertemplate = `<b>${label}</b><br>%{x|%d %b %Y}<br>%{y} ms <extra></extra>`;
436
+ const traceShort = this.barTrace(dataShort, label, false, 'skip', '', group);
437
+ const traceTall = this.barTrace(dataTall, label, true, 'all', hovertemplate, group);
438
+ return [traceShort, traceTall];
439
+ },
440
+ buildOfflineNATraces(data) {
441
+ /*
442
+ This function builds the bar traces of offline and NA values.
443
+ Arguments:
444
+ - data: array of objects with keys "access_time", "date" and "code". access_time and code can be null
445
+
446
+ Returns an array of bar traces
447
+ */
448
+
449
+ var traces = [];
450
+ const arrays = this.extractOfflineNADates(data);
451
+
452
+ // Down arrays
453
+ if (arrays.down.length > 0) {
454
+ traces = traces.concat(this.buildBarTraces(arrays.down, this.colorOffline, 'Offline', 'down'));
455
+ console.log(arrays.down);
456
+ }
457
+ // NA arrays
458
+ if (arrays.NA.length > 0) {
459
+ traces = traces.concat(this.buildBarTraces(arrays.NA, this.colorNA, 'No information available', 'na'));
460
+ console.log(arrays.NA);
461
+ }
462
+ return traces;
463
+ },
464
+ xaxesTickFormat() {
465
+ /*
466
+ This function returns the tickformat of the x axis.
467
+ If the plot is used to show data of one week, it returns the day of the week and the day.
468
+ Otherwise, it returns the day and the month.
469
+ */
470
+
471
+ if (this.week) {
472
+ return "%A<br>%d %b";
473
+ } else {
474
+ return "%d %b";
475
+ }
476
+ },
477
+ xaxesTickAngle() {
478
+ /*
479
+ This function returns the tickangle of the x axis.
480
+ If the plot is used to show data of one week, it returns 0.
481
+ Otherwise, it returns 45.
482
+ */
483
+ if (this.week) {
484
+ return 0;
485
+ } else {
486
+ return 45;
487
+ }
488
+ }
489
+ }
490
+ };function normalizeComponent(template, style, script, scopeId, isFunctionalTemplate, moduleIdentifier
491
+ /* server only */
492
+ , shadowMode, createInjector, createInjectorSSR, createInjectorShadow) {
493
+ if (typeof shadowMode !== 'boolean') {
494
+ createInjectorSSR = createInjector;
495
+ createInjector = shadowMode;
496
+ shadowMode = false;
497
+ } // Vue.extend constructor export interop.
498
+
499
+
500
+ var options = typeof script === 'function' ? script.options : script; // render functions
501
+
502
+ if (template && template.render) {
503
+ options.render = template.render;
504
+ options.staticRenderFns = template.staticRenderFns;
505
+ options._compiled = true; // functional template
506
+
507
+ if (isFunctionalTemplate) {
508
+ options.functional = true;
509
+ }
510
+ } // scopedId
511
+
512
+
513
+ if (scopeId) {
514
+ options._scopeId = scopeId;
515
+ }
516
+
517
+ var hook;
518
+
519
+ if (moduleIdentifier) {
520
+ // server build
521
+ hook = function hook(context) {
522
+ // 2.3 injection
523
+ context = context || // cached call
524
+ this.$vnode && this.$vnode.ssrContext || // stateful
525
+ this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext; // functional
526
+ // 2.2 with runInNewContext: true
527
+
528
+ if (!context && typeof __VUE_SSR_CONTEXT__ !== 'undefined') {
529
+ context = __VUE_SSR_CONTEXT__;
530
+ } // inject component styles
531
+
532
+
533
+ if (style) {
534
+ style.call(this, createInjectorSSR(context));
535
+ } // register component module identifier for async chunk inference
536
+
537
+
538
+ if (context && context._registeredComponents) {
539
+ context._registeredComponents.add(moduleIdentifier);
540
+ }
541
+ }; // used by ssr in case component is cached and beforeCreate
542
+ // never gets called
543
+
544
+
545
+ options._ssrRegister = hook;
546
+ } else if (style) {
547
+ hook = shadowMode ? function () {
548
+ style.call(this, createInjectorShadow(this.$root.$options.shadowRoot));
549
+ } : function (context) {
550
+ style.call(this, createInjector(context));
551
+ };
552
+ }
553
+
554
+ if (hook) {
555
+ if (options.functional) {
556
+ // register for functional component in vue file
557
+ var originalRender = options.render;
558
+
559
+ options.render = function renderWithStyleInjection(h, context) {
560
+ hook.call(context);
561
+ return originalRender(h, context);
562
+ };
563
+ } else {
564
+ // inject component registration as beforeCreate hook
565
+ var existing = options.beforeCreate;
566
+ options.beforeCreate = existing ? [].concat(existing, hook) : [hook];
567
+ }
568
+ }
569
+
570
+ return script;
571
+ }
572
+
573
+ var normalizeComponent_1 = normalizeComponent;/* script */
574
+ const __vue_script__$1 = script$1;
575
+
576
+ /* template */
577
+ var __vue_render__$1 = function () {
578
+ var _vm = this;
579
+ var _h = _vm.$createElement;
580
+ var _c = _vm._self._c || _h;
581
+ return _c('div', {
582
+ attrs: {
583
+ "id": _vm.divId
584
+ }
585
+ }, []);
586
+ };
587
+ var __vue_staticRenderFns__$1 = [];
588
+
589
+ /* style */
590
+ const __vue_inject_styles__$1 = undefined;
591
+ /* scoped */
592
+ const __vue_scope_id__$1 = undefined;
593
+ /* module identifier */
594
+ const __vue_module_identifier__$1 = "data-v-5ead469f";
595
+ /* functional template */
596
+ const __vue_is_functional_template__$1 = false;
597
+ /* style inject */
598
+
599
+ /* style inject SSR */
600
+
601
+ var accessibilityPlot = normalizeComponent_1({
602
+ render: __vue_render__$1,
603
+ staticRenderFns: __vue_staticRenderFns__$1
604
+ }, __vue_inject_styles__$1, __vue_script__$1, __vue_scope_id__$1, __vue_is_functional_template__$1, __vue_module_identifier__$1, undefined, undefined);//
605
+ var script = {
606
+ name: 'citationsPlot',
607
+ data: () => ({
608
+ divId: randstr('cit_plot')
609
+ }),
610
+ props: {
611
+ dataTraces: {
612
+ /*
613
+ dataTraces is and array of data to be plotted. Each element of the array is an object with the following structure:
614
+ TODO: apply vue-types to define the prop
615
+ https://github.com/dwightjack/vue-types
616
+ {
617
+ data: array, // required
618
+ id: string, // required
619
+ label: string, // optional
620
+ title: string, // optional
621
+ year: number, // optional
622
+ url: string // optional
623
+ }
624
+ */
625
+ type: Array,
626
+ required: true
627
+ },
628
+ stack: {
629
+ type: Boolean,
630
+ required: false,
631
+ default: false
632
+ },
633
+ colors: {
634
+ type: Array,
635
+ required: false,
636
+ default: () => ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd']
637
+ },
638
+ height: {
639
+ type: Number,
640
+ required: false,
641
+ default: 400
642
+ },
643
+ showlegend: {
644
+ type: Boolean,
645
+ required: false,
646
+ default: true
647
+ },
648
+ title: {
649
+ type: String,
650
+ required: false,
651
+ default: ''
652
+ },
653
+ xaxisTitle: {
654
+ type: String,
655
+ required: false,
656
+ default: 'Year'
657
+ },
658
+ yaxisTitle: {
659
+ type: String,
660
+ required: false,
661
+ default: 'Number of citations'
662
+ },
663
+ darkMode: {
664
+ type: Boolean,
665
+ required: false,
666
+ default: false
667
+ }
668
+ },
669
+ mounted() {
670
+ const traces = this.buildTraces();
671
+ const layout = {
672
+ showlegend: this.showlegend,
673
+ autosize: true,
674
+ height: this.height,
675
+ margin: {
676
+ l: 50,
677
+ r: 50,
678
+ b: 70,
679
+ t: 50,
680
+ pad: 4
681
+ },
682
+ xaxis: {
683
+ title: this.xaxisTitle,
684
+ font: {
685
+ size: 10
686
+ },
687
+ tickfont: {
688
+ size: 10
689
+ },
690
+ tickmode: 'linear',
691
+ color: this.darkMode ? 'white' : 'black'
692
+ },
693
+ yaxis: {
694
+ title: this.yaxisTitle,
695
+ titlefont: {
696
+ size: 10
697
+ },
698
+ tickfont: {
699
+ size: 10
700
+ },
701
+ font: {
702
+ size: 10
703
+ },
704
+ color: this.darkMode ? 'white' : 'black'
705
+ },
706
+ legend: {
707
+ orientation: 'h',
708
+ yanchor: 'bottom',
709
+ y: 1.02,
710
+ xanchor: 'right',
711
+ x: 1,
712
+ font: {
713
+ size: 8,
714
+ color: this.darkMode ? 'white' : 'black'
715
+ }
716
+ },
717
+ hoverlabel: {
718
+ color: this.darkMode ? 'white' : 'black'
719
+ },
720
+ hovermode: this.stack ? 'x unified' : 'closest',
721
+ hoverdistance: 70,
722
+ plot_bgcolor: this.darkMode ? "rgb(38, 50, 56)" : "white",
723
+ paper_bgcolor: this.darkMode ? "rgb(38, 50, 56)" : "white"
724
+ };
725
+ Plotly__default["default"].newPlot(this.divId, traces, layout);
726
+ },
727
+ methods: {
728
+ buildTraces() {
729
+ const traces = [];
730
+ // build traces for object in dataTraces
731
+ for (let i = 0; i < this.dataTraces.length; i++) {
732
+ const trace = {
733
+ x: this.dataTraces[i].data.map(d => d.year),
734
+ y: this.dataTraces[i].data.map(d => d.citations),
735
+ mode: 'lines+markers',
736
+ name: this.dataTraces[i].label,
737
+ hovertemplate: this.hoverTemplate(),
738
+ marker: {
739
+ size: 5
740
+ },
741
+ line: {
742
+ color: this.colors[i],
743
+ width: 1.8
744
+ },
745
+ stackgroup: this.stack ? 'one' : null
746
+ };
747
+ traces.push(trace);
748
+ }
749
+ return traces;
750
+ },
751
+ hoverTemplate() {
752
+ if (this.stack) {
753
+ return "%{y} citations <extra></extra>";
754
+ } else {
755
+ return "%{y} citations in %{x} <extra></extra>";
756
+ }
757
+ }
758
+ }
759
+ };/* script */
760
+ const __vue_script__ = script;
761
+
762
+ /* template */
763
+ var __vue_render__ = function () {
764
+ var _vm = this;
765
+ var _h = _vm.$createElement;
766
+ var _c = _vm._self._c || _h;
767
+ return _c('div', {
768
+ attrs: {
769
+ "id": _vm.divId
770
+ }
771
+ }, []);
772
+ };
773
+ var __vue_staticRenderFns__ = [];
774
+
775
+ /* style */
776
+ const __vue_inject_styles__ = undefined;
777
+ /* scoped */
778
+ const __vue_scope_id__ = undefined;
779
+ /* module identifier */
780
+ const __vue_module_identifier__ = "data-v-64c53c55";
781
+ /* functional template */
782
+ const __vue_is_functional_template__ = false;
783
+ /* style inject */
784
+
785
+ /* style inject SSR */
786
+
787
+ var citationsPlot = normalizeComponent_1({
788
+ render: __vue_render__,
789
+ staticRenderFns: __vue_staticRenderFns__
790
+ }, __vue_inject_styles__, __vue_script__, __vue_scope_id__, __vue_is_functional_template__, __vue_module_identifier__, undefined, undefined);var components=/*#__PURE__*/Object.freeze({__proto__:null,accessibilityPlot:accessibilityPlot,citationsPlot:citationsPlot});// install function executed by Vue.use()
791
+ const install = function installVueOEBViz(Vue) {
792
+ if (install.installed) return;
793
+ install.installed = true;
794
+ Object.entries(components).forEach(([componentName, component]) => {
795
+ Vue.component(componentName, component);
796
+ });
797
+ };
798
+
799
+ // Create module definition for Vue.use()
800
+ const plugin = {
801
+ install
802
+ };
803
+
804
+ // To auto-install on non-es builds, when vue is found
805
+ // eslint-disable-next-line no-redeclare
806
+ /* global window, global */
807
+ {
808
+ let GlobalVue = null;
809
+ if (typeof window !== 'undefined') {
810
+ GlobalVue = window.Vue;
811
+ } else if (typeof global !== 'undefined') {
812
+ GlobalVue = global.Vue;
813
+ }
814
+ if (GlobalVue) {
815
+ GlobalVue.use(plugin);
816
+ }
817
+ }
818
+
819
+ /*
820
+ if (typeof Vue !== 'undefined') {
821
+ for (const name in components) {
822
+ Vue.component(name, components[name])
823
+ }
824
+ }
825
+ */exports.accessibilityPlot=accessibilityPlot;exports.citationsPlot=citationsPlot;exports["default"]=plugin;