Skip to content

Commit 7fac1eb

Browse files
Pradyumn ShroffPradyumn Shroff
authored andcommitted
added more features (see GitHub comments)
1 parent a4d5207 commit 7fac1eb

File tree

2 files changed

+85
-17
lines changed

2 files changed

+85
-17
lines changed
Lines changed: 84 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,118 @@
11
function renderJobsGraphs(data) {
2+
/* show visualization toggle */
23
$(".expand-visualization-arrow").toggleClass('arrow-closed');
34
$(".expand-visualization-arrow").toggleClass('arrow-open');
45
if ($(".expand-visualization-arrow").hasClass("arrow-closed")) {
56
$("#chartContainer").empty();
67
return;
78
}
9+
10+
/* no data to graph */
11+
if (!Object.keys(data).length) {
12+
return;
13+
}
14+
15+
/* format data to a form readable by dimple.js */
816
var tableData = [];
917
for (var k in data) {
1018
var arr = (data[k]).split(",");
1119
data[k] = arr;
1220
}
13-
var startTime = getMin(data["Launch Time"]);
14-
var numTasks = data[k].length;
21+
var startTime = getMin(data["launchtime"]);
22+
var numTasks = Math.min(1000, data[k].length);
23+
24+
/*data update */
25+
data["launchtime"] = data["launchtime"].map(function (launchTime) {return launchTime-startTime;});
1526
var maxTime = 0;
16-
data["Launch Time"] = data["Launch Time"].map(function (launchTime) {return launchTime-startTime;});
17-
for (i = 0; i < data[k].length; i++) {
27+
for (i = 0; i < numTasks; i++) {
1828
var time = 0;
29+
for (var key in data) {
30+
time += parseFloat(data[key][i]);
31+
}
32+
maxTime = Math.max(time, maxTime);
33+
}
34+
divisorAndTitle = getDivisiorAndTitle(maxTime);
35+
for (i = 0; i < numTasks; i++) {
1936
for (var key in data) {
2037
job = {};
21-
job["Task #"] = i+1;
38+
job["Task #"] = i;
2239
job["Task"] = key;
23-
job["Time"] = parseFloat(data[key][i]);
24-
time += job["Time"];
40+
job["Time"] = parseFloat(data[key][i])/divisorAndTitle[0];
2541
tableData.push(job);
2642
}
27-
maxTime = Math.max(time, maxTime);
2843
}
29-
console.log(JSON.stringify(tableData));
30-
var height = Math.min(numTasks * 100, 2000);
31-
var width = Math.min(maxTime * 2.5, 2000);
44+
45+
var height = Math.max(Math.min(numTasks * 50, 2000), 200);
3246
var svg = dimple.newSvg("#chartContainer", "100%", height);
3347
var chart = new dimple.chart(svg);
34-
chart.setBounds("5%","20%","90%","60%");
48+
chart.setMargins(60, 60, 60, 60);
49+
3550
var x = chart.addMeasureAxis("x", "Time");
36-
var y = chart.addCategoryAxis("y", "Task #");
37-
x.title = "Time (ms)";
3851
x.fontSize = "12px";
52+
x.title = divisorAndTitle[1];
53+
54+
var y = chart.addCategoryAxis("y", "Task #");
3955
y.fontSize = "12px";
56+
4057
var s = chart.addSeries("Task", dimple.plot.bar);
4158
s.data = tableData;
42-
s.addOrderRule(["Launch Time", "Scheduler Delay", "Task Deserialization Time", "Duration", "Result Serialization Time", "Getting Result Time", "GC Time"]);
43-
chart.addLegend("20%", "10%", "80%", "20%", "right");
59+
s.addOrderRule(getOrderRule());
60+
61+
s.getTooltipText = function (dat) {
62+
return ["Task #: " + dat["yField"][0],
63+
"Phase: " + dat["aggField"][0],
64+
"Time (ms): " + dat["xValue"]*divisorAndTitle[0]
65+
];
66+
};
67+
68+
chart.addLegend(20, 10, 1000, 40, "right");
4469
(chart.legends[0]).fontSize = "12px";
70+
4571
chart.draw();
72+
svg.selectAll(".dimple-launchtime").remove();
73+
numTicks(y, Math.floor(numTasks/20));
4674
}
4775

4876
function getMin(arr) {
4977
return Math.min.apply(null, arr);
78+
}
79+
80+
function getOrderRule() {
81+
return ["launchtime", "Scheduler Delay", "Task Deserialization Time",
82+
"Duration", "Result Serialization Time", "Getting Result Time", "GC Time"];
83+
}
84+
85+
function getDivisiorAndTitle(maxTime) {
86+
var sec = 1000;
87+
var min = sec * 60;
88+
var hr = min * 60;
89+
if (maxTime >= hr) {
90+
return [hr, "Time (hr)"];
91+
} else if (maxTime >= min) {
92+
return [min, "Time (min)"];
93+
} else if (maxTime >= sec) {
94+
return [sec, "Time (s)"];
95+
} else {
96+
return [1, "Time (ms)"];
97+
}
98+
}
99+
100+
/* limits the number of ticks in the Y-axis to oneInEvery */
101+
function numTicks(axis, oneInEvery) {
102+
if (axis.shapes.length > 0) {
103+
var del = 0;
104+
if (oneInEvery > 1) {
105+
axis.shapes.selectAll("text").each(function (d) {
106+
if (del % oneInEvery !== 0) {
107+
this.remove();
108+
axis.shapes.selectAll("line").each(function (d2) {
109+
if (d === d2) {
110+
this.remove();
111+
}
112+
});
113+
}
114+
del += 1;
115+
});
116+
}
117+
}
50118
}

core/src/main/scala/org/apache/spark/ui/jobs/StagePage.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ private[ui] class StagePage(parent: StagesTab) extends WebUIPage("stage") {
299299
val launchTimes = validTasks.map { case TaskUIData(info, metrics, _) =>
300300
info.launchTime
301301
}
302-
graphData("Launch Time") = launchTimes.mkString(",")
302+
graphData("launchtime") = launchTimes.mkString(",")
303303

304304
val durations = validTasks.map { case TaskUIData(info, metrics, _) => if (info.status == "RUNNING")
305305
info.timeRunning(System.currentTimeMillis()) else metrics.map(_.executorRunTime).getOrElse(1L)

0 commit comments

Comments
 (0)