Skip to content

Commit 8a3a6a9

Browse files
committed
chore: improve plugin flamegraph hover node UI
1 parent 713033a commit 8a3a6a9

1 file changed

Lines changed: 47 additions & 39 deletions

File tree

packages/devtools-vite/src/app/components/chart/PluginFlamegraph.vue

Lines changed: 47 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
import type { TreeNodeInput } from 'nanovis'
33
import type { PluginBuildInfo, RolldownPluginBuildMetrics, SessionContext } from '~~/shared/types'
44
import { Flamegraph, normalizeTreeNode } from 'nanovis'
5-
import { relative } from 'pathe'
65
import { computed, onMounted, onUnmounted, ref, shallowRef, useTemplateRef, watch } from 'vue'
76
import { parseReadablePath } from '~/utils/filepath'
87
import { normalizeTimestamp } from '~/utils/format'
@@ -26,51 +25,41 @@ const moduleTypes = computed(() => ModuleTypeRules.filter(rule => parsedPaths.va
2625
2726
const n = (node: TreeNodeInput<PluginBuildInfo>) => normalizeTreeNode(node, undefined, false)
2827
29-
function normalizeModulePath(path: string) {
30-
const normalized = path.replace(/%2F/g, '/')
31-
const cwd = props.session!.meta.cwd
32-
let relate = cwd ? relative(cwd, normalized) : normalized
33-
if (!relate.startsWith('.'))
34-
relate = `./${relate}`
35-
if (relate.startsWith('./'))
36-
return relate
37-
if (relate.match(/^(?:\.\.\/){1,3}[^.]/))
38-
return relate
39-
return normalized
40-
}
41-
4228
const tree = computed(() => {
4329
const resolveIds = moduleTypes.value.map((type, idx) => n({
4430
id: `resolveId-${type.name}-${idx}`,
4531
text: type.description,
4632
children: props.buildMetrics.resolveIdMetrics.filter((item) => {
4733
return getFileTypeFromModuleId(item.module).name === type.name
48-
}).map((id, idx) => n({
34+
}).map((item, idx) => n({
4935
id: `resolveId-${idx}`,
50-
text: normalizeModulePath(id.module),
51-
size: id.duration,
36+
text: item.module,
37+
size: item.duration,
38+
meta: item,
5239
})),
5340
}))
5441
const loads = moduleTypes.value.map((type, idx) => n({
5542
id: `loads-${type.name}-${idx}`,
5643
text: type.description,
5744
children: props.buildMetrics.loadMetrics.filter((item) => {
5845
return getFileTypeFromModuleId(item.module).name === type.name
59-
}).map((id, idx) => n({
46+
}).map((item, idx) => n({
6047
id: `resolveId-${idx}`,
61-
text: normalizeModulePath(id.module),
62-
size: id.duration,
48+
text: item.module,
49+
size: item.duration,
50+
meta: item,
6351
})),
6452
}))
6553
const transforms = moduleTypes.value.map((type, idx) => n({
6654
id: `transforms-${type.name}-${idx}`,
6755
text: type.description,
6856
children: props.buildMetrics.transformMetrics.filter((item) => {
6957
return getFileTypeFromModuleId(item.module).name === type.name
70-
}).map((id, idx) => n({
58+
}).map((item, idx) => n({
7159
id: `resolveId-${idx}`,
72-
text: normalizeModulePath(id.module),
73-
size: id.duration,
60+
text: item.module,
61+
size: item.duration,
62+
meta: item,
7463
})),
7564
}))
7665
@@ -101,7 +90,7 @@ const tree = computed(() => {
10190
})
10291
10392
const hoverNode = ref<{
104-
plugin_name: string
93+
title: string
10594
duration: number
10695
meta: PluginBuildInfo | undefined
10796
} | null>(null)
@@ -133,7 +122,7 @@ function buildFlamegraph() {
133122
hoverY.value = e.clientY
134123
}
135124
hoverNode.value = {
136-
plugin_name: node.text!,
125+
title: node.text!,
137126
duration: node.size,
138127
meta: node.meta,
139128
}
@@ -167,26 +156,45 @@ watch(tree, async () => {
167156
<Teleport to="body">
168157
<div
169158
v-if="hoverNode"
170-
border="~ base" rounded shadow px2 py1 fixed
171-
z-panel-content bg-glass pointer-events-none text-sm
159+
border="~ base" rounded-lg shadow-lg px3 py2 fixed
160+
z-panel-content bg-glass pointer-events-none text-sm max-w-80
172161
:style="{ left: `${hoverX}px`, top: `${hoverY}px` }"
173162
>
174-
<div flex="~" font-bold font-mono>
175-
<DisplayFileIcon v-if="hoverNode.meta" :filename="hoverNode.meta.module" mr1.5 />
176-
{{ hoverNode.plugin_name }}
163+
<div v-if="hoverNode.meta?.module" flex="~" font-semibold font-mono text-base mb2>
164+
<DisplayModuleId :id="hoverNode.meta.module" :session="session" :link="false" />
177165
</div>
178-
<div v-if="hoverNode.meta">
179-
<div>
180-
<label>Start Time: </label>
181-
<time :datetime="new Date(hoverNode.meta.timestamp_start).toISOString()">{{ normalizeTimestamp(hoverNode.meta.timestamp_start) }}</time>
166+
<div v-else font-semibold text-base mb2>
167+
{{ hoverNode.title }}
168+
</div>
169+
<div v-if="hoverNode.meta?.module" border="t base" pt2 flex="~ col gap-1.5" min-w-48>
170+
<div flex="~ justify-between items-center" py1>
171+
<label text-xs opacity-70>Start Time</label>
172+
<time
173+
:datetime="new Date(hoverNode.meta.timestamp_start).toISOString()"
174+
font-mono text="xs"
175+
bg="base/10"
176+
px1.5 py0.5 rounded
177+
>
178+
{{ normalizeTimestamp(hoverNode.meta.timestamp_start) }}
179+
</time>
180+
</div>
181+
<div flex="~ justify-between items-center" py1>
182+
<label text-xs opacity-70>End Time</label>
183+
<time
184+
:datetime="new Date(hoverNode.meta.timestamp_end).toISOString()"
185+
font-mono text="xs"
186+
bg="base/10"
187+
px1.5 py0.5 rounded
188+
>
189+
{{ normalizeTimestamp(hoverNode.meta.timestamp_end) }}
190+
</time>
182191
</div>
183-
<div>
184-
<label>End Time: </label>
185-
<time :datetime="new Date(hoverNode.meta.timestamp_end).toISOString()">{{ normalizeTimestamp(hoverNode.meta.timestamp_end) }}</time>
192+
<div flex="~ justify-between items-center" py1 border="t base dashed" pt2>
193+
<label text="xs" op70>Duration</label>
194+
<DisplayDuration :duration="hoverNode.duration" />
186195
</div>
187196
</div>
188-
<div flex="~ gap-1">
189-
<label>Duration: </label>
197+
<div v-else>
190198
<DisplayDuration :duration="hoverNode.duration" />
191199
</div>
192200
</div>

0 commit comments

Comments
 (0)