@inb/oeb_visualizations 0.0.6 → 0.0.8-beta
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/README.md +7 -206
- package/dist/oeb-visualizations.cjs.js +134 -39
- package/dist/oeb-visualizations.esm.js +132 -37
- package/dist/oeb-visualizations.min.js +1 -1
- package/dist/oeb-visualizations.umd.js +134 -39
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
# OpenEBench Visualizations
|
|
2
2
|
|
|
3
|
-
Collection of Vue components for data visualization in OpenEBench.
|
|
3
|
+
Collection of Vue components for data visualization in [OpenEBench](https://openebench.bsc.es/).
|
|
4
4
|
|
|
5
|
-
- Go to the [demo](https://inab.github.io/oeb-visualizations-demo/) to see the components in action.
|
|
6
|
-
-
|
|
5
|
+
- :magic_wand: Go to the [live demo](https://inab.github.io/oeb-visualizations-demo/) to see the components in action.
|
|
6
|
+
- :open_book: Check the [documentation](https://inab.github.io/oeb-visualizations/) for details on how to use the components.
|
|
7
|
+
- :package: This package is available through [npmjs](https://www.npmjs.com/package/@inb/oeb_visualizations).
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
## Installation
|
|
@@ -11,209 +12,9 @@ Collection of Vue components for data visualization in OpenEBench.
|
|
|
11
12
|
To install the package run:
|
|
12
13
|
|
|
13
14
|
```bash
|
|
14
|
-
npm install @inb/
|
|
15
|
+
npm install @inb/oeb_visualizations
|
|
15
16
|
```
|
|
16
17
|
|
|
17
|
-
##
|
|
18
|
+
## Development
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
#### Data
|
|
23
|
-
|
|
24
|
-
Data is provided to the component as an array of objects through the `dataItems` prop. Each object represents an access to the server. The object must have the following keys: `access_time`, `date` and `code`.
|
|
25
|
-
- `access_time`: time it took to access the server in ms.
|
|
26
|
-
- `date`: date of the access. Should not be null.
|
|
27
|
-
- `code`: HTTP code returned by the server. If `null` the bar will be colored with the color specified in the `colorNA` prop. If the code is an error code the bar will be colored with the color specified in the `colorOffline` prop. If the code is 200 the bar will be colored with the color specified in the `colorOnline` prop.
|
|
28
|
-
|
|
29
|
-
Example:
|
|
30
|
-
|
|
31
|
-
```json
|
|
32
|
-
[
|
|
33
|
-
{
|
|
34
|
-
"date": "2022-10-23T07:54:06.716122Z",
|
|
35
|
-
"code": 200,
|
|
36
|
-
"access_time": 51
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
"date": "2022-10-24T07:58:50.609475Z",
|
|
40
|
-
"code": 200,
|
|
41
|
-
"access_time": 67
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
"date": "2022-10-25T07:51:53.841140Z",
|
|
45
|
-
"code": 200,
|
|
46
|
-
"access_time": 55
|
|
47
|
-
}
|
|
48
|
-
]
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
#### Props
|
|
52
|
-
|
|
53
|
-
| Name | Type | Description | Default | Required |
|
|
54
|
-
| --- | --- | --- | --- | --- |
|
|
55
|
-
|dataItems | Array | Array of objects with keys `access_time`, `date` and `code`. <br> More details in "Data" section | | true |
|
|
56
|
-
| height | Number | Height of the plot in pixels. | 400 | false |
|
|
57
|
-
| colorNA | String | Color of bars for which there is no monitoring information (`code`=`null`). RGB format: `"<R>, <G>, <B>"` | 204, 204, 204 | false |
|
|
58
|
-
| colorOffline | String | Color of bars for which the server was offline (`code` is an error code). RGB format: `"<R>, <G>, <B>"` | 255, 153, 145 | false |
|
|
59
|
-
| colorOnline | String | Color of bars for which the server was online (`code` is 200). RGB format: `"<R>, <G>, <B>"` | 111, 176, 129 | false |
|
|
60
|
-
| yaxisTitle | String | Title of the y axis. | Access time (ms) | false |
|
|
61
|
-
| xaxisTitle | String | Title of the x axis. | Date | false |
|
|
62
|
-
| dtick | String | Tick interval for the x axis in unix epoch. | 86400000 | false |
|
|
63
|
-
|
|
64
|
-
#### Usage
|
|
65
|
-
|
|
66
|
-
Import the `accessibilityPlot` in your Vue component and add it to the `components` section. Then use the component in the template.
|
|
67
|
-
|
|
68
|
-
```html
|
|
69
|
-
<template>
|
|
70
|
-
<div>
|
|
71
|
-
<accessibilityPlot :dataItems="data" />
|
|
72
|
-
</div>
|
|
73
|
-
</template>
|
|
74
|
-
|
|
75
|
-
<script>
|
|
76
|
-
import { accessibilityPlot } from '@inb/oeb_visualizations'
|
|
77
|
-
|
|
78
|
-
export default {
|
|
79
|
-
components: {
|
|
80
|
-
accessibilityPlot
|
|
81
|
-
},
|
|
82
|
-
data(){
|
|
83
|
-
return {
|
|
84
|
-
data: [
|
|
85
|
-
{
|
|
86
|
-
"date": "2022-10-23T07:54:06.716122Z",
|
|
87
|
-
"code": 200,
|
|
88
|
-
"access_time": 51
|
|
89
|
-
},
|
|
90
|
-
{
|
|
91
|
-
"date": "2022-10-24T07:58:50.609475Z",
|
|
92
|
-
"code": 200,
|
|
93
|
-
"access_time": 67
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
"date": "2022-10-25T07:51:53.841140Z",
|
|
97
|
-
"code": 200,
|
|
98
|
-
"access_time": 55
|
|
99
|
-
}
|
|
100
|
-
]
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
</script>
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
### citationsPlot
|
|
108
|
-
|
|
109
|
-
#### Data
|
|
110
|
-
|
|
111
|
-
Data is provided to the component as an array of objects through the `dataTraces` prop. Each object corresponds to a publication and will be represented as a trace in the resulting plot. They have the following keys: `data`, `id`, `label`, `title`, `year` and `url`.
|
|
112
|
-
- `data`: array of objects. Each object has the following keys: `count` and `year`. `count` is the number of citations of the publication in the year `year`. Exmple
|
|
113
|
-
```
|
|
114
|
-
[
|
|
115
|
-
{
|
|
116
|
-
"count": 1,
|
|
117
|
-
"year": 2019
|
|
118
|
-
},
|
|
119
|
-
{
|
|
120
|
-
"count": 1,
|
|
121
|
-
"year": 2020
|
|
122
|
-
},
|
|
123
|
-
{
|
|
124
|
-
"count": 1,
|
|
125
|
-
"year": 2021
|
|
126
|
-
}
|
|
127
|
-
]
|
|
128
|
-
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
- `id`: string. Identifier of the publication.
|
|
132
|
-
- `label`: string. Label of the publication.
|
|
133
|
-
- `title`: string. Title of the publication.
|
|
134
|
-
- `year`: number. Year of the publication.
|
|
135
|
-
- `url`: string. URL of the publication.
|
|
136
|
-
|
|
137
|
-
#### Props
|
|
138
|
-
|
|
139
|
-
| Name | Type | Description | Default | Required |
|
|
140
|
-
| --- | --- | --- | --- | --- |
|
|
141
|
-
|dataTraces | Array | Array of objects with keys `data`, `id`, `label`, `title`, `year` and `url`. <br> More details in "Data" section | | true |
|
|
142
|
-
| stack | Boolean | If true, the traces will be stacked. | false | false |
|
|
143
|
-
| colors | Array | Array of colors for the traces. HEX format | | false |
|
|
144
|
-
| height | Number | Height of the plot in pixels. | 400 | false |
|
|
145
|
-
| showlegend | Boolean | If true, the legend will be shown. | true | false |
|
|
146
|
-
| title | String | Title of the plot. | | false |
|
|
147
|
-
| xaxisTitle | String | Title of the x axis. | Year | false |
|
|
148
|
-
| yaxisTitle | String | Title of the y axis. | Number of citations | false |
|
|
149
|
-
| dark | Boolean | If true, the plot will be displayed in dark mode. | false | false |
|
|
150
|
-
|
|
151
|
-
#### Usage
|
|
152
|
-
|
|
153
|
-
Import the `citationsPlot` in your Vue component and add it to the `components` section. Then use the component in the template.
|
|
154
|
-
|
|
155
|
-
```html
|
|
156
|
-
<template>
|
|
157
|
-
<div>
|
|
158
|
-
<citationsPlot :dataTraces="data" />
|
|
159
|
-
</div>
|
|
160
|
-
</template>
|
|
161
|
-
<script>
|
|
162
|
-
import citationsPlotPage from '../components/citationsPlotPage.vue'
|
|
163
|
-
|
|
164
|
-
export default {
|
|
165
|
-
name: 'IndexPage',
|
|
166
|
-
components: {
|
|
167
|
-
citationsPlotPage
|
|
168
|
-
},
|
|
169
|
-
data(){
|
|
170
|
-
return {
|
|
171
|
-
data: [
|
|
172
|
-
{
|
|
173
|
-
"data": [
|
|
174
|
-
{
|
|
175
|
-
"count": 1,
|
|
176
|
-
"year": 2019
|
|
177
|
-
},
|
|
178
|
-
{
|
|
179
|
-
"count": 1,
|
|
180
|
-
"year": 2020
|
|
181
|
-
},
|
|
182
|
-
{
|
|
183
|
-
"count": 1,
|
|
184
|
-
"year": 2021
|
|
185
|
-
}
|
|
186
|
-
],
|
|
187
|
-
"id": "paper1",
|
|
188
|
-
"label": "OEB paper",
|
|
189
|
-
"title": "OpenEBench: a web platform for transparent and reproducible biomedical benchmarking",
|
|
190
|
-
"year": 2020,
|
|
191
|
-
"url": ""
|
|
192
|
-
},
|
|
193
|
-
{
|
|
194
|
-
"data": [
|
|
195
|
-
{
|
|
196
|
-
"count": 1,
|
|
197
|
-
"year": 2019
|
|
198
|
-
},
|
|
199
|
-
{
|
|
200
|
-
"count": 1,
|
|
201
|
-
"year": 2020
|
|
202
|
-
},
|
|
203
|
-
{
|
|
204
|
-
"count": 1,
|
|
205
|
-
"year": 2021
|
|
206
|
-
}
|
|
207
|
-
],
|
|
208
|
-
"id": "paper2",
|
|
209
|
-
"label": "OEB paper 2",
|
|
210
|
-
"title": "OpenEBench 2: an update of the web platform for transparent and reproducible biomedical benchmarking",
|
|
211
|
-
"year": 2020,
|
|
212
|
-
"url": ""
|
|
213
|
-
}
|
|
214
|
-
]
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
</script>
|
|
219
|
-
```
|
|
20
|
+
🚧 Work in progress 🚧
|
|
@@ -4,7 +4,13 @@
|
|
|
4
4
|
var script$1 = {
|
|
5
5
|
name: 'accessibilityPlot',
|
|
6
6
|
data: () => ({
|
|
7
|
-
divId: randstr('
|
|
7
|
+
divId: randstr('acc_plot_'),
|
|
8
|
+
max_access_time: 0,
|
|
9
|
+
config: {
|
|
10
|
+
displaylogo: false,
|
|
11
|
+
responsive: true,
|
|
12
|
+
modeBarButtonsToRemove: ['lasso']
|
|
13
|
+
}
|
|
8
14
|
}),
|
|
9
15
|
props: {
|
|
10
16
|
dtick: {
|
|
@@ -66,6 +72,24 @@ var script$1 = {
|
|
|
66
72
|
required: false,
|
|
67
73
|
default: 350
|
|
68
74
|
},
|
|
75
|
+
week: {
|
|
76
|
+
/*
|
|
77
|
+
whether the plot is used to show data of one week
|
|
78
|
+
If true, days of the week are shown on the x axis
|
|
79
|
+
*/
|
|
80
|
+
type: Boolean,
|
|
81
|
+
required: false,
|
|
82
|
+
default: false
|
|
83
|
+
},
|
|
84
|
+
sixMonths: {
|
|
85
|
+
/*
|
|
86
|
+
whether the plot is used to show data of six months
|
|
87
|
+
If true, months are shown on the x axis
|
|
88
|
+
*/
|
|
89
|
+
type: Boolean,
|
|
90
|
+
required: false,
|
|
91
|
+
default: false
|
|
92
|
+
},
|
|
69
93
|
dataItems: {
|
|
70
94
|
/*
|
|
71
95
|
dataItems is an array of objects with keys "access_time", "date" and "code".
|
|
@@ -114,6 +138,7 @@ var script$1 = {
|
|
|
114
138
|
}
|
|
115
139
|
},
|
|
116
140
|
mounted() {
|
|
141
|
+
this.max_access_time = Math.max(...this.dataItems.map(item => item.access_time));
|
|
117
142
|
var traces = this.buildOnlineTraces(this.dataItems); // generate line traces
|
|
118
143
|
|
|
119
144
|
traces = traces.concat(this.buildOfflineNATraces(this.dataItems)); // generate bar traces
|
|
@@ -127,12 +152,13 @@ var script$1 = {
|
|
|
127
152
|
margin: {
|
|
128
153
|
l: 50,
|
|
129
154
|
r: 50,
|
|
130
|
-
b:
|
|
131
|
-
t:
|
|
155
|
+
b: 50,
|
|
156
|
+
t: 20,
|
|
132
157
|
pad: 4
|
|
133
158
|
},
|
|
134
159
|
xaxis: {
|
|
135
160
|
type: 'date',
|
|
161
|
+
ticklabelmode: this.xaxisMode(),
|
|
136
162
|
title: this.xaxisTitle,
|
|
137
163
|
font: {
|
|
138
164
|
size: 10
|
|
@@ -140,11 +166,17 @@ var script$1 = {
|
|
|
140
166
|
tickfont: {
|
|
141
167
|
size: 10
|
|
142
168
|
},
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
169
|
+
showgrid: this.sixMonths ? true : false,
|
|
170
|
+
griddash: "dot",
|
|
171
|
+
gridwidth: 1,
|
|
172
|
+
gridcolor: "#d9d7d7",
|
|
173
|
+
showspikes: true,
|
|
174
|
+
spikedash: "4px",
|
|
175
|
+
spikethickness: 1,
|
|
176
|
+
tick0: this.xaxisTickZero(),
|
|
177
|
+
dtick: this.xaxisTickD(),
|
|
178
|
+
tickangle: this.xaxisTickAngle(),
|
|
179
|
+
tickformat: this.xaxisTickFormat()
|
|
148
180
|
},
|
|
149
181
|
yaxis: {
|
|
150
182
|
title: this.yaxisTitle,
|
|
@@ -159,9 +191,9 @@ var script$1 = {
|
|
|
159
191
|
legend: {
|
|
160
192
|
orientation: 'h',
|
|
161
193
|
yanchor: 'bottom',
|
|
162
|
-
y:
|
|
163
|
-
xanchor: '
|
|
164
|
-
x:
|
|
194
|
+
y: -0.5,
|
|
195
|
+
xanchor: 'left',
|
|
196
|
+
x: 0.05,
|
|
165
197
|
font: {
|
|
166
198
|
size: 8
|
|
167
199
|
}
|
|
@@ -171,7 +203,8 @@ var script$1 = {
|
|
|
171
203
|
},
|
|
172
204
|
hovermode: 'closest'
|
|
173
205
|
};
|
|
174
|
-
|
|
206
|
+
console.log(this.divId);
|
|
207
|
+
Plotly__default["default"].newPlot(this.divId, traces, layout, this.config);
|
|
175
208
|
},
|
|
176
209
|
methods: {
|
|
177
210
|
generateColor(values, transparency) {
|
|
@@ -298,10 +331,18 @@ var script$1 = {
|
|
|
298
331
|
|
|
299
332
|
// set start and end dates so that the line spands the whole plot
|
|
300
333
|
const firstDate = new Date(this.dataItems[0].date);
|
|
301
|
-
|
|
334
|
+
if (this.week) {
|
|
335
|
+
firstDate.setDate(firstDate.getDate() - 0.3); // one day before the first date in data
|
|
336
|
+
} else {
|
|
337
|
+
firstDate.setDate(firstDate.getDate() - 1); // one month before the first date in data
|
|
338
|
+
}
|
|
302
339
|
|
|
303
340
|
const lastDate = new Date(this.dataItems[this.dataItems.length - 1].date);
|
|
304
|
-
|
|
341
|
+
if (this.week) {
|
|
342
|
+
lastDate.setDate(lastDate.getDate() + 0.3);
|
|
343
|
+
} else {
|
|
344
|
+
lastDate.setDate(lastDate.getDate() + 1); // one month after the last date in data
|
|
345
|
+
}
|
|
305
346
|
|
|
306
347
|
const trace = {
|
|
307
348
|
x: [firstDate, lastDate],
|
|
@@ -340,17 +381,6 @@ var script$1 = {
|
|
|
340
381
|
return traces;
|
|
341
382
|
},
|
|
342
383
|
extractOfflineNADates(data) {
|
|
343
|
-
/*
|
|
344
|
-
This function extracts dates with access_time null.
|
|
345
|
-
Depending on the code, the server is offline or NA on those dates.
|
|
346
|
-
Arguments:
|
|
347
|
-
- data: array of objects with keys "access_time", "date" and "code". access_time and code can be null
|
|
348
|
-
|
|
349
|
-
Returns an object with keys:
|
|
350
|
-
- NA: array of dates with access_time null and code null
|
|
351
|
-
- down: array of dates with access_time null and code in errorCodes
|
|
352
|
-
*/
|
|
353
|
-
const errorCodes = [404, 500, 502, 503, 504];
|
|
354
384
|
const resultNA = [];
|
|
355
385
|
const resultOffline = [];
|
|
356
386
|
for (let i = 0; i < data.length; i++) {
|
|
@@ -358,7 +388,7 @@ var script$1 = {
|
|
|
358
388
|
if (data[i].access_time === null && data[i].code === null) {
|
|
359
389
|
resultNA.push(data[i].date);
|
|
360
390
|
// if the access_time is null and the code is in errorCodes, it means that the server is offline
|
|
361
|
-
} else if (data[i].access_time === null
|
|
391
|
+
} else if (data[i].access_time === null) {
|
|
362
392
|
resultOffline.push(data[i].date);
|
|
363
393
|
}
|
|
364
394
|
}
|
|
@@ -367,7 +397,7 @@ var script$1 = {
|
|
|
367
397
|
down: resultOffline
|
|
368
398
|
};
|
|
369
399
|
},
|
|
370
|
-
barTrace(data, name, showlegend, hoverinfo, hovertemplate) {
|
|
400
|
+
barTrace(data, name, showlegend, hoverinfo, hovertemplate, group) {
|
|
371
401
|
/*
|
|
372
402
|
This function builds a bar trace.
|
|
373
403
|
Arguments:
|
|
@@ -385,14 +415,17 @@ var script$1 = {
|
|
|
385
415
|
},
|
|
386
416
|
name: name,
|
|
387
417
|
type: "bar",
|
|
388
|
-
legendgroup:
|
|
418
|
+
legendgroup: group,
|
|
389
419
|
showlegend: showlegend,
|
|
390
420
|
hoverinfo: hoverinfo,
|
|
391
|
-
hovertemplate: hovertemplate
|
|
421
|
+
hovertemplate: hovertemplate,
|
|
422
|
+
width: 1000 * 3600 * 24 * 1 // 100% of the space between two dates
|
|
392
423
|
};
|
|
424
|
+
|
|
425
|
+
console.log(trace);
|
|
393
426
|
return trace;
|
|
394
427
|
},
|
|
395
|
-
buildBarTraces(dates, color, label) {
|
|
428
|
+
buildBarTraces(dates, color, label, group) {
|
|
396
429
|
/*
|
|
397
430
|
This function builds the series used to display the offline/NA bars.
|
|
398
431
|
For each date, two columns are created: one very short and one tall.
|
|
@@ -413,12 +446,12 @@ var script$1 = {
|
|
|
413
446
|
};
|
|
414
447
|
const dataTall = {
|
|
415
448
|
dates: dates,
|
|
416
|
-
access_times: Array(dates.length).fill(
|
|
449
|
+
access_times: Array(dates.length).fill(this.max_access_time * 1.1),
|
|
417
450
|
colors: Array(dates.length).fill(colorLight)
|
|
418
451
|
};
|
|
419
452
|
const hovertemplate = `<b>${label}</b><br>%{x|%d %b %Y}<br>%{y} ms <extra></extra>`;
|
|
420
|
-
const traceShort = this.barTrace(dataShort, label, false, 'skip', '');
|
|
421
|
-
const traceTall = this.barTrace(dataTall, label, true, 'all', hovertemplate);
|
|
453
|
+
const traceShort = this.barTrace(dataShort, label, false, 'skip', '', group);
|
|
454
|
+
const traceTall = this.barTrace(dataTall, label, true, 'all', hovertemplate, group);
|
|
422
455
|
return [traceShort, traceTall];
|
|
423
456
|
},
|
|
424
457
|
buildOfflineNATraces(data) {
|
|
@@ -434,11 +467,73 @@ var script$1 = {
|
|
|
434
467
|
const arrays = this.extractOfflineNADates(data);
|
|
435
468
|
|
|
436
469
|
// Down arrays
|
|
437
|
-
|
|
438
|
-
|
|
470
|
+
if (arrays.down.length > 0) {
|
|
471
|
+
traces = traces.concat(this.buildBarTraces(arrays.down, this.colorOffline, 'Offline', 'down'));
|
|
472
|
+
console.log(arrays.down);
|
|
473
|
+
}
|
|
439
474
|
// NA arrays
|
|
440
|
-
|
|
475
|
+
if (arrays.NA.length > 0) {
|
|
476
|
+
traces = traces.concat(this.buildBarTraces(arrays.NA, this.colorNA, 'No information available', 'na'));
|
|
477
|
+
console.log(arrays.NA);
|
|
478
|
+
}
|
|
441
479
|
return traces;
|
|
480
|
+
},
|
|
481
|
+
xaxisTickFormat() {
|
|
482
|
+
/*
|
|
483
|
+
This function returns the tickformat of the x axis.
|
|
484
|
+
If the plot is used to show data of one week, it returns the day of the week and the day.
|
|
485
|
+
Otherwise, it returns the day and the month.
|
|
486
|
+
*/
|
|
487
|
+
|
|
488
|
+
if (this.week) {
|
|
489
|
+
return "%A<br>%d %b";
|
|
490
|
+
}
|
|
491
|
+
if (this.sixMonths) {
|
|
492
|
+
return "%b";
|
|
493
|
+
} else {
|
|
494
|
+
return "%d %b";
|
|
495
|
+
}
|
|
496
|
+
},
|
|
497
|
+
xaxisTickAngle() {
|
|
498
|
+
/*
|
|
499
|
+
This function returns the tickangle of the x axis.
|
|
500
|
+
If the plot is used to show data of one week, it returns 0.
|
|
501
|
+
Otherwise, it returns 45.
|
|
502
|
+
*/
|
|
503
|
+
if (this.week) {
|
|
504
|
+
return 0;
|
|
505
|
+
}
|
|
506
|
+
if (this.sixMonths) {
|
|
507
|
+
return 0;
|
|
508
|
+
} else {
|
|
509
|
+
return 45;
|
|
510
|
+
}
|
|
511
|
+
},
|
|
512
|
+
xaxisTickD() {
|
|
513
|
+
if (this.sixMonths === true) {
|
|
514
|
+
return "M1";
|
|
515
|
+
} else {
|
|
516
|
+
return this.dtick;
|
|
517
|
+
}
|
|
518
|
+
},
|
|
519
|
+
xaxisTickZero() {
|
|
520
|
+
if (this.sixMonths === true) {
|
|
521
|
+
console.log('zero six months ago');
|
|
522
|
+
const lastDate = new Date(this.dataItems[this.dataItems.length - 1].date);
|
|
523
|
+
//return lastDate minus six months
|
|
524
|
+
console.log(lastDate);
|
|
525
|
+
console.log('six months ago: ' + new Date(lastDate.setMonth(lastDate.getMonth() - 6)));
|
|
526
|
+
return new Date(lastDate.setMonth(lastDate.getMonth() - 6));
|
|
527
|
+
} else {
|
|
528
|
+
return this.dataItems[0];
|
|
529
|
+
}
|
|
530
|
+
},
|
|
531
|
+
xaxisMode() {
|
|
532
|
+
if (this.sixMonths === true) {
|
|
533
|
+
return "period";
|
|
534
|
+
} else {
|
|
535
|
+
return "instant";
|
|
536
|
+
}
|
|
442
537
|
}
|
|
443
538
|
}
|
|
444
539
|
};function normalizeComponent(template, style, script, scopeId, isFunctionalTemplate, moduleIdentifier
|
|
@@ -545,7 +640,7 @@ const __vue_inject_styles__$1 = undefined;
|
|
|
545
640
|
/* scoped */
|
|
546
641
|
const __vue_scope_id__$1 = undefined;
|
|
547
642
|
/* module identifier */
|
|
548
|
-
const __vue_module_identifier__$1 = "data-v-
|
|
643
|
+
const __vue_module_identifier__$1 = "data-v-77c84891";
|
|
549
644
|
/* functional template */
|
|
550
645
|
const __vue_is_functional_template__$1 = false;
|
|
551
646
|
/* style inject */
|
|
@@ -559,7 +654,7 @@ var accessibilityPlot = normalizeComponent_1({
|
|
|
559
654
|
var script = {
|
|
560
655
|
name: 'citationsPlot',
|
|
561
656
|
data: () => ({
|
|
562
|
-
divId: randstr('
|
|
657
|
+
divId: randstr('cit_plot_')
|
|
563
658
|
}),
|
|
564
659
|
props: {
|
|
565
660
|
dataTraces: {
|
|
@@ -731,7 +826,7 @@ const __vue_inject_styles__ = undefined;
|
|
|
731
826
|
/* scoped */
|
|
732
827
|
const __vue_scope_id__ = undefined;
|
|
733
828
|
/* module identifier */
|
|
734
|
-
const __vue_module_identifier__ = "data-v-
|
|
829
|
+
const __vue_module_identifier__ = "data-v-4ac5e814";
|
|
735
830
|
/* functional template */
|
|
736
831
|
const __vue_is_functional_template__ = false;
|
|
737
832
|
/* style inject */
|
|
@@ -8,7 +8,13 @@ function randstr(prefix) {
|
|
|
8
8
|
var script$1 = {
|
|
9
9
|
name: 'accessibilityPlot',
|
|
10
10
|
data: () => ({
|
|
11
|
-
divId: randstr('
|
|
11
|
+
divId: randstr('acc_plot_'),
|
|
12
|
+
max_access_time: 0,
|
|
13
|
+
config: {
|
|
14
|
+
displaylogo: false,
|
|
15
|
+
responsive: true,
|
|
16
|
+
modeBarButtonsToRemove: ['lasso']
|
|
17
|
+
}
|
|
12
18
|
}),
|
|
13
19
|
props: {
|
|
14
20
|
dtick: {
|
|
@@ -70,6 +76,24 @@ var script$1 = {
|
|
|
70
76
|
required: false,
|
|
71
77
|
default: 350
|
|
72
78
|
},
|
|
79
|
+
week: {
|
|
80
|
+
/*
|
|
81
|
+
whether the plot is used to show data of one week
|
|
82
|
+
If true, days of the week are shown on the x axis
|
|
83
|
+
*/
|
|
84
|
+
type: Boolean,
|
|
85
|
+
required: false,
|
|
86
|
+
default: false
|
|
87
|
+
},
|
|
88
|
+
sixMonths: {
|
|
89
|
+
/*
|
|
90
|
+
whether the plot is used to show data of six months
|
|
91
|
+
If true, months are shown on the x axis
|
|
92
|
+
*/
|
|
93
|
+
type: Boolean,
|
|
94
|
+
required: false,
|
|
95
|
+
default: false
|
|
96
|
+
},
|
|
73
97
|
dataItems: {
|
|
74
98
|
/*
|
|
75
99
|
dataItems is an array of objects with keys "access_time", "date" and "code".
|
|
@@ -118,6 +142,7 @@ var script$1 = {
|
|
|
118
142
|
}
|
|
119
143
|
},
|
|
120
144
|
mounted() {
|
|
145
|
+
this.max_access_time = Math.max(...this.dataItems.map(item => item.access_time));
|
|
121
146
|
var traces = this.buildOnlineTraces(this.dataItems); // generate line traces
|
|
122
147
|
|
|
123
148
|
traces = traces.concat(this.buildOfflineNATraces(this.dataItems)); // generate bar traces
|
|
@@ -131,12 +156,13 @@ var script$1 = {
|
|
|
131
156
|
margin: {
|
|
132
157
|
l: 50,
|
|
133
158
|
r: 50,
|
|
134
|
-
b:
|
|
135
|
-
t:
|
|
159
|
+
b: 50,
|
|
160
|
+
t: 20,
|
|
136
161
|
pad: 4
|
|
137
162
|
},
|
|
138
163
|
xaxis: {
|
|
139
164
|
type: 'date',
|
|
165
|
+
ticklabelmode: this.xaxisMode(),
|
|
140
166
|
title: this.xaxisTitle,
|
|
141
167
|
font: {
|
|
142
168
|
size: 10
|
|
@@ -144,11 +170,17 @@ var script$1 = {
|
|
|
144
170
|
tickfont: {
|
|
145
171
|
size: 10
|
|
146
172
|
},
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
173
|
+
showgrid: this.sixMonths ? true : false,
|
|
174
|
+
griddash: "dot",
|
|
175
|
+
gridwidth: 1,
|
|
176
|
+
gridcolor: "#d9d7d7",
|
|
177
|
+
showspikes: true,
|
|
178
|
+
spikedash: "4px",
|
|
179
|
+
spikethickness: 1,
|
|
180
|
+
tick0: this.xaxisTickZero(),
|
|
181
|
+
dtick: this.xaxisTickD(),
|
|
182
|
+
tickangle: this.xaxisTickAngle(),
|
|
183
|
+
tickformat: this.xaxisTickFormat()
|
|
152
184
|
},
|
|
153
185
|
yaxis: {
|
|
154
186
|
title: this.yaxisTitle,
|
|
@@ -163,9 +195,9 @@ var script$1 = {
|
|
|
163
195
|
legend: {
|
|
164
196
|
orientation: 'h',
|
|
165
197
|
yanchor: 'bottom',
|
|
166
|
-
y:
|
|
167
|
-
xanchor: '
|
|
168
|
-
x:
|
|
198
|
+
y: -0.5,
|
|
199
|
+
xanchor: 'left',
|
|
200
|
+
x: 0.05,
|
|
169
201
|
font: {
|
|
170
202
|
size: 8
|
|
171
203
|
}
|
|
@@ -175,7 +207,8 @@ var script$1 = {
|
|
|
175
207
|
},
|
|
176
208
|
hovermode: 'closest'
|
|
177
209
|
};
|
|
178
|
-
|
|
210
|
+
console.log(this.divId);
|
|
211
|
+
Plotly.newPlot(this.divId, traces, layout, this.config);
|
|
179
212
|
},
|
|
180
213
|
methods: {
|
|
181
214
|
generateColor(values, transparency) {
|
|
@@ -302,10 +335,18 @@ var script$1 = {
|
|
|
302
335
|
|
|
303
336
|
// set start and end dates so that the line spands the whole plot
|
|
304
337
|
const firstDate = new Date(this.dataItems[0].date);
|
|
305
|
-
|
|
338
|
+
if (this.week) {
|
|
339
|
+
firstDate.setDate(firstDate.getDate() - 0.3); // one day before the first date in data
|
|
340
|
+
} else {
|
|
341
|
+
firstDate.setDate(firstDate.getDate() - 1); // one month before the first date in data
|
|
342
|
+
}
|
|
306
343
|
|
|
307
344
|
const lastDate = new Date(this.dataItems[this.dataItems.length - 1].date);
|
|
308
|
-
|
|
345
|
+
if (this.week) {
|
|
346
|
+
lastDate.setDate(lastDate.getDate() + 0.3);
|
|
347
|
+
} else {
|
|
348
|
+
lastDate.setDate(lastDate.getDate() + 1); // one month after the last date in data
|
|
349
|
+
}
|
|
309
350
|
|
|
310
351
|
const trace = {
|
|
311
352
|
x: [firstDate, lastDate],
|
|
@@ -344,17 +385,6 @@ var script$1 = {
|
|
|
344
385
|
return traces;
|
|
345
386
|
},
|
|
346
387
|
extractOfflineNADates(data) {
|
|
347
|
-
/*
|
|
348
|
-
This function extracts dates with access_time null.
|
|
349
|
-
Depending on the code, the server is offline or NA on those dates.
|
|
350
|
-
Arguments:
|
|
351
|
-
- data: array of objects with keys "access_time", "date" and "code". access_time and code can be null
|
|
352
|
-
|
|
353
|
-
Returns an object with keys:
|
|
354
|
-
- NA: array of dates with access_time null and code null
|
|
355
|
-
- down: array of dates with access_time null and code in errorCodes
|
|
356
|
-
*/
|
|
357
|
-
const errorCodes = [404, 500, 502, 503, 504];
|
|
358
388
|
const resultNA = [];
|
|
359
389
|
const resultOffline = [];
|
|
360
390
|
for (let i = 0; i < data.length; i++) {
|
|
@@ -362,7 +392,7 @@ var script$1 = {
|
|
|
362
392
|
if (data[i].access_time === null && data[i].code === null) {
|
|
363
393
|
resultNA.push(data[i].date);
|
|
364
394
|
// if the access_time is null and the code is in errorCodes, it means that the server is offline
|
|
365
|
-
} else if (data[i].access_time === null
|
|
395
|
+
} else if (data[i].access_time === null) {
|
|
366
396
|
resultOffline.push(data[i].date);
|
|
367
397
|
}
|
|
368
398
|
}
|
|
@@ -371,7 +401,7 @@ var script$1 = {
|
|
|
371
401
|
down: resultOffline
|
|
372
402
|
};
|
|
373
403
|
},
|
|
374
|
-
barTrace(data, name, showlegend, hoverinfo, hovertemplate) {
|
|
404
|
+
barTrace(data, name, showlegend, hoverinfo, hovertemplate, group) {
|
|
375
405
|
/*
|
|
376
406
|
This function builds a bar trace.
|
|
377
407
|
Arguments:
|
|
@@ -389,14 +419,17 @@ var script$1 = {
|
|
|
389
419
|
},
|
|
390
420
|
name: name,
|
|
391
421
|
type: "bar",
|
|
392
|
-
legendgroup:
|
|
422
|
+
legendgroup: group,
|
|
393
423
|
showlegend: showlegend,
|
|
394
424
|
hoverinfo: hoverinfo,
|
|
395
|
-
hovertemplate: hovertemplate
|
|
425
|
+
hovertemplate: hovertemplate,
|
|
426
|
+
width: 1000 * 3600 * 24 * 1 // 100% of the space between two dates
|
|
396
427
|
};
|
|
428
|
+
|
|
429
|
+
console.log(trace);
|
|
397
430
|
return trace;
|
|
398
431
|
},
|
|
399
|
-
buildBarTraces(dates, color, label) {
|
|
432
|
+
buildBarTraces(dates, color, label, group) {
|
|
400
433
|
/*
|
|
401
434
|
This function builds the series used to display the offline/NA bars.
|
|
402
435
|
For each date, two columns are created: one very short and one tall.
|
|
@@ -417,12 +450,12 @@ var script$1 = {
|
|
|
417
450
|
};
|
|
418
451
|
const dataTall = {
|
|
419
452
|
dates: dates,
|
|
420
|
-
access_times: Array(dates.length).fill(
|
|
453
|
+
access_times: Array(dates.length).fill(this.max_access_time * 1.1),
|
|
421
454
|
colors: Array(dates.length).fill(colorLight)
|
|
422
455
|
};
|
|
423
456
|
const hovertemplate = `<b>${label}</b><br>%{x|%d %b %Y}<br>%{y} ms <extra></extra>`;
|
|
424
|
-
const traceShort = this.barTrace(dataShort, label, false, 'skip', '');
|
|
425
|
-
const traceTall = this.barTrace(dataTall, label, true, 'all', hovertemplate);
|
|
457
|
+
const traceShort = this.barTrace(dataShort, label, false, 'skip', '', group);
|
|
458
|
+
const traceTall = this.barTrace(dataTall, label, true, 'all', hovertemplate, group);
|
|
426
459
|
return [traceShort, traceTall];
|
|
427
460
|
},
|
|
428
461
|
buildOfflineNATraces(data) {
|
|
@@ -438,11 +471,73 @@ var script$1 = {
|
|
|
438
471
|
const arrays = this.extractOfflineNADates(data);
|
|
439
472
|
|
|
440
473
|
// Down arrays
|
|
441
|
-
|
|
442
|
-
|
|
474
|
+
if (arrays.down.length > 0) {
|
|
475
|
+
traces = traces.concat(this.buildBarTraces(arrays.down, this.colorOffline, 'Offline', 'down'));
|
|
476
|
+
console.log(arrays.down);
|
|
477
|
+
}
|
|
443
478
|
// NA arrays
|
|
444
|
-
|
|
479
|
+
if (arrays.NA.length > 0) {
|
|
480
|
+
traces = traces.concat(this.buildBarTraces(arrays.NA, this.colorNA, 'No information available', 'na'));
|
|
481
|
+
console.log(arrays.NA);
|
|
482
|
+
}
|
|
445
483
|
return traces;
|
|
484
|
+
},
|
|
485
|
+
xaxisTickFormat() {
|
|
486
|
+
/*
|
|
487
|
+
This function returns the tickformat of the x axis.
|
|
488
|
+
If the plot is used to show data of one week, it returns the day of the week and the day.
|
|
489
|
+
Otherwise, it returns the day and the month.
|
|
490
|
+
*/
|
|
491
|
+
|
|
492
|
+
if (this.week) {
|
|
493
|
+
return "%A<br>%d %b";
|
|
494
|
+
}
|
|
495
|
+
if (this.sixMonths) {
|
|
496
|
+
return "%b";
|
|
497
|
+
} else {
|
|
498
|
+
return "%d %b";
|
|
499
|
+
}
|
|
500
|
+
},
|
|
501
|
+
xaxisTickAngle() {
|
|
502
|
+
/*
|
|
503
|
+
This function returns the tickangle of the x axis.
|
|
504
|
+
If the plot is used to show data of one week, it returns 0.
|
|
505
|
+
Otherwise, it returns 45.
|
|
506
|
+
*/
|
|
507
|
+
if (this.week) {
|
|
508
|
+
return 0;
|
|
509
|
+
}
|
|
510
|
+
if (this.sixMonths) {
|
|
511
|
+
return 0;
|
|
512
|
+
} else {
|
|
513
|
+
return 45;
|
|
514
|
+
}
|
|
515
|
+
},
|
|
516
|
+
xaxisTickD() {
|
|
517
|
+
if (this.sixMonths === true) {
|
|
518
|
+
return "M1";
|
|
519
|
+
} else {
|
|
520
|
+
return this.dtick;
|
|
521
|
+
}
|
|
522
|
+
},
|
|
523
|
+
xaxisTickZero() {
|
|
524
|
+
if (this.sixMonths === true) {
|
|
525
|
+
console.log('zero six months ago');
|
|
526
|
+
const lastDate = new Date(this.dataItems[this.dataItems.length - 1].date);
|
|
527
|
+
//return lastDate minus six months
|
|
528
|
+
console.log(lastDate);
|
|
529
|
+
console.log('six months ago: ' + new Date(lastDate.setMonth(lastDate.getMonth() - 6)));
|
|
530
|
+
return new Date(lastDate.setMonth(lastDate.getMonth() - 6));
|
|
531
|
+
} else {
|
|
532
|
+
return this.dataItems[0];
|
|
533
|
+
}
|
|
534
|
+
},
|
|
535
|
+
xaxisMode() {
|
|
536
|
+
if (this.sixMonths === true) {
|
|
537
|
+
return "period";
|
|
538
|
+
} else {
|
|
539
|
+
return "instant";
|
|
540
|
+
}
|
|
446
541
|
}
|
|
447
542
|
}
|
|
448
543
|
};
|
|
@@ -569,7 +664,7 @@ var accessibilityPlot = normalizeComponent_1({
|
|
|
569
664
|
var script = {
|
|
570
665
|
name: 'citationsPlot',
|
|
571
666
|
data: () => ({
|
|
572
|
-
divId: randstr('
|
|
667
|
+
divId: randstr('cit_plot_')
|
|
573
668
|
}),
|
|
574
669
|
props: {
|
|
575
670
|
dataTraces: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var oeb_visualizations=function(e,t){"use strict";function i(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var
|
|
1
|
+
var oeb_visualizations=function(e,t){"use strict";function i(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var s=i(t);function a(e){return Math.random().toString(36).replace("0.",e||"")}var r=function(e,t,i,s,a,r,o,n,l,c){"boolean"!=typeof o&&(l=n,n=o,o=!1);var d,h="function"==typeof i?i.options:i;if(e&&e.render&&(h.render=e.render,h.staticRenderFns=e.staticRenderFns,h._compiled=!0,a&&(h.functional=!0)),s&&(h._scopeId=s),r?(d=function(e){(e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext)||"undefined"==typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),t&&t.call(this,l(e)),e&&e._registeredComponents&&e._registeredComponents.add(r)},h._ssrRegister=d):t&&(d=o?function(){t.call(this,c(this.$root.$options.shadowRoot))}:function(e){t.call(this,n(e))}),d)if(h.functional){var u=h.render;h.render=function(e,t){return d.call(t),u(e,t)}}else{var m=h.beforeCreate;h.beforeCreate=m?[].concat(m,d):[d]}return i};var o=r({render:function(){var e=this,t=e.$createElement;return(e._self._c||t)("div",{attrs:{id:e.divId}})},staticRenderFns:[]},undefined,{name:"accessibilityPlot",data:()=>({divId:a("acc_plot_"),max_access_time:0,config:{displaylogo:!1,responsive:!0,modeBarButtonsToRemove:["lasso"]}}),props:{dtick:{type:Number,required:!1,default:864e5},xaxisTitle:{type:String,required:!1,default:"Date"},yaxisTitle:{type:String,required:!1,default:"Access time (ms)"},colorOnline:{type:String,required:!1,default:"111, 176, 129"},colorOffline:{type:String,required:!1,default:"255, 153, 145"},colorNA:{type:String,required:!1,default:"204,204,204"},height:{type:Number,required:!1,default:350},week:{type:Boolean,required:!1,default:!1},sixMonths:{type:Boolean,required:!1,default:!1},dataItems:{type:Array,required:!0,validator:function(e){for(let t=0;t<e.length;t++)e[t].hasOwnProperty("access_time")?e[t].hasOwnProperty("date")?e[t].hasOwnProperty("code")||console.error(`[oeb-visualizations warn] code key is missing in dataItems prop item (at position ${t})`):console.error(`[oeb-visualizations warn] date key is missing in dataItems prop item (at position ${t})`):console.error(`[oeb-visualizations warn] access_time key is missing in dataItems prop item (at position ${t})`),null!==e[t].access_time&&"number"!=typeof e[t].access_time&&console.error(`[oeb-visualizations warn] access_time must be null or a number in dataItems prop item (at position ${t})`),null!==e[t].code&&"number"!=typeof e[t].code&&console.error(`[oeb-visualizations warn] code must be null or a number in dataItems prop item (at position ${t})`),("string"!=typeof e[t].date||isNaN(Date.parse(e[t].date)))&&console.error(`[oeb-visualizations warn] date must be a string containing a date in dataItems prop item (at position ${t})`),null===e[t].date&&console.error(`[oeb-visualizations warn] date cannot be null in dataItems prop item (at position ${t})`);return!0}}},mounted(){this.max_access_time=Math.max(...this.dataItems.map((e=>e.access_time)));var e=this.buildOnlineTraces(this.dataItems);e=e.concat(this.buildOfflineNATraces(this.dataItems));const t={bargap:0,barmode:"stack",showlegend:!0,autosize:!0,height:this.height,margin:{l:50,r:50,b:50,t:20,pad:4},xaxis:{type:"date",ticklabelmode:this.xaxisMode(),title:this.xaxisTitle,font:{size:10},tickfont:{size:10},showgrid:!!this.sixMonths,griddash:"dot",gridwidth:1,gridcolor:"#d9d7d7",showspikes:!0,spikedash:"4px",spikethickness:1,tick0:this.xaxisTickZero(),dtick:this.xaxisTickD(),tickangle:this.xaxisTickAngle(),tickformat:this.xaxisTickFormat()},yaxis:{title:this.yaxisTitle,titlefont:{size:10},tickfont:{size:10}},template:"plotly_white",legend:{orientation:"h",yanchor:"bottom",y:-.5,xanchor:"left",x:.05,font:{size:8}},hoverlabel:{bgcolor:"#FFF"},hovermode:"closest"};console.log(this.divId),s.default.newPlot(this.divId,e,t,this.config)},methods:{generateColor(e,t){let i=[];for(let s=0;s<30;s++)switch(e[s]){case"up":i.push(`rgba(${this.colorOnline},0)`);break;case"down":i.push(`rgba(${this.colorOffline},${t})`);break;case"NA":i.push(`rgba(${this.colorNA},${t})`)}return i},extractSubarraysBetweenNullValues(e){var t={access_time:[],date:[],average_access_time:0},i=[],s=[],a=0,r=0;for(let o=0;o<e.length;o++)null!==e[o].access_time?(i.push(e[o].access_time),s.push(e[o].date),a+=e[o].access_time,r+=1):i.length>0&&(t.access_time.push(i),t.date.push(s),i=[],s=[]);return t.access_time.push(i),t.date.push(s),t.average_access_time=a/r,t},buildAccessTimeTraces(e){var t=[];for(let i=0;i<e.access_time.length;i++){const s=e.access_time[i],a={x:e.date[i],y:s,name:"Online",legendgroup:"up",showlegend:0===i,mode:"markers+lines",type:"scatter",fill:"tozeroy",fillcolor:`rgba(${this.colorOnline},.2)`,connectgaps:!1,line:{color:`rgba(${this.colorOnline},.8)`,width:1.5},marker:{size:5},hovertemplate:"<b>Online</b><br>%{x|%d %b %Y}<br>%{y} ms <extra></extra>",hoveron:"points+fills"};t.push(a)}return t},buildAvgAccessTimeTrace(e){const t=new Date(this.dataItems[0].date);this.week?t.setDate(t.getDate()-.3):t.setDate(t.getDate()-1);const i=new Date(this.dataItems[this.dataItems.length-1].date);this.week?i.setDate(i.getDate()+.3):i.setDate(i.getDate()+1);return{x:[t,i],y:[e,e],name:"Average access time",showlegend:!0,mode:"lines",type:"scatter",line:{color:`rgba(${this.colorOnline},.6)`,width:1.5,dash:"4px"},marker:{size:5},hovertemplate:"<b>Average access time</b><br>%{y:.2f} ms <extra></extra>"}},buildOnlineTraces(e){const t=this.extractSubarraysBetweenNullValues(e);var i=this.buildAccessTimeTraces(t);return i.push(this.buildAvgAccessTimeTrace(t.average_access_time)),i},extractOfflineNADates(e){const t=[],i=[];for(let s=0;s<e.length;s++)null===e[s].access_time&&null===e[s].code?t.push(e[s].date):null===e[s].access_time&&i.push(e[s].date);return{NA:t,down:i}},barTrace(e,t,i,s,a,r){const o={x:e.dates,y:e.access_times,marker:{color:e.colors},name:t,type:"bar",legendgroup:r,showlegend:i,hoverinfo:s,hovertemplate:a,width:864e5};return console.log(o),o},buildBarTraces(e,t,i,s){const a=`rgba(${t},.8)`,r=`rgba(${t},.2)`,o={dates:e,access_times:Array(e.length).fill(2),colors:Array(e.length).fill(a)},n={dates:e,access_times:Array(e.length).fill(1.1*this.max_access_time),colors:Array(e.length).fill(r)},l=`<b>${i}</b><br>%{x|%d %b %Y}<br>%{y} ms <extra></extra>`;return[this.barTrace(o,i,!1,"skip","",s),this.barTrace(n,i,!0,"all",l,s)]},buildOfflineNATraces(e){var t=[];const i=this.extractOfflineNADates(e);return i.down.length>0&&(t=t.concat(this.buildBarTraces(i.down,this.colorOffline,"Offline","down")),console.log(i.down)),i.NA.length>0&&(t=t.concat(this.buildBarTraces(i.NA,this.colorNA,"No information available","na")),console.log(i.NA)),t},xaxisTickFormat(){return this.week?"%A<br>%d %b":this.sixMonths?"%b":"%d %b"},xaxisTickAngle(){return this.week||this.sixMonths?0:45},xaxisTickD(){return!0===this.sixMonths?"M1":this.dtick},xaxisTickZero(){if(!0===this.sixMonths){console.log("zero six months ago");const e=new Date(this.dataItems[this.dataItems.length-1].date);return console.log(e),console.log("six months ago: "+new Date(e.setMonth(e.getMonth()-6))),new Date(e.setMonth(e.getMonth()-6))}return this.dataItems[0]},xaxisMode(){return!0===this.sixMonths?"period":"instant"}}},undefined,!1,undefined,void 0,void 0);var n=r({render:function(){var e=this,t=e.$createElement;return(e._self._c||t)("div",{attrs:{id:e.divId}})},staticRenderFns:[]},undefined,{name:"citationsPlot",data:()=>({divId:a("cit_plot_")}),props:{dataTraces:{type:Array,required:!0},stack:{type:Boolean,required:!1,default:!1},colors:{type:Array,required:!1,default:()=>["#1f77b4","#ff7f0e","#2ca02c","#d62728","#9467bd"]},height:{type:Number,required:!1,default:400},showlegend:{type:Boolean,required:!1,default:!0},title:{type:String,required:!1,default:""},xaxisTitle:{type:String,required:!1,default:"Year"},yaxisTitle:{type:String,required:!1,default:"Number of citations"},darkMode:{type:Boolean,required:!1,default:!1}},mounted(){const e=this.buildTraces(),t={showlegend:this.showlegend,autosize:!0,height:this.height,margin:{l:50,r:50,b:70,t:50,pad:4},xaxis:{title:this.xaxisTitle,font:{size:10},tickfont:{size:10},tickmode:"linear",color:this.darkMode?"white":"black"},yaxis:{title:this.yaxisTitle,titlefont:{size:10},tickfont:{size:10},font:{size:10},color:this.darkMode?"white":"black"},legend:{orientation:"h",yanchor:"bottom",y:1.02,xanchor:"right",x:1,font:{size:8,color:this.darkMode?"white":"black"}},hoverlabel:{color:this.darkMode?"white":"black"},hovermode:this.stack?"x unified":"closest",hoverdistance:70,plot_bgcolor:this.darkMode?"rgb(38, 50, 56)":"white",paper_bgcolor:this.darkMode?"rgb(38, 50, 56)":"white"};s.default.newPlot(this.divId,e,t)},methods:{buildTraces(){const e=[];for(let t=0;t<this.dataTraces.length;t++){const i={x:this.dataTraces[t].data.map((e=>e.year)),y:this.dataTraces[t].data.map((e=>e.citations)),mode:"lines+markers",name:this.dataTraces[t].label,hovertemplate:this.hoverTemplate(),marker:{size:5},line:{color:this.colors[t],width:1.8},stackgroup:this.stack?"one":null};e.push(i)}return e},hoverTemplate(){return this.stack?"%{y} citations <extra></extra>":"%{y} citations in %{x} <extra></extra>"}}},undefined,!1,undefined,void 0,void 0),l=Object.freeze({__proto__:null,accessibilityPlot:o,citationsPlot:n});const c=function(e){c.installed||(c.installed=!0,Object.entries(l).forEach((([t,i])=>{e.component(t,i)})))},d={install:c};{let e=null;"undefined"!=typeof window?e=window.Vue:"undefined"!=typeof global&&(e=global.Vue),e&&e.use(d)}return e.accessibilityPlot=o,e.citationsPlot=n,e.default=d,Object.defineProperty(e,"__esModule",{value:!0}),e}({},Plotly);
|
|
@@ -4,7 +4,13 @@
|
|
|
4
4
|
var script$1 = {
|
|
5
5
|
name: 'accessibilityPlot',
|
|
6
6
|
data: () => ({
|
|
7
|
-
divId: randstr('
|
|
7
|
+
divId: randstr('acc_plot_'),
|
|
8
|
+
max_access_time: 0,
|
|
9
|
+
config: {
|
|
10
|
+
displaylogo: false,
|
|
11
|
+
responsive: true,
|
|
12
|
+
modeBarButtonsToRemove: ['lasso']
|
|
13
|
+
}
|
|
8
14
|
}),
|
|
9
15
|
props: {
|
|
10
16
|
dtick: {
|
|
@@ -66,6 +72,24 @@ var script$1 = {
|
|
|
66
72
|
required: false,
|
|
67
73
|
default: 350
|
|
68
74
|
},
|
|
75
|
+
week: {
|
|
76
|
+
/*
|
|
77
|
+
whether the plot is used to show data of one week
|
|
78
|
+
If true, days of the week are shown on the x axis
|
|
79
|
+
*/
|
|
80
|
+
type: Boolean,
|
|
81
|
+
required: false,
|
|
82
|
+
default: false
|
|
83
|
+
},
|
|
84
|
+
sixMonths: {
|
|
85
|
+
/*
|
|
86
|
+
whether the plot is used to show data of six months
|
|
87
|
+
If true, months are shown on the x axis
|
|
88
|
+
*/
|
|
89
|
+
type: Boolean,
|
|
90
|
+
required: false,
|
|
91
|
+
default: false
|
|
92
|
+
},
|
|
69
93
|
dataItems: {
|
|
70
94
|
/*
|
|
71
95
|
dataItems is an array of objects with keys "access_time", "date" and "code".
|
|
@@ -114,6 +138,7 @@ var script$1 = {
|
|
|
114
138
|
}
|
|
115
139
|
},
|
|
116
140
|
mounted() {
|
|
141
|
+
this.max_access_time = Math.max(...this.dataItems.map(item => item.access_time));
|
|
117
142
|
var traces = this.buildOnlineTraces(this.dataItems); // generate line traces
|
|
118
143
|
|
|
119
144
|
traces = traces.concat(this.buildOfflineNATraces(this.dataItems)); // generate bar traces
|
|
@@ -127,12 +152,13 @@ var script$1 = {
|
|
|
127
152
|
margin: {
|
|
128
153
|
l: 50,
|
|
129
154
|
r: 50,
|
|
130
|
-
b:
|
|
131
|
-
t:
|
|
155
|
+
b: 50,
|
|
156
|
+
t: 20,
|
|
132
157
|
pad: 4
|
|
133
158
|
},
|
|
134
159
|
xaxis: {
|
|
135
160
|
type: 'date',
|
|
161
|
+
ticklabelmode: this.xaxisMode(),
|
|
136
162
|
title: this.xaxisTitle,
|
|
137
163
|
font: {
|
|
138
164
|
size: 10
|
|
@@ -140,11 +166,17 @@ var script$1 = {
|
|
|
140
166
|
tickfont: {
|
|
141
167
|
size: 10
|
|
142
168
|
},
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
169
|
+
showgrid: this.sixMonths ? true : false,
|
|
170
|
+
griddash: "dot",
|
|
171
|
+
gridwidth: 1,
|
|
172
|
+
gridcolor: "#d9d7d7",
|
|
173
|
+
showspikes: true,
|
|
174
|
+
spikedash: "4px",
|
|
175
|
+
spikethickness: 1,
|
|
176
|
+
tick0: this.xaxisTickZero(),
|
|
177
|
+
dtick: this.xaxisTickD(),
|
|
178
|
+
tickangle: this.xaxisTickAngle(),
|
|
179
|
+
tickformat: this.xaxisTickFormat()
|
|
148
180
|
},
|
|
149
181
|
yaxis: {
|
|
150
182
|
title: this.yaxisTitle,
|
|
@@ -159,9 +191,9 @@ var script$1 = {
|
|
|
159
191
|
legend: {
|
|
160
192
|
orientation: 'h',
|
|
161
193
|
yanchor: 'bottom',
|
|
162
|
-
y:
|
|
163
|
-
xanchor: '
|
|
164
|
-
x:
|
|
194
|
+
y: -0.5,
|
|
195
|
+
xanchor: 'left',
|
|
196
|
+
x: 0.05,
|
|
165
197
|
font: {
|
|
166
198
|
size: 8
|
|
167
199
|
}
|
|
@@ -171,7 +203,8 @@ var script$1 = {
|
|
|
171
203
|
},
|
|
172
204
|
hovermode: 'closest'
|
|
173
205
|
};
|
|
174
|
-
|
|
206
|
+
console.log(this.divId);
|
|
207
|
+
Plotly__default["default"].newPlot(this.divId, traces, layout, this.config);
|
|
175
208
|
},
|
|
176
209
|
methods: {
|
|
177
210
|
generateColor(values, transparency) {
|
|
@@ -298,10 +331,18 @@ var script$1 = {
|
|
|
298
331
|
|
|
299
332
|
// set start and end dates so that the line spands the whole plot
|
|
300
333
|
const firstDate = new Date(this.dataItems[0].date);
|
|
301
|
-
|
|
334
|
+
if (this.week) {
|
|
335
|
+
firstDate.setDate(firstDate.getDate() - 0.3); // one day before the first date in data
|
|
336
|
+
} else {
|
|
337
|
+
firstDate.setDate(firstDate.getDate() - 1); // one month before the first date in data
|
|
338
|
+
}
|
|
302
339
|
|
|
303
340
|
const lastDate = new Date(this.dataItems[this.dataItems.length - 1].date);
|
|
304
|
-
|
|
341
|
+
if (this.week) {
|
|
342
|
+
lastDate.setDate(lastDate.getDate() + 0.3);
|
|
343
|
+
} else {
|
|
344
|
+
lastDate.setDate(lastDate.getDate() + 1); // one month after the last date in data
|
|
345
|
+
}
|
|
305
346
|
|
|
306
347
|
const trace = {
|
|
307
348
|
x: [firstDate, lastDate],
|
|
@@ -340,17 +381,6 @@ var script$1 = {
|
|
|
340
381
|
return traces;
|
|
341
382
|
},
|
|
342
383
|
extractOfflineNADates(data) {
|
|
343
|
-
/*
|
|
344
|
-
This function extracts dates with access_time null.
|
|
345
|
-
Depending on the code, the server is offline or NA on those dates.
|
|
346
|
-
Arguments:
|
|
347
|
-
- data: array of objects with keys "access_time", "date" and "code". access_time and code can be null
|
|
348
|
-
|
|
349
|
-
Returns an object with keys:
|
|
350
|
-
- NA: array of dates with access_time null and code null
|
|
351
|
-
- down: array of dates with access_time null and code in errorCodes
|
|
352
|
-
*/
|
|
353
|
-
const errorCodes = [404, 500, 502, 503, 504];
|
|
354
384
|
const resultNA = [];
|
|
355
385
|
const resultOffline = [];
|
|
356
386
|
for (let i = 0; i < data.length; i++) {
|
|
@@ -358,7 +388,7 @@ var script$1 = {
|
|
|
358
388
|
if (data[i].access_time === null && data[i].code === null) {
|
|
359
389
|
resultNA.push(data[i].date);
|
|
360
390
|
// if the access_time is null and the code is in errorCodes, it means that the server is offline
|
|
361
|
-
} else if (data[i].access_time === null
|
|
391
|
+
} else if (data[i].access_time === null) {
|
|
362
392
|
resultOffline.push(data[i].date);
|
|
363
393
|
}
|
|
364
394
|
}
|
|
@@ -367,7 +397,7 @@ var script$1 = {
|
|
|
367
397
|
down: resultOffline
|
|
368
398
|
};
|
|
369
399
|
},
|
|
370
|
-
barTrace(data, name, showlegend, hoverinfo, hovertemplate) {
|
|
400
|
+
barTrace(data, name, showlegend, hoverinfo, hovertemplate, group) {
|
|
371
401
|
/*
|
|
372
402
|
This function builds a bar trace.
|
|
373
403
|
Arguments:
|
|
@@ -385,14 +415,17 @@ var script$1 = {
|
|
|
385
415
|
},
|
|
386
416
|
name: name,
|
|
387
417
|
type: "bar",
|
|
388
|
-
legendgroup:
|
|
418
|
+
legendgroup: group,
|
|
389
419
|
showlegend: showlegend,
|
|
390
420
|
hoverinfo: hoverinfo,
|
|
391
|
-
hovertemplate: hovertemplate
|
|
421
|
+
hovertemplate: hovertemplate,
|
|
422
|
+
width: 1000 * 3600 * 24 * 1 // 100% of the space between two dates
|
|
392
423
|
};
|
|
424
|
+
|
|
425
|
+
console.log(trace);
|
|
393
426
|
return trace;
|
|
394
427
|
},
|
|
395
|
-
buildBarTraces(dates, color, label) {
|
|
428
|
+
buildBarTraces(dates, color, label, group) {
|
|
396
429
|
/*
|
|
397
430
|
This function builds the series used to display the offline/NA bars.
|
|
398
431
|
For each date, two columns are created: one very short and one tall.
|
|
@@ -413,12 +446,12 @@ var script$1 = {
|
|
|
413
446
|
};
|
|
414
447
|
const dataTall = {
|
|
415
448
|
dates: dates,
|
|
416
|
-
access_times: Array(dates.length).fill(
|
|
449
|
+
access_times: Array(dates.length).fill(this.max_access_time * 1.1),
|
|
417
450
|
colors: Array(dates.length).fill(colorLight)
|
|
418
451
|
};
|
|
419
452
|
const hovertemplate = `<b>${label}</b><br>%{x|%d %b %Y}<br>%{y} ms <extra></extra>`;
|
|
420
|
-
const traceShort = this.barTrace(dataShort, label, false, 'skip', '');
|
|
421
|
-
const traceTall = this.barTrace(dataTall, label, true, 'all', hovertemplate);
|
|
453
|
+
const traceShort = this.barTrace(dataShort, label, false, 'skip', '', group);
|
|
454
|
+
const traceTall = this.barTrace(dataTall, label, true, 'all', hovertemplate, group);
|
|
422
455
|
return [traceShort, traceTall];
|
|
423
456
|
},
|
|
424
457
|
buildOfflineNATraces(data) {
|
|
@@ -434,11 +467,73 @@ var script$1 = {
|
|
|
434
467
|
const arrays = this.extractOfflineNADates(data);
|
|
435
468
|
|
|
436
469
|
// Down arrays
|
|
437
|
-
|
|
438
|
-
|
|
470
|
+
if (arrays.down.length > 0) {
|
|
471
|
+
traces = traces.concat(this.buildBarTraces(arrays.down, this.colorOffline, 'Offline', 'down'));
|
|
472
|
+
console.log(arrays.down);
|
|
473
|
+
}
|
|
439
474
|
// NA arrays
|
|
440
|
-
|
|
475
|
+
if (arrays.NA.length > 0) {
|
|
476
|
+
traces = traces.concat(this.buildBarTraces(arrays.NA, this.colorNA, 'No information available', 'na'));
|
|
477
|
+
console.log(arrays.NA);
|
|
478
|
+
}
|
|
441
479
|
return traces;
|
|
480
|
+
},
|
|
481
|
+
xaxisTickFormat() {
|
|
482
|
+
/*
|
|
483
|
+
This function returns the tickformat of the x axis.
|
|
484
|
+
If the plot is used to show data of one week, it returns the day of the week and the day.
|
|
485
|
+
Otherwise, it returns the day and the month.
|
|
486
|
+
*/
|
|
487
|
+
|
|
488
|
+
if (this.week) {
|
|
489
|
+
return "%A<br>%d %b";
|
|
490
|
+
}
|
|
491
|
+
if (this.sixMonths) {
|
|
492
|
+
return "%b";
|
|
493
|
+
} else {
|
|
494
|
+
return "%d %b";
|
|
495
|
+
}
|
|
496
|
+
},
|
|
497
|
+
xaxisTickAngle() {
|
|
498
|
+
/*
|
|
499
|
+
This function returns the tickangle of the x axis.
|
|
500
|
+
If the plot is used to show data of one week, it returns 0.
|
|
501
|
+
Otherwise, it returns 45.
|
|
502
|
+
*/
|
|
503
|
+
if (this.week) {
|
|
504
|
+
return 0;
|
|
505
|
+
}
|
|
506
|
+
if (this.sixMonths) {
|
|
507
|
+
return 0;
|
|
508
|
+
} else {
|
|
509
|
+
return 45;
|
|
510
|
+
}
|
|
511
|
+
},
|
|
512
|
+
xaxisTickD() {
|
|
513
|
+
if (this.sixMonths === true) {
|
|
514
|
+
return "M1";
|
|
515
|
+
} else {
|
|
516
|
+
return this.dtick;
|
|
517
|
+
}
|
|
518
|
+
},
|
|
519
|
+
xaxisTickZero() {
|
|
520
|
+
if (this.sixMonths === true) {
|
|
521
|
+
console.log('zero six months ago');
|
|
522
|
+
const lastDate = new Date(this.dataItems[this.dataItems.length - 1].date);
|
|
523
|
+
//return lastDate minus six months
|
|
524
|
+
console.log(lastDate);
|
|
525
|
+
console.log('six months ago: ' + new Date(lastDate.setMonth(lastDate.getMonth() - 6)));
|
|
526
|
+
return new Date(lastDate.setMonth(lastDate.getMonth() - 6));
|
|
527
|
+
} else {
|
|
528
|
+
return this.dataItems[0];
|
|
529
|
+
}
|
|
530
|
+
},
|
|
531
|
+
xaxisMode() {
|
|
532
|
+
if (this.sixMonths === true) {
|
|
533
|
+
return "period";
|
|
534
|
+
} else {
|
|
535
|
+
return "instant";
|
|
536
|
+
}
|
|
442
537
|
}
|
|
443
538
|
}
|
|
444
539
|
};function normalizeComponent(template, style, script, scopeId, isFunctionalTemplate, moduleIdentifier
|
|
@@ -545,7 +640,7 @@ const __vue_inject_styles__$1 = undefined;
|
|
|
545
640
|
/* scoped */
|
|
546
641
|
const __vue_scope_id__$1 = undefined;
|
|
547
642
|
/* module identifier */
|
|
548
|
-
const __vue_module_identifier__$1 = "data-v-
|
|
643
|
+
const __vue_module_identifier__$1 = "data-v-77c84891";
|
|
549
644
|
/* functional template */
|
|
550
645
|
const __vue_is_functional_template__$1 = false;
|
|
551
646
|
/* style inject */
|
|
@@ -559,7 +654,7 @@ var accessibilityPlot = normalizeComponent_1({
|
|
|
559
654
|
var script = {
|
|
560
655
|
name: 'citationsPlot',
|
|
561
656
|
data: () => ({
|
|
562
|
-
divId: randstr('
|
|
657
|
+
divId: randstr('cit_plot_')
|
|
563
658
|
}),
|
|
564
659
|
props: {
|
|
565
660
|
dataTraces: {
|
|
@@ -731,7 +826,7 @@ const __vue_inject_styles__ = undefined;
|
|
|
731
826
|
/* scoped */
|
|
732
827
|
const __vue_scope_id__ = undefined;
|
|
733
828
|
/* module identifier */
|
|
734
|
-
const __vue_module_identifier__ = "data-v-
|
|
829
|
+
const __vue_module_identifier__ = "data-v-4ac5e814";
|
|
735
830
|
/* functional template */
|
|
736
831
|
const __vue_is_functional_template__ = false;
|
|
737
832
|
/* style inject */
|