738 lines
21 KiB
JavaScript
Executable File
738 lines
21 KiB
JavaScript
Executable File
// TODO - most code copied from map-telemetry, need to move them to a separate module
|
|
// Array that stores objects for each element returned via rest
|
|
var restEndpoint = config.mapExportsBySection,
|
|
restEndpointAsync = config.mapExportsBySectionAsync,
|
|
restEndpoint2 = config.mapExportsSectionAge,
|
|
restEndpoint2Async = config.mapExportsSectionAgeAsync,
|
|
sectionsVectorData, // to store the section vector data
|
|
exportsStats, // to store the map export raw returned data
|
|
sectionExportAge;
|
|
|
|
var vBoxWidth = 1200,
|
|
vBoxHeight = 900,
|
|
bgWidth = 900,
|
|
bgHeight = 1500,
|
|
clicked;
|
|
|
|
//var defaultFilterText = "type text to filter the sections",
|
|
defaultFilterText = "",
|
|
sectionsMapId = "sections-overlay",
|
|
propsSuffix = "_PROPS";
|
|
|
|
var sectionTypes = [{name: "Main Sections", value: "main"},
|
|
{name: "Props Sections", value: "props"}],
|
|
statTypes = ["Average", "Min", "Max"];
|
|
|
|
var optionCalculations = { // create an associative array - use as hashtable
|
|
"OverallTime": {
|
|
hasTypes: true,
|
|
calcValue: function(d, statType) {
|
|
var value;
|
|
|
|
if (statType == statTypes[1]) {
|
|
//value = d.MinTotalTime;
|
|
value = 0;
|
|
}
|
|
else if (statType == statTypes[2]) {
|
|
value = d.MaxTotalTime;
|
|
}
|
|
else {
|
|
value = d.AvgTotalTime;
|
|
}
|
|
|
|
return (value) ? value : 0;
|
|
},
|
|
units: " secs",
|
|
reversedColours: true,
|
|
},
|
|
"ExportTime": {
|
|
hasTypes: true,
|
|
calcValue: function(d, statType) {
|
|
var value;
|
|
|
|
if (statType == statTypes[1]) {
|
|
//value = d.MinSectionExportTime;
|
|
value = 0;
|
|
}
|
|
else if (statType == statTypes[2]) {
|
|
value = d.MaxSectionExportTime;
|
|
}
|
|
else {
|
|
value = d.AvgSectionExportTime;
|
|
}
|
|
|
|
return (value) ? value : 0;
|
|
},
|
|
units: " secs",
|
|
reversedColours: true,
|
|
},
|
|
"ExportCount": {
|
|
hasTypes: false,
|
|
calcValue: function(d, s) {
|
|
return d.SectionExportCount;
|
|
},
|
|
units: " times exported",
|
|
reversedColours: true,
|
|
},
|
|
"ExportSuccessRatio": {
|
|
hasTypes: false,
|
|
calcValue: function(d, s) {
|
|
return (d.SectionExportCount) ? (d.SectionExportSuccessCount / d.SectionExportCount) : 0;
|
|
},
|
|
units: " success ratio",
|
|
reversedColours: false
|
|
},
|
|
"BuildTime": {
|
|
hasTypes: true,
|
|
calcValue: function(d, statType) {
|
|
var value;
|
|
|
|
if (statType == statTypes[1]) {
|
|
//value = d.MinBuildTime;
|
|
value = 0;
|
|
}
|
|
else if (statType == statTypes[2]) {
|
|
value = d.MaxBuildTime;
|
|
}
|
|
else {
|
|
value = d.AvgBuildTime;
|
|
}
|
|
|
|
return (value) ? value : 0;
|
|
},
|
|
units: " secs",
|
|
reversedColours: true,
|
|
},
|
|
"BuildCount": {
|
|
hasTypes: false,
|
|
calcValue: function(d, s) {
|
|
return d.BuildCount;
|
|
},
|
|
units: " times built",
|
|
reversedColours: true,
|
|
},
|
|
"BuildSuccessRatio": {
|
|
hasTypes: false,
|
|
calcValue: function(d, s) {
|
|
return (d.BuildCount) ? (d.BuildSuccessCount / d.BuildCount) : 0;
|
|
},
|
|
units: " success ratio",
|
|
reversedColours: false,
|
|
},
|
|
"LastExport": {
|
|
hasTypes: false,
|
|
calcValue: function(d, s) {
|
|
return datesDiffInSecs(new Date(), parseJsonDate(d.MostRecentExport));
|
|
},
|
|
units: " secs",
|
|
reversedColours: true,
|
|
isSectionAgeStat: true,
|
|
},
|
|
|
|
};
|
|
|
|
//set true for disabled filter
|
|
var headerAndFilters = {
|
|
headerType: "header-map-exports", // social club filtering header
|
|
disabledFields: [ // disabled header fields
|
|
false, // section
|
|
false, // user
|
|
false, // dates
|
|
],
|
|
};
|
|
|
|
function convert2WebXCoord(x) {
|
|
return ((x + project.map.coords.x)/project.map.scale);
|
|
}
|
|
function convert2WebYCoord(y) {
|
|
return (((-1)*y + project.map.coords.y)/project.map.scale);
|
|
}
|
|
|
|
function convert2WebCoords(p) {
|
|
return [convert2WebXCoord(p[0]), convert2WebYCoord(p[1])];
|
|
}
|
|
|
|
function updateMapHeight() {
|
|
// Adjust the height of the map automatically
|
|
var windowHeight = $("#content").height() - 30;
|
|
$("#map-wrapper").css("height", windowHeight);
|
|
}
|
|
|
|
function initPage() {
|
|
// function from generic.js, variable from config file
|
|
initHeaderAndFilters(headerAndFilters);
|
|
|
|
if (!$("#section").val())
|
|
$("#section").val(defaultFilterText);
|
|
$("#section").focus(function() {
|
|
if($(this).val() == defaultFilterText)
|
|
$(this).val("");
|
|
});
|
|
$("#section").blur(function() {
|
|
if($(this).val() == "")
|
|
$(this).val(defaultFilterText);
|
|
});
|
|
/*
|
|
$("#section").change(function() {
|
|
if (exportsStats)
|
|
generateOverlays();
|
|
});
|
|
*/
|
|
$("#section").keyup(function() {
|
|
if (exportsStats)
|
|
generateOverlays();
|
|
});
|
|
|
|
/* Generate the html here */
|
|
|
|
|
|
/* End of html generation */
|
|
//block();
|
|
$.ajax({
|
|
url: project.map.svgFile,
|
|
type: "GET",
|
|
data: {},
|
|
dataType: "xml",
|
|
async: false,
|
|
success: function(xml, textStatus, jqXHR) {
|
|
var importedNode;
|
|
try {
|
|
importedNode = document.importNode(xml.documentElement, true);
|
|
}
|
|
catch(e) {
|
|
// IE case
|
|
importedNode = ieImportNode(xml.documentElement, document);
|
|
}
|
|
|
|
$("#map").append(importedNode);
|
|
},
|
|
error: function (xhr, ajaxOptions, thrownError){
|
|
console.error(this.url + "\n" + ajaxOptions + " " + xhr.status + " " + thrownError );
|
|
},
|
|
complete: function() {
|
|
var svg = d3.select("#map svg")
|
|
.attr("width", $("#map").width())
|
|
.attr("height", $("#map").height())
|
|
.attr("enable-background", "new 0 0 " + bgWidth + " "+ bgHeight)
|
|
.call(svg_interact);
|
|
|
|
drawGrid();
|
|
|
|
svg.append("svg:g")
|
|
.attr("id", sectionsMapId);
|
|
}
|
|
});
|
|
|
|
$.ajax({
|
|
url: project.map.vectorsFile,
|
|
type: "GET",
|
|
data: {},
|
|
dataType: "xml",
|
|
async: false,
|
|
success: function(xml, textStatus, jqXHR) {
|
|
sectionsVectorData = parseSectionsVectorXml(xml);
|
|
},
|
|
error: function (xhr, ajaxOptions, thrownError){
|
|
console.error(this.url + "\n" + ajaxOptions + " " + xhr.status + " " + thrownError );
|
|
},
|
|
complete: function() {}
|
|
});
|
|
|
|
//unBlock();
|
|
|
|
|
|
// Activate the map layer show/hide checkboxes
|
|
$("#map-layers input[type=checkbox]").click(function() {
|
|
var layer = d3.select("#map svg").select("g#" + $(this).val());
|
|
|
|
var currentLayerId = $(this).val();
|
|
if ($(this).is(":checked")) {
|
|
layer
|
|
.transition()
|
|
.style("opacity", 1);
|
|
}
|
|
else {
|
|
layer
|
|
.transition()
|
|
.style("opacity", 0.01);
|
|
}
|
|
});
|
|
|
|
$("#overlay-options input[name=section-type-radio]:radio").change(function() {
|
|
generateOverlays();
|
|
});
|
|
$("#overlay-options input[name=calc-type-radio]:radio").change(function() {
|
|
generateOverlays();
|
|
});
|
|
$("#overlay-options input[name=stat-type-radio]:radio").change(function() {
|
|
generateOverlays();
|
|
});
|
|
|
|
/* Initialise the heatmap gradient and sliders*/
|
|
|
|
var defaultMinHue = 0,
|
|
defaultMaxHue = 240,
|
|
defaultMinHueSlider = 0,
|
|
defaultMaxHueSlider = 120;
|
|
|
|
$("#overlay-options div.heatmap-slider-placeholder").slider({
|
|
range: true,
|
|
min: defaultMinHue,
|
|
max: defaultMaxHue,
|
|
values: [defaultMinHueSlider, defaultMaxHueSlider],
|
|
stop: function(event, ui ) { // fire when mouse is released
|
|
//generateHeatmapGradient("overlay-options span.heatmap-gradient",
|
|
// ui.values[0], ui.values[1]);
|
|
generateOverlays();
|
|
}
|
|
});
|
|
|
|
$("#overlay-options div.value-slider").slider({
|
|
range: true,
|
|
min: 0,
|
|
max: 0,
|
|
values: [0, 0],
|
|
stop: function(event, ui ) { // fire when mouse is released
|
|
generateOverlays()
|
|
}
|
|
});
|
|
|
|
$("#overlay-options div.threshold-slider").slider({
|
|
min: 0,
|
|
max: 0,
|
|
value: 0,
|
|
stop: function(event, ui ) { // fire when mouse is released
|
|
//$(this).next().text(ui.value.toFixed(2));
|
|
generateOverlays();
|
|
}
|
|
});
|
|
|
|
generateHeatmapGradient("overlay-options span.heatmap-slider", defaultMinHue, defaultMaxHue);
|
|
|
|
//generateHeatmapGradient("overlay-options span.heatmap-gradient",
|
|
// defaultMinHueSlider, defaultMaxHueSlider);
|
|
|
|
/* End of heatmap init */
|
|
|
|
//updateMapHeight();
|
|
$(window).resize(updateMapHeight);
|
|
|
|
$("#filter").click(function() {
|
|
fetchMapExportStats();
|
|
});
|
|
|
|
fetchMapExportStats();
|
|
}
|
|
|
|
function drawGrid() {
|
|
var gridStep = 500/project.map.scale; // The step of the grid in map coordinates
|
|
|
|
var grid = d3.select("#map svg")
|
|
.append("svg:g")
|
|
.attr("id", "grid");
|
|
|
|
var xAxisDataNeg = d3.range(convert2WebXCoord(0), 0, -gridStep);
|
|
var xAxisDataPos = d3.range(convert2WebXCoord(0), bgWidth, gridStep);
|
|
|
|
var yAxisDataNeg = d3.range(convert2WebYCoord(0), 0, -gridStep);
|
|
var yAxisDataPos = d3.range(convert2WebYCoord(0), bgHeight, gridStep);
|
|
|
|
grid.selectAll("line.vertical")
|
|
.data(xAxisDataNeg.concat(xAxisDataPos))
|
|
.enter()
|
|
.append("svg:line")
|
|
.attr("x1", function(d) {return d;})
|
|
.attr("y1", 0)
|
|
.attr("x2", function(d) {return d;})
|
|
.attr("y2", bgHeight)
|
|
.attr("class", "map-grid");
|
|
|
|
grid.selectAll("line.horizontal")
|
|
.data(yAxisDataNeg.concat(yAxisDataPos))
|
|
.enter()
|
|
.append("svg:line")
|
|
.attr("x1", 0)
|
|
.attr("y1", function(d) {return d;})
|
|
.attr("x2", bgWidth)
|
|
.attr("y2", function(d) {return d;})
|
|
.attr("class", "map-grid");
|
|
}
|
|
|
|
function fetchMapExportStats() {
|
|
var pValues = config.headerOptions[headerAndFilters.headerType].getParamValues();
|
|
|
|
var endpointObject = {
|
|
restUrl: config.restHost + restEndpoint,
|
|
restAsyncUrl: config.restHost + restEndpointAsync + pValues.ForceUrlSuffix,
|
|
pValues: [pValues],
|
|
}
|
|
// This is for querying the time of last export of all the sections
|
|
var endpointObject2 = {
|
|
restUrl: config.restHost + restEndpoint2,
|
|
restAsyncUrl: config.restHost + restEndpoint2Async + pValues.ForceUrlSuffix,
|
|
pValues: [pValues],
|
|
}
|
|
|
|
var req = new ReportRequest(null, "json", null, config.restHost + config.reportsQueryAsync);
|
|
req.sendMultipleAsyncRequest([endpointObject, endpointObject2], handleMultipleResponse);
|
|
}
|
|
|
|
function handleMultipleResponse(monitoredProcesses) {
|
|
exportsStats = monitoredProcesses[0][0].response;
|
|
sectionExportAge = monitoredProcesses[1][0].response;
|
|
|
|
generateOverlays();
|
|
}
|
|
|
|
function generateOverlays() {
|
|
removeOverlay(); // remove overlay if exists
|
|
|
|
$("#stat-type").css("display", "none");
|
|
|
|
var calcType = $("#overlay-options input[name=calc-type-radio]:radio:checked").val();
|
|
var calcObj = optionCalculations[calcType];
|
|
var statType = $("#overlay-options input[name=stat-type-radio]:radio:checked").val();
|
|
var sectionType = $("#overlay-options input[name=section-type-radio]:radio:checked").val();
|
|
|
|
if (calcObj.hasTypes && ($("#stat-type").css("display") == "none"))
|
|
$("#stat-type").css("display", "inherit");
|
|
|
|
var overlayStatsData;
|
|
if (calcObj.isSectionAgeStat)
|
|
overlayStatsData = sectionExportAge;
|
|
else
|
|
overlayStatsData = exportsStats;
|
|
|
|
var filteredExports = [];
|
|
var propsSelected = (sectionType == sectionTypes[1].value) ? true : false;
|
|
var filterText = $("#section").val();
|
|
|
|
if (filterText == defaultFilterText)
|
|
filterText = "";
|
|
|
|
$.each(overlayStatsData, function(i, mapExportStat) {
|
|
// if the section passes the filter then continue further processing
|
|
if ((new RegExp("^" + filterText, "i")).test(mapExportStat.SectionName)) {
|
|
|
|
// check if the names matches the props suffix
|
|
if ((new RegExp(propsSuffix + "$", "i")).test(mapExportStat.SectionName)) {
|
|
if (propsSelected) { // add if it's props and pros is selected
|
|
filteredExports.push(mapExportStat);
|
|
}
|
|
}
|
|
else { // add if it's not props and pros is not selected
|
|
if (!propsSelected) {
|
|
filteredExports.push(mapExportStat);
|
|
}
|
|
} // end of props check
|
|
} // end of sections filtering check
|
|
});
|
|
|
|
//console.log(filteredExports);
|
|
|
|
var min = d3.min(filteredExports, function(d) {return calcObj.calcValue(d, statType)});
|
|
min = (min) ? min : 0;
|
|
//var avg = d3.mean(exportsStats, function(d) {return calcObj.calcValue(d, statType)});
|
|
var max = d3.max(filteredExports, function(d) {return calcObj.calcValue(d, statType)});
|
|
max = (max) ? max : 0;
|
|
var med = ((min+max)/2);
|
|
//console.log(filteredExports);
|
|
|
|
var thresholdSlider = $("#overlay-options div.threshold-slider");
|
|
thresholdSlider.slider("option", "min", min);
|
|
thresholdSlider.slider("option", "max", max);
|
|
thresholdSlider.slider("refresh");
|
|
$("#overlay-options span.threshold-value").text(thresholdSlider.slider("value").toFixed(2));
|
|
|
|
var valuesSlider = $("#overlay-options div.value-slider");
|
|
valuesSlider.slider("option", "min", min);
|
|
valuesSlider.slider("option", "max", max);
|
|
$("#overlay-options span.value-min").text(min.toFixed(2));
|
|
$("#overlay-options span.value-max").text(max.toFixed(2));
|
|
|
|
if (((valuesSlider.slider("values")[0] == min) && (valuesSlider.slider("values")[1] == min))
|
|
|| !calcObj.reversedColours) {
|
|
//console.log("Values init");
|
|
valuesSlider.slider("values", 0, min);
|
|
valuesSlider.slider("values", 1, max);
|
|
}
|
|
valuesSlider.slider("refresh");
|
|
|
|
var rangeSliderValues = valuesSlider.slider("values");
|
|
var heatmapSliderValues = $("#overlay-options div.heatmap-slider-placeholder").slider("values");
|
|
|
|
|
|
var colourCalc;
|
|
if (calcObj.reversedColours) {
|
|
colourCalc = getColourInterpolator(rangeSliderValues[0], rangeSliderValues[1],
|
|
heatmapSliderValues[1], heatmapSliderValues[0]);
|
|
|
|
generateHeatmapGradient("overlay-options span.heatmap-gradient",
|
|
heatmapSliderValues[1], heatmapSliderValues[0]);
|
|
//$(".heatmap-min").text(max.toFixed(2));
|
|
//$(".heatmap-med").text(med.toFixed(2));
|
|
//$(".heatmap-max").text(min.toFixed(2));
|
|
}
|
|
else {
|
|
colourCalc = getColourInterpolator(rangeSliderValues[0], rangeSliderValues[1],
|
|
heatmapSliderValues[0], heatmapSliderValues[1]);
|
|
|
|
generateHeatmapGradient("overlay-options span.heatmap-gradient",
|
|
heatmapSliderValues[0], heatmapSliderValues[1]);
|
|
//$(".heatmap-min").text(min.toFixed(2));
|
|
//$(".heatmap-med").text(med.toFixed(2));
|
|
//$(".heatmap-max").text(max.toFixed(2));
|
|
}
|
|
// Update the heatmap gradient text
|
|
$("#overlay-options span.heatmap-min").text(rangeSliderValues[0].toFixed(2));
|
|
$("#overlay-options span.heatmap-med").text(
|
|
((rangeSliderValues[0] + rangeSliderValues[1]) / 2).toFixed(2)
|
|
);
|
|
$("#overlay-options span.heatmap-max").text(rangeSliderValues[1].toFixed(2))
|
|
$(".heatmap-units").text(" (" + calcObj.units + " )")
|
|
|
|
|
|
var line = d3.svg.line()
|
|
.x(function(point) {return convert2WebXCoord(point.x);})
|
|
.y(function(point) {return convert2WebYCoord(point.y);})
|
|
.interpolate("basic");
|
|
|
|
var sectionOverlays = d3.select("#map svg")
|
|
.append("svg:g")
|
|
.attr("id", sectionsMapId)
|
|
.attr("opacity", 0.01);
|
|
|
|
sectionOverlays
|
|
.selectAll("path")
|
|
.data(filteredExports)
|
|
.enter()
|
|
.append("svg:path")
|
|
.attr("id", function(d) {return d.SectionName})
|
|
.attr("d", function(d) {
|
|
//console.log(sectionsVectorData);
|
|
var sectionData = sectionsVectorData[d.SectionName.toUpperCase().replace(propsSuffix, "")];
|
|
if (sectionData)
|
|
return (line(sectionData.points) + "z");
|
|
|
|
})
|
|
.style("fill", function(d) {return colourCalc(calcObj.calcValue(d, statType));})
|
|
.attr("visibility", function(d) { // Hide if below the threshold limit
|
|
return (calcObj.calcValue(d, statType) > thresholdSlider.slider("value")) ? "visible" : "hidden";
|
|
})
|
|
.on("click", highlightClicked)
|
|
.append("title")
|
|
.text(function(d) {
|
|
//console.log(d);
|
|
var title;
|
|
var sectionValue = calcObj.calcValue(d, statType);
|
|
if (calcObj.units == optionCalculations["OverallTime"].units) // == " secs", don't want to hardcode the string
|
|
title = d.SectionName + " : " + formatSecsWithDays(sectionValue)
|
|
+ " (" + sectionValue.toFixed(2) + calcObj.units + ") ";
|
|
else
|
|
title = d.SectionName + " : " + sectionValue.toFixed(2) + calcObj.units;
|
|
|
|
return title;
|
|
});
|
|
|
|
sectionOverlays
|
|
.transition()
|
|
.attr("opacity", 1);
|
|
|
|
}
|
|
|
|
function highlightClicked(data) {
|
|
|
|
if (data && (clicked !== data)) {
|
|
clicked = data;
|
|
}
|
|
else {
|
|
clicked = null;
|
|
}
|
|
|
|
d3.select("#map svg")
|
|
.select("#" + sectionsMapId)
|
|
.selectAll("path")
|
|
.classed("active", clicked && function(d) {return d === clicked; });
|
|
}
|
|
|
|
function removeOverlay() {
|
|
d3.select("#map svg")
|
|
.select("g#" + sectionsMapId)
|
|
.transition()
|
|
.style("opacity", 0.01)
|
|
.remove();
|
|
}
|
|
|
|
function generateHeatmapGradient(elementID, minHue, maxHue) {
|
|
var canvas = $("#" + elementID + " canvas")[0];
|
|
var context = canvas.getContext("2d");
|
|
|
|
context.rect(0, 0, canvas.width, canvas.height);
|
|
|
|
// add linear gradient
|
|
var grd = context.createLinearGradient(0, 0, canvas.width, 0);
|
|
|
|
var s = 0.9, v = 0.9;
|
|
var hueStep = (maxHue - minHue) / 5;
|
|
|
|
grd.addColorStop(0, hsv2hex(minHue, s, v));
|
|
grd.addColorStop(0.167, hsv2hex(minHue+hueStep, s, v));
|
|
grd.addColorStop(0.333, hsv2hex(minHue+2*hueStep, s, v));
|
|
grd.addColorStop(0.5, hsv2hex(minHue+3*hueStep, s, v));
|
|
grd.addColorStop(0.667, hsv2hex(minHue+4*hueStep, s, v));
|
|
grd.addColorStop(0.833, hsv2hex(minHue+5*hueStep, s, v));
|
|
grd.addColorStop(1, hsv2hex(maxHue, s, v));
|
|
|
|
context.fillStyle = grd;
|
|
context.fill();
|
|
}
|
|
|
|
function getColourInterpolator(minVal, maxVal, minHue, maxHue) {
|
|
// copying Michael Taschler's code of interpolation
|
|
|
|
return function (val) {
|
|
// Give the values outside the limits the limit colours
|
|
if (val < minVal)
|
|
val = minVal;
|
|
else if (val > maxVal)
|
|
val = maxVal;
|
|
|
|
// 0.0 to 1.0 scale convertion
|
|
val -= minVal;
|
|
if ((maxVal - minVal) != 0) // avoid division by zero
|
|
val /= (maxVal - minVal);
|
|
else
|
|
val = 0;
|
|
|
|
var lowHue = minHue / 360.0;
|
|
var highHue = maxHue / 360.0;
|
|
var diffHue = highHue - lowHue;
|
|
|
|
var h = (lowHue + (val * diffHue)) * 360;
|
|
var s = 0.9;
|
|
var v = 0.9;
|
|
|
|
return hsv2hex(h, s, v);
|
|
}
|
|
}
|
|
|
|
function hsv2hex(h, s, v) {
|
|
// Hue stays the same
|
|
// Saturation is very different between the two color spaces
|
|
// If (2-s)*v < 1 set it to s*v/((2-s)*v)
|
|
// Otherwise s*v/(2-(2-s)*v)
|
|
// Conditional is not operating with hue, it is reassigned!
|
|
s = (s * v) / ((((2-s) * v) < 1) ? ((2-s) * v) : 2-((2-s) * v));
|
|
l = (2-s)*v/2; // Lightness is (2-s)*v/2
|
|
|
|
return d3.hsl(h, s, l).toString();
|
|
}
|
|
|
|
/*
|
|
function drawSectionOverlay(mapExportStat, sectionValue, units, colour) {
|
|
var sectionData = sectionsVectorData[mapExportStat.SectionName.replace(propsSuffix, "")];
|
|
|
|
if (sectionData) {
|
|
var line = d3.svg.line()
|
|
.x(function(d) {return convert2WebXCoord(d.x);})
|
|
.y(function(d) {return convert2WebYCoord(d.y);})
|
|
.interpolate("basic");
|
|
|
|
var svg = d3.select("#map svg")
|
|
.select("#" + sectionsMapId)
|
|
svg.append("svg:path")
|
|
.attr("d", line(sectionData.points) + "z")
|
|
.style("fill", colour)
|
|
.on("click", function() {click(mapExportStat);})
|
|
.append("title")
|
|
.text(function() {
|
|
var title;
|
|
if (units == optionCalculations["OverallTime"].units) // == " secs", don't want to hardcode the string
|
|
title = mapExportStat.SectionName + " : " + formatSecsWithDays(sectionValue)
|
|
+ " (" + sectionValue.toFixed(2) + "" + units + ") ";
|
|
else
|
|
title = mapExportStat.SectionName + " : " + sectionValue.toFixed(2) + units;
|
|
|
|
return title;
|
|
});
|
|
}
|
|
|
|
function click(mapExportStat) {
|
|
|
|
if (mapExportStat && (clicked !== mapExportStat)) {
|
|
clicked = mapExportStat;
|
|
}
|
|
else {
|
|
clicked = null;
|
|
}
|
|
console.log(clicked);
|
|
|
|
d3.select("#map svg")
|
|
.select("#" + sectionsMapId)
|
|
.selectAll("path")
|
|
.classed("active", clicked && function(d) { console.log(d); return d === clicked; });
|
|
}
|
|
|
|
} */
|
|
|
|
function parseSectionsVectorXml(xml) {
|
|
var sections = [];
|
|
|
|
$(xml).find("section").each(function() {
|
|
var points = [];
|
|
$(this).find("point").each(function() {
|
|
points.push({
|
|
x: Number($(this).attr("x")),
|
|
y: Number($(this).attr("y")),
|
|
z: Number($(this).attr("z")),
|
|
});
|
|
});
|
|
|
|
var section = {
|
|
name: $(this).attr("name").toUpperCase(),
|
|
owner: $(this).attr("owner"),
|
|
points: points,
|
|
};
|
|
|
|
sections[section.name] = section;
|
|
});
|
|
|
|
return sections;
|
|
}
|
|
|
|
/*
|
|
|
|
function parseMapExportsAllStatsXml(xml) {
|
|
var sectionStats = [];
|
|
|
|
$(xml).find("DailySectionStatsDto").each(function() {
|
|
|
|
var exportStat = $(this).find("ExportStat");
|
|
var imageBuildStat = $(this).find("ImageBuildStat");
|
|
|
|
var sectionStat = {
|
|
SectionName: $(this).find("SectionName").text().toUpperCase(), // Capitalise the names to match the vectordata
|
|
ExportStat: {
|
|
SuccessfulCount: Number(exportStat.find("SuccessfulCount").text()),
|
|
FailedCount: Number(exportStat.find("FailedCount").text()),
|
|
TotalTimeTicks: Number(exportStat.find("TotalTimeTicks").text()),
|
|
MinTimeTicks: Number(exportStat.find("MinTimeTicks").text()),
|
|
MaxTimeTicks: Number(exportStat.find("MaxTimeTicks").text()),
|
|
},
|
|
ImageBuildStat: {
|
|
SuccessfulCount: Number(imageBuildStat.find("SuccessfulCount").text()),
|
|
FailedCount: Number(imageBuildStat.find("FailedCount").text()),
|
|
TotalTimeTicks: Number(imageBuildStat.find("TotalTimeTicks").text()),
|
|
MinTimeTicks: Number(imageBuildStat.find("MinTimeTicks").text()),
|
|
MaxTimeTicks: Number(imageBuildStat.find("MaxTimeTicks").text()),
|
|
},
|
|
TotalSectionsBuilt: Number($(this).find("TotalSectionsBuilt").text()),
|
|
};
|
|
|
|
sectionStats.push(sectionStat);
|
|
});
|
|
|
|
return sectionStats;
|
|
}
|
|
|
|
*/ |