blob: 99f0b8839a430c62a923df20bc869b90043d05eb [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
app.SwimlaneView = Backbone.Marionette.LayoutView.extend({
"template": "#swimlane-layout-template",
"regions": {
"swimlane": "div[role='main']",
}
});
app.SwimlaneGraphView = Backbone.Marionette.View.extend({
className: "swimlane",
initialize: function() {
this.spans = this.getSpans(0, [],
this.getJsonSync("/span/" + this.options.spanId),
this.options.lim || "lim=100",
this.getJsonSync);
},
onShow: function() {
this.appendSVG(this.spans);
},
getSpans: function getSpans(depth, spans, span, lim, getJSON) {
span.depth = depth;
spans.push(span);
var children = [];
getJSON("/span/" + span.s + "/children?" + lim).forEach(function(childId) {
children.push(getJSON("/span/" + childId));
});
children.sort(function(x, y) {
return x.b < y.b ? -1 : x.b > y.b ? 1 : 0;
});
children.forEach(function(child) {
spans = getSpans(depth + 1, spans, child, lim, getJSON);
});
return spans;
},
getJsonSync: function getJsonSync(url) {
return $.ajax({
type: "GET",
url: url,
async: false,
dataType: "json"
}).responseJSON;
},
appendSVG: function appendSVG(spans) {
const height_span = 20;
const width_span = 700;
const size_tl = 6;
const margin = {top: 50, bottom: 50, left: 20, right: 1000, process: 300};
var height_screen = spans.length * height_span;
var dmax = d3.max(spans, function(s) { return s.depth; });
var tmin = d3.min(spans, function(s) { return s.b; });
var tmax = d3.max(spans, function(s) { return s.e; });
var xscale = d3.time.scale()
.domain([new Date(tmin), new Date(tmax)]).range([0, width_span]);
var svg = d3.select("div[role='main']").append("svg")
.attr("id", "svg-swimlane")
.attr("width", width_span + margin.process + margin.left + margin.right)
.attr("height", height_screen + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var bars = svg.append("g")
.attr("id", "bars")
.attr("width", width_span)
.attr("height", height_screen)
.attr("transform", "translate(" + (10 * dmax + margin.process) + ", 0)");
var axis = d3.svg.axis()
.scale(xscale)
.orient("top")
.tickValues(xscale.domain())
.tickFormat(d3.time.format("%x %X.%L"))
.tickSize(6, 3);
bars.append("g").attr("class", "axis").call(axis);
var span_g = bars.selectAll("g.span")
.data(spans)
.enter()
.append("g")
.attr("transform", function(s, i) {
return "translate(0, " + (i * height_span + 5) + ")";
})
.classed("timeline", function(d) { return d.t; });
span_g.append("text")
.text(function(s) { return s.r; })
.style("alignment-baseline", "hanging")
.style("font-size", "14px")
.attr("transform", function(s) {
return "translate(" + (s.depth * 10 - margin.process - 10 * dmax) + ", 0)";
});
var rect_g = span_g.append("g")
.attr("transform", function(s) {
return "translate(" + xscale(new Date(s.b)) + ", 0)";
});
rect_g.append("rect")
.attr("height", height_span - 1)
.attr("width", function (s) {
return (width_span * (s.e - s.b)) / (tmax - tmin) + 1;
})
.style("fill", "lightblue")
.attr("class", "span")
rect_g.append("text")
.text(function(s){ return s.d; })
.style("alignment-baseline", "hanging")
.style("font-size", "14px");
rect_g.append("text")
.text(function(s){ return s.e - s.b; })
.style("alignment-baseline", "baseline")
.style("text-anchor", "end")
.style("font-size", "10px")
.attr("transform", function(s, i) { return "translate(0, 10)"; });
bars.selectAll("g.timeline").selectAll("rect.timeline")
.data(function(s) { return s.t; })
.enter()
.append("rect")
.style("fill", "red")
.attr("class", "timeline")
.attr("height", size_tl)
.attr("width", size_tl)
.attr("transform", function(t) {
return "translate(" + xscale(t.t) + "," + (height_span - 1 - size_tl) + ")";
});
var popup = d3.select("div[role='main']").append("div")
.attr("class", "popup")
.style("opacity", 0);
bars.selectAll("g.timeline")
.on("mouseover", function(d) {
popup.transition().duration(300).style("opacity", .95);
var text = "<table>";
d.t.forEach(function (t) {
text += "<tr><td>" + (t.t - tmin) + "</td>";
text += "<td> : " + t.m + "</td></tr>";
});
text += "</table>"
popup.html(text)
.style("left", (document.body.scrollLeft + 50) + "px")
.style("top", (document.body.scrollTop + 70) + "px")
.style("width", "700px")
.style("background", "orange")
.style("position", "absolute");
})
.on("mouseout", function(d) {
popup.transition().duration(300).style("opacity", 0);
});
}
});