Skip to content

Commit 99dabd8

Browse files
[ui] Implement creating diffs from UI
1 parent 3132d0d commit 99dabd8

File tree

2 files changed

+58
-25
lines changed

2 files changed

+58
-25
lines changed

res/ui/index.html

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,12 @@
22
<head>
33
<meta charset="utf-8"/>
44
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
5-
<link rel="preconnect" href="https://fonts.googleapis.com">
6-
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
7-
<link href="https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap" rel="stylesheet">
85
<link rel='icon' href='favicon.png' type='image/x-icon'/>
96
<title>clj-async-profiler</title>
107
<style>
118
body {margin:1em auto; max-width:800px; background-color:#f9f9f9;}
129
img {margin:5px}
13-
body, table, input, select {color:#474747; font:0.9em/1.5 Inter, sans-serif;}
10+
body, table, input, select {color:#474747; font:0.9em/1.5 Verdana, sans-serif;}
1411
table, input, select {background-color:white;}
1512
tbody tr td {border-bottom:1px solid #ededed;}
1613
tbody tr:last-child td {border-bottom: none;}
@@ -21,23 +18,26 @@
2118
thead tr.heading {background-color:white;}
2219
tr.heading td {padding: 1px 10px; font-weight:500; color:black;}
2320
tr.heading {background-color:#F5F5F5}
24-
tr.data td {height:40px}
21+
tr.data td {height:35px}
2522
table th:first-child {border-radius:12px 0 0 0;}
2623
table th:last-child {border-radius:0 12px 0 0;}
27-
th:nth-child(1), td:nth-child(1) {/* max-width:15%; width:15%; */text-align:right;}
28-
/* th:nth-child(2), td:nth-child(2) {max-width:5%; width:5%;} */
29-
/* th:nth-child(6), td:nth-child(6) {max-width:10%; width:10%;} */
24+
th:nth-child(1), td:nth-child(1) {text-align:right;}
25+
th:nth-child(7), td:nth-child(7) {max-width:15%; width:15%; text-align:center;}
3026
a {text-decoration:none;}
3127
table {border-collapse: separate; width:100%; box-shadow: 0 8px 10px 0 rgba(0,0,0,0.2);
32-
border-spacing: 0; border-radius: 10px; border: 1px solid #ededed;
33-
}
28+
border-spacing: 0; border-radius: 10px; border: 1px solid #ededed;}
3429
.header {justify-content:space-between; margin-bottom:2em;}
3530
.flex-center {display:flex; align-items:center;}
3631
.controls {display:flex; justify-content:center; width:100%;}
37-
input[type=submit] {border: none; padding: 4px 10px; border-radius: 4px;
38-
box-shadow: 2px 2px 3px 0px rgba(0, 0, 0, 0.2);}
39-
select {border: 1px solid #878787; border-radius: 4px; accent-color: green;
40-
padding: 2px;}
32+
input[type=submit] {box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.25);}
33+
input[type=submit] {background-color:#e2e2e2;
34+
border: none; padding: 4px 10px; border-radius: 4px;
35+
box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.25);}
36+
select#event {border: 1px solid #878787; border-radius: 4px; accent-color: green;
37+
padding: 2px; min-width: 100px;}
38+
button.diff {background-color:inherit; color:inherit; border: 1px solid #8e8e8e;
39+
border-radius:4px; font-size: 0.8em; padding: 2px 6px;}
40+
button.diff.cancel {background-color:#ffa5a5;}
4141
</style>
4242
</head>
4343
<body>

src/clj_async_profiler/ui.clj

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,13 @@
1818
(defn- profiler-controls []
1919
(let [^String status-msg (core/status)]
2020
(if (.contains status-msg "is running")
21-
(format "<form action=\"/stop-profiler\">[%s] profiling is running&nbsp;
22-
<input type=\"submit\" value=\"Stop profiler\"/></form>"
21+
(format "<form action='/stop-profiler'>[%s] profiling is running&nbsp;
22+
<input type='submit' value='Stop profiler'/></form>"
2323
(name (@@#'core/start-options :event :cpu)))
24-
(format "<form action=\"/start-profiler\">Event:&nbsp;
25-
<select name=\"event\">%s</select>&nbsp;
26-
<input type=\"submit\" value=\"Start profiler\"/></form>"
24+
(format "<form action='/start-profiler'>
25+
<label for='event'>Event:</label>&nbsp;
26+
<select id='event' name='event'>%s</select>&nbsp;
27+
<input type='submit' value='Start profiler'/></form>"
2728
(forj [ev (remove #{:ClassName.methodName}
2829
(core/list-event-types {:silent? true}))]
2930
(format "<option value=%s>%s</option>" (name ev) (name ev)))))))
@@ -46,16 +47,21 @@
4647
(defn- format-size [sz samples]
4748
(let [sz (if (< sz 1024) (str sz " b") (format "%.1f Kb" (/ sz 1024.0)))
4849
samples (cond (nil? samples) nil
49-
(< samples 1000) (str "<br>" samples " samples")
50-
:else (format "<br>%.1fk samples" (/ samples 1e3)))]
51-
(cond-> sz samples (str samples))))
50+
(< samples 1000) (str samples " samples")
51+
:else (format "%.1fk samples" (/ samples 1e3)))]
52+
(or samples sz)))
53+
54+
(defn- resolve-stacks-file [short-name]
55+
(when-let [^File f (some->> short-name (io/file results/root-directory "results"))]
56+
(when (.exists f) f)))
5257

5358
(defn- file-table [root files]
5459
(let [files (sort-by #(.lastModified ^File %) > files) ;; Newer on top
5560
parsed-files (for [^File f files
5661
:let [info (results/parse-results-filename (.getName f))]]
5762
[f (update info :date #(or % (Date. (.lastModified f))))])
58-
grouped (group-by #(date->local-date (:date (second %))) parsed-files)]
63+
grouped (group-by #(date->local-date (:date (second %))) parsed-files)
64+
diff-from-file (resolve-stacks-file (@ui-state :diff-from))]
5965
(format
6066
"<table><thead>%s</thead><tbody>%s</tbody></table>"
6167
(row :th "heading"
@@ -86,7 +92,20 @@
8692
id2)
8793
stacks (format "<a href='%s'>raw</a>"
8894
(str root (.getName stacks))))
89-
"")))))))
95+
(if diff-from-file
96+
(cond (= diff-from-file stacks)
97+
"<button class='diff cancel' onclick=\"window.location.href='/cancel-diff'\">Cancel</button>"
98+
stacks
99+
(format "<button class='diff' onclick=\"window.location.href='/finish-diff?to=%s'\">...to this</button>"
100+
(.getName stacks)))
101+
(when stacks
102+
(format "<button class='diff' onclick=\"window.location.href='/start-diff?from=%s'\">Diff to...</button>"
103+
(.getName stacks)))))))))))
104+
105+
(defn- generate-diff [to-file-short-name]
106+
(let [from-file (resolve-stacks-file (@ui-state :diff-from))
107+
to-file (resolve-stacks-file to-file-short-name)]
108+
(core/generate-diffgraph from-file to-file {})))
90109

91110
(defn- main-page [root files]
92111
(->> {:profiler-controls (profiler-controls)
@@ -110,8 +129,22 @@
110129
(do (core/clear-results)
111130
(redirect "/"))
112131

132+
(= path "/start-diff")
133+
(do (swap! ui-state assoc :diff-from (params "from"))
134+
(redirect "/"))
135+
136+
(= path "/finish-diff")
137+
(do (generate-diff (params "to"))
138+
(swap! ui-state dissoc :diff-from)
139+
(redirect "/"))
140+
141+
(= path "/cancel-diff")
142+
(do (swap! ui-state dissoc :diff-from)
143+
(redirect "/"))
144+
113145
(= path "/")
114-
{:body (main-page path files)}
146+
(let [files (filter #(= (wwws/get-extension (str %)) "html") files)]
147+
{:body (main-page path files)})
115148

116149
(= path "/favicon.png")
117150
{:body (io/resource "favicon.png")

0 commit comments

Comments
 (0)