diff --git a/src/visualizations/VisTimeline.vue b/src/visualizations/VisTimeline.vue
index cf9c435f..c7e56e7b 100644
--- a/src/visualizations/VisTimeline.vue
+++ b/src/visualizations/VisTimeline.vue
@@ -28,6 +28,13 @@ div#visualization {
pointer-events: none;
}
+ .vis-labelset .vis-label .vis-inner {
+ max-width: 250px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+
.timeline-timeline {
font-family: sans-serif !important;
@@ -224,6 +231,26 @@ export default {
alert('selected multiple items: ' + JSON.stringify(properties.items));
}
},
+ escapeHtml(str: string): string {
+ return str
+ .replace(/&/g, '&')
+ .replace(//g, '>')
+ .replace(/"/g, '"')
+ .replace(/'/g, ''');
+ },
+ abbreviateBucketName(bucketId: string): string {
+ // Abbreviate synced bucket names which can be extremely long (#682)
+ // e.g. "aw-watcher-window_host-synced-from-remotehost" -> "aw-watcher-window (synced from remotehost)"
+ const escaped = this.escapeHtml(bucketId);
+ const syncMatch = bucketId.match(/^([^_]+)_.*-synced-from-(.+)$/);
+ if (syncMatch) {
+ return `${this.escapeHtml(
+ syncMatch[1]
+ )} (synced from ${this.escapeHtml(syncMatch[2])})`;
+ }
+ return `${escaped}`;
+ },
ensureUpdate() {
// Will only run update() if data available and never ran before
if (!this.updateHasRun) {
@@ -248,7 +275,8 @@ export default {
);
}
}
- return { id: bucket.id, content: this.showRowLabels ? bucket.id : '' };
+ const label = this.showRowLabels ? this.abbreviateBucketName(bucket.id) : '';
+ return { id: bucket.id, content: label };
});
// Build items