Skip to content

Commit

Permalink
Add timeline view for events
Browse files Browse the repository at this point in the history
Signed-off-by: Robin Appelman <robin@icewind.nl>
  • Loading branch information
icewind1991 authored and CarlSchwan committed May 4, 2022
1 parent bf555c3 commit a271a73
Show file tree
Hide file tree
Showing 2 changed files with 147 additions and 0 deletions.
84 changes: 84 additions & 0 deletions src/components/TimelineNode.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<!--
SPDX-FileCopyrightText: 2022 Robin Appelman <robin@icewind.nl>

SPDX-License-Identifier: AGPL-3.0-or-later
-->

<template>
<div class="node-group">
<div class="node" :title="`${event.id} - ${event.description} ${duration}ms`">
{{ event.id }} - {{ event.description }} {{ duration }}ms
</div>
<div v-if="children.length > 0" class="children">
<div v-for="(event) in children"
:key="event.id"
:style="event.style"
class="child">
<TimelineNode :event="event" />
</div>
</div>
</div>
</template>

<script>
export default {
name: 'TimelineNode',
props: {
event: {
type: Object,
required: true,
},
},
computed: {
children() {
return this.event.children.map(child => {
const startRelative = (child.start - this.event.start) / this.event.duration
const durationRelative = child.duration / this.event.duration
child.style = `left: ${startRelative * 100}%; width: ${durationRelative * 100}%`
return child
})
},
duration() {
return (this.event.duration * 1000).toFixed(1)
},
},
}
</script>

<style lang="scss" scoped>
div.node-group {
position: relative;
display: inline-block;
vertical-align: top;
width: 100%;
overflow-x: hidden;
margin: 0;
}

div.node, div.children {
display: inline-block;
vertical-align: top;
width: 100%;
position: relative;
margin: 0;
}

div.node {
background-color: #00000044;
padding: 0 2px;
white-space: nowrap;
}

div.child {
position: relative;
display: inline-block;
vertical-align: top;
top: 0;
overflow-x: hidden;
margin: 0;
}

span.duration {
float: right;
}
</style>
63 changes: 63 additions & 0 deletions src/views/EventsView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-or-later
<template>
<div>
<h2>Events</h2>
<TimelineNode :event="eventTree" />
<div style="overflow-x:auto;">
<table>
<thead>
Expand Down Expand Up @@ -43,13 +44,75 @@ SPDX-License-Identifier: AGPL-3.0-or-later

<script>
import { mapState } from 'vuex'
import TimelineNode from '../components/TimelineNode'

export default {
name: 'EventsView',
components: {
TimelineNode,
},
computed: {
events() {
return this.profiles[this.$route.params.token]?.collectors.event
},
eventTree() {
if (!this.profiles[this.$route.params.token]?.collectors.event) {
return {
id: 'root',
duration: 0,
start: 0,
stop: 0,
description: '',
children: [],
}
}
const runtimeStop = this.events.runtime.stop
const events = Object.values(this.events)
events.forEach(event => {
if (!event.stop) {
event.stop = runtimeStop
}
})
events.sort((a, b) => {
if (a.start < b.start) {
return -1
} else if (a.start > b.start) {
return 1
} else {
// if 2 events have the same start, the one that ends last should be sorted first as it is the parent
return b.stop - a.stop
}
})
const startTime = events[0].start
const stopTime = Math.max(...events.map(event => event.stop))
let current = {
id: 'root',
duration: stopTime - startTime,
start: 0,
stop: stopTime - startTime,
children: [],
}
const stack = [current]

for (let event of events) {
event = {
id: event.id,
duration: event.duration,
start: event.start - startTime,
stop: event.stop - startTime,
description: event.description,
children: [],
}
while (event.stop > current.stop) {
current = stack.pop()
}

current.children.push(event)
stack.push(current)
current = event
}
return stack[0]
},
...mapState(['profiles']),
},
}
Expand Down

0 comments on commit a271a73

Please sign in to comment.