azkaban-memoizeit
Changes
src/web/js/azkaban.schedule.svg.js 117(+93 -24)
Details
src/web/js/azkaban.schedule.svg.js 117(+93 -24)
diff --git a/src/web/js/azkaban.schedule.svg.js b/src/web/js/azkaban.schedule.svg.js
index a58700d..d272251 100644
--- a/src/web/js/azkaban.schedule.svg.js
+++ b/src/web/js/azkaban.schedule.svg.js
@@ -4,7 +4,8 @@ $(function() {
var border = 20;
var header = 30;
- var timeWidth = 60;
+ var minTimeWidth = 80;
+ var timeWidth = minTimeWidth;
var lineHeight = 40;
var numDays = 7;
var today = new Date();
@@ -21,8 +22,6 @@ $(function() {
$("#svgDivCustom").find("svg").eq(0).removeAttr("width");
- var dayWidth = Math.floor((totalWidth - 3 * border - timeWidth) / numDays);
-
//Outer g
var gMain = svg.group({transform: "translate(" + border + ".5," + border + ".5)", stroke : "#999", strokeWidth: 1});
@@ -30,22 +29,37 @@ $(function() {
today = new Date();
var svgDate = defaultDate;
+ //Load the date from the hash if existing
+ if(window.location.hash) {
+ try {
+ var dateParts = window.location.hash.replace("#", "").split("-");
+ var newDate = new Date(parseInt(dateParts[0]), parseInt(dateParts[1]) - 1, parseInt(dateParts[2]));
+ if(!isNaN(newDate)) {
+ svgDate = newDate;
+ }
+ }
+ catch(err){ }
+ }
+
//Used to filter projects or flows out
var filterProject = new Array();
var filterFlow = new Array();
$(".nav-prev-week").click(function (event) {
svgDate = new Date(svgDate.valueOf() - 7 * dayMillisConst);
+ window.location.hash = "#" + svgDate.getFullYear() + "-" + (svgDate.getMonth() + 1) + "-" + svgDate.getDate();
loadSvg(svgDate);
event.stopPropagation();
});
$(".nav-next-week").click(function (event) {
svgDate = new Date(svgDate.valueOf() + 7 * dayMillisConst);
+ window.location.hash = "#" + svgDate.getFullYear() + "-" + (svgDate.getMonth() + 1) + "-" + svgDate.getDate();
loadSvg(svgDate);
event.stopPropagation();
});
$(".nav-this-week").click(function (event) {
svgDate = defaultDate;
+ window.location.hash = "#" + svgDate.getFullYear() + "-" + (svgDate.getMonth() + 1) + "-" + svgDate.getDate();
loadSvg(svgDate);
event.stopPropagation();
});
@@ -56,10 +70,17 @@ $(function() {
function loadSvg(firstDay)
{
+ //Text to show which month/year it is
+ var monthIndicatorText = monthConst[firstDay.getMonth()] + " " + firstDay.getFullYear().toString();
+ //Measure a good width for the text to display well
+ timeWidth = Math.max(minTimeWidth, measureText(svg, monthIndicatorText, {fontSize: "20", style: "text-anchor: end;"}));
+
+ var dayWidth = Math.floor((totalWidth - 3 * border - timeWidth) / numDays);
+
//svg.configure({viewBox: "0 0 " + totalWidth + " " + totalHeight, style: "width:100%"}, true);
svg.remove(gMain);
gMain = svg.group({transform: "translate(" + border + ".5," + border + ".5)", stroke : "#999", strokeWidth: 1});
- svg.text(gMain, timeWidth, header - 8, monthConst[firstDay.getMonth()], {fontSize: "20", style: "text-anchor: end;", fill : "#F60", stroke : "none"});
+ svg.text(gMain, timeWidth, header - 8, monthIndicatorText, {fontSize: "20", style: "text-anchor: end;", fill : "#F60", stroke : "none"});
//time indicator group
var gLeft = svg.group(gMain, {transform: "translate(0," + header + ")"});
//Draw lines and hours
@@ -143,13 +164,16 @@ $(function() {
var data = itemByDay[deltaDay];
//Sort the arrays to have a better view
data.sort(function (a, b){
- if(a.length == dayMillisConst) return -1;
- if(b.length == dayMillisConst) return 1;
//Smaller time in front
var timeDiff = a.time - b.time;
if(timeDiff == 0) {
//Larger length in front
- return b.length - b.length;
+ var lengthDiff = b.length - a.length;
+ if(lengthDiff == 0) {
+ //Sort by alphabetical
+ return (a.flowname < b.flowname ? 1 : a.flowname > b.flowname ? -1 : 0);
+ }
+ return lengthDiff;
}
return timeDiff;
});
@@ -183,7 +207,7 @@ $(function() {
//Actually drawing them
for(var i = 0; i < columns.length; i++) {
//Split into columns
- var gColumn = svg.group(gDay, {transform: "translate(" + (i * dayWidth / columns.length) + ")", style: "opacity: 0.8"});
+ var gColumn = svg.group(gDay, {transform: "translate(" + Math.floor(i * dayWidth / columns.length) + ")", style: "opacity: 0.8"});
for(var j = 0; j < columns[i].length; j++) {
//Draw item
var item = columns[i][j];
@@ -208,6 +232,8 @@ $(function() {
//$(gItem).attr("style","color:red");
var rect = svg.rect(gItem, 0, 0, Math.ceil(dayWidth / columns.length), Math.floor(endY - startY), 0, 0, {fill : "#7E7", stroke : "#444", strokeWidth : 1});
+
+ item.rect = rect;
//Draw text
//svg.text(gItem, 6, 16, item.flowname, {fontSize: "13", fill : "#000", stroke : "none"});
}
@@ -242,27 +268,27 @@ $(function() {
if (period <= 0) {
// Single instance case
if (firstTime >= startTime && firstTime < endTime) {
- addItem({flowname : item.flowname, projectname: item.projectname, time: firstTime, length: item.length});
+ addItem({flowname : item.flowname, projectname: item.projectname, time: firstTime, length: item.length, item: item});
}
}
else {
if(period <= hourMillisConst) {
- addItem({flowname : item.flowname, projectname: item.projectname, time: firstTime, length: endTime - firstTime});
+ addItem({flowname : item.flowname, projectname: item.projectname, time: firstTime, length: endTime - firstTime, item: item});
}
else{
// Repetitive schedule, firstTime is assumed to be after startTime
while (firstTime < endTime) {
- addItem({flowname : item.flowname, projectname: item.projectname, time: firstTime, length: item.length});
+ addItem({flowname : item.flowname, projectname: item.projectname, time: firstTime, length: item.length, item: item});
firstTime += period;
}
}
}
}
- function addItem(item)
+ function addItem(obj)
{
- var itemStartTime = new Date(item.time);
- var itemEndTime = new Date(item.time + item.length);
+ var itemStartTime = new Date(obj.time);
+ var itemEndTime = new Date(obj.time + obj.length);
var itemStartDate = new Date(itemStartTime.getFullYear(), itemStartTime.getMonth(), itemStartTime.getDate());
var itemEndDate = new Date(itemEndTime.getFullYear(), itemEndTime.getMonth(), itemEndTime.getDate());
@@ -270,10 +296,20 @@ $(function() {
if(itemStartDate.valueOf() != itemEndDate.valueOf() && itemEndTime.valueOf() != itemStartDate + dayMillisConst)
{
var nextMorning = itemStartDate.valueOf() + dayMillisConst;
- var excess = item.length - (nextMorning - itemStartTime.valueOf());
- item.length = nextMorning - itemStartTime.valueOf();
- var item2 = {time: nextMorning, length: excess, projectname: item.projectname, flowname: item.flowname};
- addItem(item2);
+ var excess = obj.length - (nextMorning - itemStartTime.valueOf());
+ obj.length = nextMorning - itemStartTime.valueOf();
+ while(excess > 0)
+ {
+ var tempLength = excess;
+ if(tempLength > dayMillisConst){
+ tempLength = dayMillisConst;
+ }
+
+ var item2 = {time: nextMorning, length: tempLength, projectname: obj.projectname, flowname: obj.flowname, item: obj.item};
+ addItem(item2);
+ excess -= tempLength;
+ nextMorning += dayMillisConst;
+ }
}
//Now the item should be only in one day
@@ -281,7 +317,8 @@ $(function() {
if(index >= 0 && index < numDays)
{
//Add the item to the rendering list
- itemByDay[index].push(item);
+ itemByDay[index].push(obj);
+ obj.item.objs.push(obj);
}
}
@@ -304,22 +341,39 @@ $(function() {
function handleMouseOver(event) {
//Create the new tooltip
var requestURL = $(this).attr("href");
- var item = $(this).data("item");
+ var obj = $(this).data("item");
var offset = $("svg").offset();
var thisOffset = $(this).offset();
var tooltip = svg.group({transform: "translate(" + (thisOffset.left - offset.left + 2) + "," + (thisOffset.top - offset.top - 2) + ")"});
- var rect = svg.rect(tooltip, 0, -20, measureText(svg, item.flowname, {fontSize: "13"}) + 4, 20, {fill : "#FFF", stroke : "none"});
- svg.text(tooltip, 2, -5, item.flowname, {fontSize: "13", fill : "#000", stroke : "none"});
-
+ var text = [
+ "\"" + obj.flowname + "\" from \"" + obj.projectname + "\"",
+ "Repeat: " + formatReadablePeriod(obj.item.period)
+ ];
+ var textLength = Math.max(measureText(svg, text[0], {fontSize: "13"}), measureText(svg, text[1], {fontSize: "13"}));
+ var rect = svg.rect(tooltip, 0, -40, textLength + 4, 40, {fill : "#FFF", stroke : "none"});
+ svg.text(tooltip, 2, -25, text[0], {fontSize: "13", fill : "#000", stroke : "none"});
+ svg.text(tooltip, 2, -5, text[1], {fontSize: "13", fill : "#000", stroke : "none"});
+
+ //Item highlight effect
+ for(var i = 0; i < obj.item.objs.length; i++) {
+ var obj2 = obj.item.objs[i];
+ $(obj2.rect).attr("fill", "#F00");
+ }
//Store tooltip
$(this).data("tooltip", tooltip);
}
function handleMouseOut(event) {
+ //Item highlight effect
+ var obj = $(this).data("item");
+ for(var i = 0; i < obj.item.objs.length; i++) {
+ var obj2 = obj.item.objs[i];
+ $(obj2.rect).attr("fill", "#7E7");
+ }
//Clear the fade interval
- $($(this).data("tooltip")).fadeOut(750, function(){ svg.remove(this); });
+ $($(this).data("tooltip")).fadeOut(250, function(){ svg.remove(this); });
}
//Asynchronously load data
@@ -339,6 +393,7 @@ $(function() {
items[i].length = hourMillisConst; //TODO: parseInt(items[i].length);
items[i].time = parseInt(items[i].time);
items[i].period = parseInt(items[i].period);
+ items[i].objs = new Array();
processItem(items[i]);
}
//Trigger a re-rendering of all the data
@@ -378,4 +433,18 @@ $(function() {
svg.remove(test);
return width;
}
+
+ function formatReadablePeriod(period) {
+ var days = Math.floor(period / dayMillisConst);
+ var hour = period - days * dayMillisConst;
+ var hours = Math.floor(hour / hourMillisConst);
+ var min = hour - hours * hourMillisConst;
+ var mins = Math.floor(min / 60000);
+
+ var text = "";
+ if(days > 0) text = (days == 1 ? "24 hours" : days.toString() + " days");
+ if(hours > 0) text = text + " " + (hours == 1 ? "1 hour" : hours.toString() + " hours");
+ if(mins > 0) text = text + " " + (mins == 1 ? "1 minute" : mins.toString() + " minutes");
+ return text;
+ }
});
\ No newline at end of file