From 107fc8b7a258fd61f6914880774e3506c6e5abee Mon Sep 17 00:00:00 2001 From: idrissou Date: Tue, 16 Aug 2016 21:25:43 +0200 Subject: [PATCH 1/9] blobs issue #387 --- src/app/app.js | 8 + .../filehandling/fileHandlingService.js | 4 +- src/app/components/map/mapController.js | 8 + src/app/components/map/mapDirective.js | 160 ++++++++++++++++++ src/app/components/toolbar/toolbarItems.js | 3 +- 5 files changed, 181 insertions(+), 2 deletions(-) diff --git a/src/app/app.js b/src/app/app.js index 996a256..c20de23 100644 --- a/src/app/app.js +++ b/src/app/app.js @@ -201,6 +201,14 @@ app.run(function ($rootScope, toolbar, toolbarItems, appMenuService) { callback: function () { $rootScope.$broadcast('api.update_table'); } + }, + { + id: toolbarItems.COMPUTE_BLOBS, + caption: 'Get Blobs', + icon: 'glyphicon glyphicon-bold', + callback: function () { + $rootScope.$broadcast('map.get_blobs'); + } } ]); diff --git a/src/app/components/filehandling/fileHandlingService.js b/src/app/components/filehandling/fileHandlingService.js index 76fb846..84fbae5 100644 --- a/src/app/components/filehandling/fileHandlingService.js +++ b/src/app/components/filehandling/fileHandlingService.js @@ -227,7 +227,7 @@ } else { var additional_params = {}; var table_additional_params = {}; // check documentation on execute>get_table for additional params - var map_additional_params = {}; // check documentation on execute>get_map for what params can be passed + var map_additional_params = {blobs:true,}; // check documentation on execute>get_map for what params can be passed original_filename = filename; return api.import_user_data(filename, additional_params).then(function (output) { cfpLoadingBar.set(0.3); @@ -422,6 +422,7 @@ function parseLayoutData(data) { var oldMap = data.map; + console.log(data); if (_.isUndefined(oldMap)) { //TODO: Throw error what went wrong @@ -433,6 +434,7 @@ newData.d3ConnectionLines = []; newData.d3ErrorLines = []; newData.stress = data.stress; + newData.blobs= data.blobs; oldMap.layout.forEach(function (layout, i) { newData.layout[i] = { diff --git a/src/app/components/map/mapController.js b/src/app/components/map/mapController.js index cab9890..d037cb5 100644 --- a/src/app/components/map/mapController.js +++ b/src/app/components/map/mapController.js @@ -54,6 +54,7 @@ * Calls fileHandlingService for API call to backend to get Error & Connectionlines */ function getErrorConnectionLines() { + console.log($scope.data); if (!$scope.showConnectionLines) { $scope.data.d3ConnectionLines = []; } @@ -159,6 +160,13 @@ fileHandling.createNewFileFromAlreadyExistingOne($scope.getSelectedFromCurrentMap()); }); + /** + * Watches for Get Blob event + */ + $scope.$on('map.get_blobs', function () { + $scope.displayBlobs() + }); + /** * Watches for moved nodes while lines(error/connection) are displayed */ diff --git a/src/app/components/map/mapDirective.js b/src/app/components/map/mapDirective.js index 011394e..abad5a2 100644 --- a/src/app/components/map/mapDirective.js +++ b/src/app/components/map/mapDirective.js @@ -959,6 +959,166 @@ app.directive('d3Map', ['$rootScope', '$window', '$timeout', 'toolbar', 'toolbar }); return orderedSera; } + /** + * computes the nodes and features them + * @returns none + */ + scope.displayBlobs = function () { + console.log(scope.data); + + + } + + /** + * This function calculate the Blob contour and returns a path for the blob + * @param sera + * @returns {Array} + */ + function pathFromPolar (point, contour, smoothing) { + // Local variables: + var + // The number of vertices + n = contour.length, + + // * The list of path vertices + vertex = [], + + // * Set a threshold for smooth edges whose appearance is indistinguishable + // from a straight line segment. + notRounded = (Math.abs(smoothing) < 1e-4), + + // * Vertex index + i, + + // * Index angle + alpha, + + // * A disposable 2D point + p, + + // * The resulting path + path = []; + + // From an array of vertices, calculate the co-ordinates of the spline curve + // handle for the edge identified by the arguments `index` and `edge` + // ('leading', 'trailing'). + function curveHandle(index, edge) { + var + pi, + ni, + prev, + next, + o, + prevLength, + nextLength, + prevToNext, + handle, + rounded = smoothing / 2 || 0; // To avoid bizarre effects at smoothing > 0.5, divide by 2 + + // The point whose curve handle we're calculating + o = vertex[index]; + + // Indices of previous and next points + if (index > 0) { + pi = index - 1; + } + else { + pi = n - 1; + } + + if (index < n - 1) { + ni = index + 1; + } + else { + ni = 0; + } + + // The neighbors of `o`. + prev = vertex[pi]; + next = vertex[ni]; + + // Lengths of the edges connecting to `prev` and `next` + prevLength = distance(prev, o); + nextLength = distance(next, o); + + // Length of the chord between `prev` and `next` + prevToNext = distance(prev, next); + + if (edge === 'trailing') { + handle = { + x: o.x + rounded * nextLength * (next.x - prev.x) / prevToNext, + y: o.y + rounded * nextLength * (next.y - prev.y) / prevToNext + }; + } + else { + handle = { + x: o.x - rounded * prevLength * (next.x - prev.x) / prevToNext, + y: o.y - rounded * prevLength * (next.y - prev.y) / prevToNext + }; + } + return handle; + } + + // calculate vertices + for (i = 0; i < n; i += 1) { + alpha = i * 2.0 * Math.PI / n; + vertex[i] = {}; + vertex[i].x = contour[i] * Math.cos(alpha); + vertex[i].y = contour[i] * Math.sin(alpha); + } + + // Calculate the first segment, starting at 12 o'clock. + path[0] = ["M", vertex[0].x, vertex[0].y]; + + // All segments between the first and the final. + for (i = 1; i < n; i += 1) { + if (notRounded) { + p = vertex[i]; + path.push(["L", p.x, p.y]); + } else { + p = curveHandle(i - 1, 'trailing'); + path.push(["C", p.x, p.y]); + p = curveHandle(i, 'leading'); + path[path.length - 1].push([p.x, p.y]); + p = vertex[i]; + path[path.length - 1].push([p.x, p.y]); + } + } + + // The final segment + if (notRounded) { + p = vertex[0]; + path.push(["L", p.x, p.y]); + } else { + p = curveHandle(n - 1, 'trailing'); + path.push(["C", p.x, p.y]); + p = curveHandle(0, 'leading'); + path[path.length - 1].push([p.x, p.y]); + p = vertex[0]; + path[path.length - 1].push([p.x, p.y]); + } + + // Terminate the path spec + path[path.length - 1].push(['z']); + + return path; + }; // pathFromPolar + + /** + * Calculate Euclidean distance between two points. A point is an object + * containing two properties named `x` and `y`. + * + * @method distance + * @param {SVGPoint|Object} p1 + * @param {SVGPoint|Object} p2 + * @return Number distance + */ + function distance(p1, p2) { + return Math.sqrt( + (p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y) + ); + }; + /** * Gets the data for a new map from selected nodes. Returns an array of nodes to remove in new map. diff --git a/src/app/components/toolbar/toolbarItems.js b/src/app/components/toolbar/toolbarItems.js index 4927a06..e057abb 100644 --- a/src/app/components/toolbar/toolbarItems.js +++ b/src/app/components/toolbar/toolbarItems.js @@ -44,7 +44,8 @@ RANDOMIZE_NODES: 17, FLIP_MAP_LEFT: 18, FLIP_MAP_HORIZENTAL: 19, - UPDATE_TABLE: 20 + UPDATE_TABLE: 20, + COMPUTE_BLOBS: 21 }; } From 79389ced4c0c870138adb0335f7d7dc8912a8fc4 Mon Sep 17 00:00:00 2001 From: idrissou Date: Wed, 17 Aug 2016 13:28:42 +0200 Subject: [PATCH 2/9] blobs functionality added issue #387 --- .../filehandling/fileHandlingService.js | 231 ++++++++++++++++- src/app/components/map/mapDirective.js | 237 ++++++------------ 2 files changed, 297 insertions(+), 171 deletions(-) diff --git a/src/app/components/filehandling/fileHandlingService.js b/src/app/components/filehandling/fileHandlingService.js index 84fbae5..745e3f6 100644 --- a/src/app/components/filehandling/fileHandlingService.js +++ b/src/app/components/filehandling/fileHandlingService.js @@ -40,14 +40,21 @@ function fileHandling($rootScope, $q, api, Flash, cfpLoadingBar, $timeout, $document) { - var acd1File = null; - var projection = 0; - var projection_comment = null; - var is_changed = false; - var original_filename = ""; - var fixedPoints = []; - var disconnectedPoints = []; - var fileHandler = {}; + var acd1File = null, + projection = 0, + projection_comment = null, + is_changed = false, + original_filename = "", + fixedPoints = [], + disconnectedPoints = [], + fileHandler = {}, + scale = 1, + BlobData, + globalData = new Array(), + smoothing=0.5, + subData = new Array(), + globalsmallY, + globalsmallX; /** * Displays errors that occurred @@ -422,8 +429,6 @@ function parseLayoutData(data) { var oldMap = data.map; - console.log(data); - if (_.isUndefined(oldMap)) { //TODO: Throw error what went wrong return {}; @@ -434,8 +439,10 @@ newData.d3ConnectionLines = []; newData.d3ErrorLines = []; newData.stress = data.stress; - newData.blobs= data.blobs; - + newData.blobs = data.blobs; + if (data.blobs){ + newData.blobs=computeBlobsCountour(data); + } oldMap.layout.forEach(function (layout, i) { newData.layout[i] = { "x": layout[0], @@ -811,6 +818,206 @@ return result; } + /** + * *This function computes the blobs raadi points, format data, and then returns a path + */ + + function computeBlobsCountour(dataElement){ + var data = new Array(); + var subData=new Array(); + var subData2=new Array(); + var counter=0; + // computing the contour for every point + dataElement.blobs.radii_for_points.forEach(function (d, i){ + subData = new Array(); + subData[counter] = pathFromPolar(dataElement.map.layout[i],d,smoothing); + //data[counter2]=subData; + data[counter]=subData; + counter++; + }); + //formating the data + for(var i=0; i< data.length; i++){ + BlobData= data[i]; + subData2 = new Array(); + var k=0; + + while(BlobData[0] == undefined){ + BlobData.splice(0, 1); + } + BlobData=BlobData[0]; + for (var j=0; j< (BlobData.length);j++){ + subData2[k] = { + "x": (BlobData[j][1])*scale, + "y": (BlobData[j][2])*scale + }; + if (k!=0){ + subData2[k+1] = { + "x": (BlobData[j][3][0])*scale, + "y": (BlobData[j][3][1])*scale + }; + subData2[k+2] = { + "x": (BlobData[j][4][0])*scale, + "y": (BlobData[j][4][1])*scale + }; + k=k+2; + } + k=k+1; + } + globalData[i] = subData2; + } + return globalData; + } + + /** + * This function calculate the Blob contour and returns a path for the blob + * @param sera + * @returns {Array} + */ + function pathFromPolar (point, contour, smoothing) { + // Local variables: + var + // The number of vertices + n = contour.length, + + // * The list of path vertices + vertex = [], + + // * Set a threshold for smooth edges whose appearance is indistinguishable + // from a straight line segment. + notRounded = (Math.abs(smoothing) < 1e-4), + + // * Vertex index + i, + + // * Index angle + alpha, + + // * A disposable 2D point + p, + + // * The resulting path + path = []; + + // From an array of vertices, calculate the co-ordinates of the spline curve + // handle for the edge identified by the arguments `index` and `edge` + // ('leading', 'trailing'). + function curveHandle(index, edge) { + var + pi, + ni, + prev, + next, + o, + prevLength, + nextLength, + prevToNext, + handle, + rounded = smoothing / 2 || 0; // To avoid bizarre effects at smoothing > 0.5, divide by 2 + + // The point whose curve handle we're calculating + o = vertex[index]; + + // Indices of previous and next points + if (index > 0) { + pi = index - 1; + } + else { + pi = n - 1; + } + + if (index < n - 1) { + ni = index + 1; + } + else { + ni = 0; + } + + // The neighbors of `o`. + prev = vertex[pi]; + next = vertex[ni]; + + // Lengths of the edges connecting to `prev` and `next` + prevLength = distance(prev, o); + nextLength = distance(next, o); + + // Length of the chord between `prev` and `next` + prevToNext = distance(prev, next); + + if (edge === 'trailing') { + handle = { + x: o.x + rounded * nextLength * (next.x - prev.x) / prevToNext, + y: o.y + rounded * nextLength * (next.y - prev.y) / prevToNext + }; + } + else { + handle = { + x: o.x - rounded * prevLength * (next.x - prev.x) / prevToNext, + y: o.y - rounded * prevLength * (next.y - prev.y) / prevToNext + }; + } + return handle; + } + + // calculate vertices + for (i = 0; i < n; i += 1) { + alpha = i * 2.0 * Math.PI / n; + vertex[i] = {}; + vertex[i].x = contour[i] * Math.cos(alpha); + vertex[i].y = contour[i] * Math.sin(alpha); + } + + // Calculate the first segment, starting at 12 o'clock. + path[0] = ["M", vertex[0].x, vertex[0].y]; + + // All segments between the first and the final. + for (i = 1; i < n; i += 1) { + if (notRounded) { + p = vertex[i]; + path.push(["L", p.x, p.y]); + } else { + p = curveHandle(i - 1, 'trailing'); + path.push(["C", p.x, p.y]); + p = curveHandle(i, 'leading'); + path[path.length - 1].push([p.x, p.y]); + p = vertex[i]; + path[path.length - 1].push([p.x, p.y]); + } + } + + // The final segment + if (notRounded) { + p = vertex[0]; + path.push(["L", p.x, p.y]); + } else { + p = curveHandle(n - 1, 'trailing'); + path.push(["C", p.x, p.y]); + p = curveHandle(0, 'leading'); + path[path.length - 1].push([p.x, p.y]); + p = vertex[0]; + path[path.length - 1].push([p.x, p.y]); + } + + // Terminate the path spec + path[path.length - 1].push(['z']); + + return path; + }; // pathFromPolar + + /** + * Calculate Euclidean distance between two points. A point is an object + * containing two properties named `x` and `y`. + * + * @method distance + * @param {SVGPoint|Object} p1 + * @param {SVGPoint|Object} p2 + * @return Number distance + */ + function distance(p1, p2) { + return Math.sqrt( + (p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y) + ); + }; + /** * * @returns {boolean} diff --git a/src/app/components/map/mapDirective.js b/src/app/components/map/mapDirective.js index abad5a2..ac1369d 100644 --- a/src/app/components/map/mapDirective.js +++ b/src/app/components/map/mapDirective.js @@ -64,7 +64,15 @@ app.directive('d3Map', ['$rootScope', '$window', '$timeout', 'toolbar', 'toolbar indentationWidthX= 0, indentationWidthY=0, indentationHeightX = 0, - indentationHeightY = 0; + indentationHeightY = 0, + showblobs= true, + scale = 1, + BlobData, + globalData = new Array(), + smoothing=0.5, + subData = new Array(), + globalsmallY, + globalsmallX; // d3 groups var boxGroup, @@ -73,7 +81,8 @@ app.directive('d3Map', ['$rootScope', '$window', '$timeout', 'toolbar', 'toolbar nodeGroup, errorlineGroup, connectionlineGroup, - labelsGroup; + labelsGroup, + blobsGroup; $rootScope.zoomed_center = undefined; @@ -135,6 +144,12 @@ app.directive('d3Map', ['$rootScope', '$window', '$timeout', 'toolbar', 'toolbar return "translate(" + xScale(d.x) + "," + yScale(d.y) + ")"; }); } + + if (nodeGroup) { + nodeGroup.attr("transform", function (d) { + return "translate(" + xScale(d.x) + "," + yScale(d.y) + ")"; + }); + } // Create brush brush = createBrush(); @@ -165,10 +180,10 @@ app.directive('d3Map', ['$rootScope', '$window', '$timeout', 'toolbar', 'toolbar nodeGroup.enter().append("path") .attr("class", "point") - .attr("id", function(d) { - return 'full-name-'+d.name; + .attr("id", function (d) { + return 'full-name-' + d.name; }) - .attr("full_name", function(d){ + .attr("full_name", function (d) { return d.name; }); @@ -275,7 +290,6 @@ app.directive('d3Map', ['$rootScope', '$window', '$timeout', 'toolbar', 'toolbar }); labelsGroup.exit().remove(); - errorlineGroup = errorlineGroup.data(data.d3ErrorLines); errorlineGroup.enter().append("line") .attr("class", "errorline") @@ -302,6 +316,45 @@ app.directive('d3Map', ['$rootScope', '$window', '$timeout', 'toolbar', 'toolbar })); errorlineGroup.exit().remove(); + //This is the accessor function we talked about above + var lineFunction = d3.svg.line() + .x(function(d) { return xScale(d.x); }) + .y(function(d) { return yScale(d.y); }) + .interpolate("linear"); + + for (var i=0; i 0.5, divide by 2 - - // The point whose curve handle we're calculating - o = vertex[index]; - - // Indices of previous and next points - if (index > 0) { - pi = index - 1; - } - else { - pi = n - 1; - } - - if (index < n - 1) { - ni = index + 1; - } - else { - ni = 0; - } - - // The neighbors of `o`. - prev = vertex[pi]; - next = vertex[ni]; - - // Lengths of the edges connecting to `prev` and `next` - prevLength = distance(prev, o); - nextLength = distance(next, o); - - // Length of the chord between `prev` and `next` - prevToNext = distance(prev, next); - - if (edge === 'trailing') { - handle = { - x: o.x + rounded * nextLength * (next.x - prev.x) / prevToNext, - y: o.y + rounded * nextLength * (next.y - prev.y) / prevToNext - }; - } - else { - handle = { - x: o.x - rounded * prevLength * (next.x - prev.x) / prevToNext, - y: o.y - rounded * prevLength * (next.y - prev.y) / prevToNext - }; - } - return handle; - } - - // calculate vertices - for (i = 0; i < n; i += 1) { - alpha = i * 2.0 * Math.PI / n; - vertex[i] = {}; - vertex[i].x = contour[i] * Math.cos(alpha); - vertex[i].y = contour[i] * Math.sin(alpha); - } - - // Calculate the first segment, starting at 12 o'clock. - path[0] = ["M", vertex[0].x, vertex[0].y]; - - // All segments between the first and the final. - for (i = 1; i < n; i += 1) { - if (notRounded) { - p = vertex[i]; - path.push(["L", p.x, p.y]); - } else { - p = curveHandle(i - 1, 'trailing'); - path.push(["C", p.x, p.y]); - p = curveHandle(i, 'leading'); - path[path.length - 1].push([p.x, p.y]); - p = vertex[i]; - path[path.length - 1].push([p.x, p.y]); - } - } - - // The final segment - if (notRounded) { - p = vertex[0]; - path.push(["L", p.x, p.y]); + if (showblobs) { + d3.selectAll(".blobs").style("visibility", "visible"); + showblobs=false; } else { - p = curveHandle(n - 1, 'trailing'); - path.push(["C", p.x, p.y]); - p = curveHandle(0, 'leading'); - path[path.length - 1].push([p.x, p.y]); - p = vertex[0]; - path[path.length - 1].push([p.x, p.y]); + d3.selectAll(".blobs").style("visibility", "hidden"); + showblobs=true; } - - // Terminate the path spec - path[path.length - 1].push(['z']); - - return path; - }; // pathFromPolar - - /** - * Calculate Euclidean distance between two points. A point is an object - * containing two properties named `x` and `y`. - * - * @method distance - * @param {SVGPoint|Object} p1 - * @param {SVGPoint|Object} p2 - * @return Number distance - */ - function distance(p1, p2) { - return Math.sqrt( - (p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y) - ); - }; - + } /** * Gets the data for a new map from selected nodes. Returns an array of nodes to remove in new map. From 84946481e87f15f52b2beed80d21a77c3650d19a Mon Sep 17 00:00:00 2001 From: idrissou Date: Wed, 24 Aug 2016 10:28:16 +0200 Subject: [PATCH 3/9] blobs working but functionality not complete --- .../filehandling/fileHandlingService.js | 16 ++++++++++++---- src/app/components/map/mapDirective.js | 5 +++-- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/app/components/filehandling/fileHandlingService.js b/src/app/components/filehandling/fileHandlingService.js index 745e3f6..64751c1 100644 --- a/src/app/components/filehandling/fileHandlingService.js +++ b/src/app/components/filehandling/fileHandlingService.js @@ -440,9 +440,7 @@ newData.d3ErrorLines = []; newData.stress = data.stress; newData.blobs = data.blobs; - if (data.blobs){ - newData.blobs=computeBlobsCountour(data); - } + oldMap.layout.forEach(function (layout, i) { newData.layout[i] = { "x": layout[0], @@ -469,6 +467,16 @@ oldMap.styles.points.forEach(function (point, i) { newData.layout[i].style = oldMap.styles.styles[point]; }); + // Computing blobs and centering them + if (data.blobs){ + newData.blobs=computeBlobsCountour(data); + for (var i=0; i< newData.blobs.length; i++){ + for (var j= 0; j Date: Mon, 29 Aug 2016 23:52:08 +0200 Subject: [PATCH 4/9] blobs front end functionality complete #387 --- .../filehandling/fileHandlingService.js | 2 + src/app/components/map/mapDirective.js | 76 ++++++++++--------- 2 files changed, 44 insertions(+), 34 deletions(-) diff --git a/src/app/components/filehandling/fileHandlingService.js b/src/app/components/filehandling/fileHandlingService.js index 64751c1..c64e619 100644 --- a/src/app/components/filehandling/fileHandlingService.js +++ b/src/app/components/filehandling/fileHandlingService.js @@ -139,6 +139,8 @@ // get new projection before export return api.new_projection(additional_params, acd1_file) .then(function (output) { + var map_additional_params = {blobs:true,}; // check documentation on execute>get_map for what params can be passed + acd1_file = output.output_acd1; var output_json = output.output_json; var data = fs.readFileSync(output_json, 'utf8'); diff --git a/src/app/components/map/mapDirective.js b/src/app/components/map/mapDirective.js index 1060df0..371c5f7 100644 --- a/src/app/components/map/mapDirective.js +++ b/src/app/components/map/mapDirective.js @@ -72,7 +72,8 @@ app.directive('d3Map', ['$rootScope', '$window', '$timeout', 'toolbar', 'toolbar smoothing=0.5, subData = new Array(), globalsmallY, - globalsmallX; + globalsmallX, + lineFunction ; // d3 groups var boxGroup, @@ -122,6 +123,10 @@ app.directive('d3Map', ['$rootScope', '$window', '$timeout', 'toolbar', 'toolbar // Scaling xScale = d3.scale.linear().domain([0, width]).range([indentationWidthX, indentationWidthY]); yScale = d3.scale.linear().domain([0, height]).range([indentationHeightX, indentationHeightY]); + lineFunction = d3.svg.line() + .x(function(d) { return xScale(d.x); }) + .y(function(d) { return yScale(d.y); }) + .interpolate("linear"); // Zoom zoom = d3.behavior.zoom() @@ -281,13 +286,14 @@ app.directive('d3Map', ['$rootScope', '$window', '$timeout', 'toolbar', 'toolbar .attr("y", function (d) { return d.y; }) - .style("visibility", "hidden") .style("font-family", "sans-serif") .style("font-size", "10px") + .style("visibility", "hidden") .style("fill", "#330066") .text(function (d) { return d.name; - }); + } + ); labelsGroup.exit().remove(); errorlineGroup = errorlineGroup.data(data.d3ErrorLines); @@ -318,42 +324,40 @@ app.directive('d3Map', ['$rootScope', '$window', '$timeout', 'toolbar', 'toolbar //This is the accessor function we talked about above - var lineFunction = d3.svg.line() - .x(function(d) { return xScale(d.x); }) - .y(function(d) { return yScale(d.y); }) - .interpolate("linear"); - for (var i=0; i Date: Wed, 7 Sep 2016 15:25:24 +0200 Subject: [PATCH 5/9] blobs front end functionality + backend functionalit complete #387 --- .../filehandling/fileHandlingService.js | 12 ++++---- src/app/components/map/mapController.js | 28 +++++++++++++++++- src/app/components/map/mapDirective.js | 29 +++++++++++++++++-- src/css/style.css | 10 +++++++ 4 files changed, 70 insertions(+), 9 deletions(-) diff --git a/src/app/components/filehandling/fileHandlingService.js b/src/app/components/filehandling/fileHandlingService.js index c64e619..8084733 100644 --- a/src/app/components/filehandling/fileHandlingService.js +++ b/src/app/components/filehandling/fileHandlingService.js @@ -139,7 +139,7 @@ // get new projection before export return api.new_projection(additional_params, acd1_file) .then(function (output) { - var map_additional_params = {blobs:true,}; // check documentation on execute>get_map for what params can be passed + var map_additional_params = {}; // check documentation on execute>get_map for what params can be passed acd1_file = output.output_acd1; var output_json = output.output_json; @@ -236,7 +236,7 @@ } else { var additional_params = {}; var table_additional_params = {}; // check documentation on execute>get_table for additional params - var map_additional_params = {blobs:true,}; // check documentation on execute>get_map for what params can be passed + var map_additional_params = {}; // check documentation on execute>get_map for what params can be passed original_filename = filename; return api.import_user_data(filename, additional_params).then(function (output) { cfpLoadingBar.set(0.3); @@ -371,7 +371,8 @@ } var map_additional_params = { - projection: (projection == 0) ? projection : projection_comment + projection: (projection == 0) ? projection : projection_comment, + blobs: true }; return api.execute(api.get_commands().GET_MAP, map_additional_params, acd1File).then(function (data) { return $q.all([ @@ -511,8 +512,6 @@ } } - console.log(newData); - return newData; } @@ -552,6 +551,7 @@ api.remove_antigens_sera(remove_antigens_sera, acd1File) .then(function (filename) { + $rootScope.$broadcast('open-file', filename.output_acd1); $rootScope.$broadcast('open-file', filename.output_acd1); cfpLoadingBar.complete(); }, function (reason) { @@ -736,7 +736,7 @@ y1: from.y, x2: to.x, y2: to.y, - stroke: 'grey', + stroke: colour, width: 0.4, opacity: 1.0 }); diff --git a/src/app/components/map/mapController.js b/src/app/components/map/mapController.js index d037cb5..5431727 100644 --- a/src/app/components/map/mapController.js +++ b/src/app/components/map/mapController.js @@ -46,6 +46,7 @@ $scope.pointsMoved = false; $scope.data = result; getErrorConnectionLines(); + $scope.pointsMoved = true; cfpLoadingBar.complete(); }); }); @@ -91,6 +92,19 @@ }); } + /** + * Gets new Projection for Blobs + */ + function getBlobsProjection() { + fileHandling.getNewProjection($scope.data).then(function (result) { + $scope.pointsMoved = false; + $scope.data = result; + fileHandling.setMapIsChanged(false); + cfpLoadingBar.complete(); + $scope.displayBlobs() + }); + } + /** * Watches for a the errorLines button */ @@ -164,7 +178,19 @@ * Watches for Get Blob event */ $scope.$on('map.get_blobs', function () { - $scope.displayBlobs() + if(!$scope.blobsLoaded()){ + getBlobsProjection() + $scope.setBloabsFlag(true); + } + else { + if ($scope.pointsMoved) { + alert("moved"); + getBlobsProjection() + } else { + alert("not moved"); + $scope.displayBlobs() + } + } }); /** diff --git a/src/app/components/map/mapDirective.js b/src/app/components/map/mapDirective.js index 371c5f7..ad1f18e 100644 --- a/src/app/components/map/mapDirective.js +++ b/src/app/components/map/mapDirective.js @@ -34,7 +34,16 @@ app.directive('d3Map', ['$rootScope', '$window', '$timeout', 'toolbar', 'toolbar data: "=" }, controller: 'mapCtrl', - template: '

Stress: {{(data.stress || "Undefined Value") | number: 3}}

', + template: '

Stress: {{(data.stress || "Undefined Value") | number: 3}}

' + + '
' + + '
' + + ' ' + + '
' + + ' ' + + ''+ + '
', + + link: function (scope, iElement) { var svg = null, @@ -66,6 +75,7 @@ app.directive('d3Map', ['$rootScope', '$window', '$timeout', 'toolbar', 'toolbar indentationHeightX = 0, indentationHeightY = 0, showblobs= true, + loadedblobs=false, scale = 1, BlobData, globalData = new Array(), @@ -354,7 +364,7 @@ app.directive('d3Map', ['$rootScope', '$window', '$timeout', 'toolbar', 'toolbar .attr("fill", "orange") .attr("class", "blobs") .style("opacity", 0.4) - .style("visibility", "hidden") + .style("visibility", "visible") ; blobsGroup.exit().remove(); @@ -1033,6 +1043,7 @@ app.directive('d3Map', ['$rootScope', '$window', '$timeout', 'toolbar', 'toolbar */ scope.displayBlobs = function () { if (showblobs) { + alert("visible"); d3.selectAll(".blobs").style("visibility", "visible"); showblobs=false; selectAllNodes(); @@ -1047,6 +1058,20 @@ app.directive('d3Map', ['$rootScope', '$window', '$timeout', 'toolbar', 'toolbar deselectNodes(); } } + /** + * checks if blobs are loaded from the backend or not + * @returns boolean + */ + scope.blobsLoaded = function () { + return loadedblobs; + } + /** + * Sets the right flag if bloabs are loaded from the backend + * @returns none + */ + scope.setBloabsFlag = function (trueorfalse) { + loadedblobs= trueorfalse; + } /** * Gets the data for a new map from selected nodes. Returns an array of nodes to remove in new map. diff --git a/src/css/style.css b/src/css/style.css index 85d6f94..f678cd6 100644 --- a/src/css/style.css +++ b/src/css/style.css @@ -110,6 +110,16 @@ html { margin-left: 10px; margin-top: 5px; } +.blobs{ + height: 30px; + color: rgb(0,0,128); + font-weight: bold; + position: absolute; + margin-left: 140px; + margin-top: 5px; + visibility: hidden; + +} .tblantigenhighlight { background-color: #d4d4d4; From 06b0c3e46a06ef0e953dc71b3bf591c2a68724cc Mon Sep 17 00:00:00 2001 From: idrissou Date: Wed, 7 Sep 2016 19:46:49 +0200 Subject: [PATCH 6/9] blobs front end functionality + backend functionalit complete #387 --- core/README.md | 37 -------------- src/app/app.js | 8 ++++ .../filehandling/fileHandlingService.js | 15 ++++-- src/app/components/map/mapController.js | 15 ++++-- src/app/components/map/mapDirective.js | 48 +++++++++++-------- src/app/components/toolbar/toolbarItems.js | 3 +- 6 files changed, 59 insertions(+), 67 deletions(-) delete mode 100644 core/README.md diff --git a/core/README.md b/core/README.md deleted file mode 100644 index 4d07434..0000000 --- a/core/README.md +++ /dev/null @@ -1,37 +0,0 @@ -# AcmacsCore.bundle -We use a special version of https://github.com/acorg/acmacs.git as our backend to do all the calculations. -In order get the application to work, you have to put a compiled version of the core bundle into this folder. - -**Attention: The acmacs repository is private. You need to request access from https://github.com/acorg to get the newest source code.** - -## Download precompiled binaries -You can get precompiled binaries for OS X (10.7+) and Ubuntu (14.04) [here](https://drive.google.com/folderview?id=0B3SjWA2XVkqCTERmV1BJUkZOYzA&usp=sharing). - -## Build AcmacsCore.bundle on OS X -1. Get current version of Acmacs: https://github.com/acorg/acmacs.git -2. Prerequisites - - OS X Command Line Developer Tools - - pkg-config (install over homebrew) -3. Set $ACMACS_ROOT environment variable to point to the Acmacs folder -4. Build AcmacsCore package - `$ACMACS_ROOT/bin/c2r-build CORE` -5. Navigate to `$ACMACS_ROOT` -6. Build core bundle -`bin/c2env make -j acmacs-core-bundle` -It will create a tree under ~/Desktop/AcmacsCore.bundle on OSX - -## Build AcmacsCore.bundle on Ubuntu -1. Get current version of Acmacs: https://github.com/acorg/acmacs.git -2. Prerequisites - - m4 - - flex - - libncurses-dev - - libbz2-dev - - g++-multilib -3. Set $ACMACS_ROOT environment variable to point to the Acmacs folder -4. Build AcmacsCore package - `$ACMACS_ROOT/bin/c2r-build CORE` -5. Navigate to `$ACMACS_ROOT` -6. Build core bundle -`bin/c2env make -j acmacs-core-bundle` -It will create a tree under ~/AcmacsCore.bundle diff --git a/src/app/app.js b/src/app/app.js index c20de23..d14bb3a 100644 --- a/src/app/app.js +++ b/src/app/app.js @@ -209,6 +209,14 @@ app.run(function ($rootScope, toolbar, toolbarItems, appMenuService) { callback: function () { $rootScope.$broadcast('map.get_blobs'); } + }, + { + id: toolbarItems.COMPUTE_BLOBS, + caption: 'Get Blobs', + icon: 'glyphicon glyphicon-bold', + callback: function () { + $rootScope.$broadcast('map.duplicate'); + } } ]); diff --git a/src/app/components/filehandling/fileHandlingService.js b/src/app/components/filehandling/fileHandlingService.js index 8084733..97c48ae 100644 --- a/src/app/components/filehandling/fileHandlingService.js +++ b/src/app/components/filehandling/fileHandlingService.js @@ -335,7 +335,11 @@ * @param mapData * @returns {*} */ - fileHandler.getNewProjection = function (mapData) { + fileHandler.getNewProjection = function (mapData, blobsvalue) { + var getblobs=false; + if (blobsvalue==true){ + getblobs=true; + } cfpLoadingBar.start(); @@ -372,7 +376,7 @@ var map_additional_params = { projection: (projection == 0) ? projection : projection_comment, - blobs: true + blobs: getblobs }; return api.execute(api.get_commands().GET_MAP, map_additional_params, acd1File).then(function (data) { return $q.all([ @@ -551,9 +555,12 @@ api.remove_antigens_sera(remove_antigens_sera, acd1File) .then(function (filename) { - $rootScope.$broadcast('open-file', filename.output_acd1); $rootScope.$broadcast('open-file', filename.output_acd1); cfpLoadingBar.complete(); + $rootScope.$emit('map.showErrorLines'); + + + }, function (reason) { return errorReason(reason); }); @@ -736,7 +743,7 @@ y1: from.y, x2: to.x, y2: to.y, - stroke: colour, + stroke: "grey", width: 0.4, opacity: 1.0 }); diff --git a/src/app/components/map/mapController.js b/src/app/components/map/mapController.js index 5431727..19896a5 100644 --- a/src/app/components/map/mapController.js +++ b/src/app/components/map/mapController.js @@ -55,7 +55,6 @@ * Calls fileHandlingService for API call to backend to get Error & Connectionlines */ function getErrorConnectionLines() { - console.log($scope.data); if (!$scope.showConnectionLines) { $scope.data.d3ConnectionLines = []; } @@ -96,10 +95,10 @@ * Gets new Projection for Blobs */ function getBlobsProjection() { - fileHandling.getNewProjection($scope.data).then(function (result) { + fileHandling.getNewProjection($scope.data,true).then(function (result) { $scope.pointsMoved = false; $scope.data = result; - fileHandling.setMapIsChanged(false); + fileHandling.setMapIsChanged(true); cfpLoadingBar.complete(); $scope.displayBlobs() }); @@ -173,21 +172,27 @@ $scope.$on('map.create_from_selected', function () { fileHandling.createNewFileFromAlreadyExistingOne($scope.getSelectedFromCurrentMap()); }); + /** + * Watches for New Map Create from Selected Nodes + */ + $scope.$on('map.duplicate', function () { + fileHandling.createNewFileFromAlreadyExistingOne($scope.getSelectedFromCurrentMap()); + }); /** * Watches for Get Blob event */ $scope.$on('map.get_blobs', function () { + alert($scope.pointsMoved); if(!$scope.blobsLoaded()){ getBlobsProjection() $scope.setBloabsFlag(true); } else { if ($scope.pointsMoved) { - alert("moved"); + alert("casenotworking"); getBlobsProjection() } else { - alert("not moved"); $scope.displayBlobs() } } diff --git a/src/app/components/map/mapDirective.js b/src/app/components/map/mapDirective.js index ad1f18e..aa109ab 100644 --- a/src/app/components/map/mapDirective.js +++ b/src/app/components/map/mapDirective.js @@ -40,7 +40,7 @@ app.directive('d3Map', ['$rootScope', '$window', '$timeout', 'toolbar', 'toolbar ' ' + '
' + ' ' + - ''+ + ''+ '', @@ -133,10 +133,13 @@ app.directive('d3Map', ['$rootScope', '$window', '$timeout', 'toolbar', 'toolbar // Scaling xScale = d3.scale.linear().domain([0, width]).range([indentationWidthX, indentationWidthY]); yScale = d3.scale.linear().domain([0, height]).range([indentationHeightX, indentationHeightY]); - lineFunction = d3.svg.line() - .x(function(d) { return xScale(d.x); }) - .y(function(d) { return yScale(d.y); }) - .interpolate("linear"); + + if (blobsGroup){ + lineFunction = d3.svg.line() + .x(function(d) { return xScale(d.x); }) + .y(function(d) { return yScale(d.y); }) + .interpolate("linear"); + } // Zoom zoom = d3.behavior.zoom() @@ -353,21 +356,24 @@ app.directive('d3Map', ['$rootScope', '$window', '$timeout', 'toolbar', 'toolbar }*/ - blobsGroup = blobsGroup.data(data.blobs); - blobsGroup.enter().append("path") - .attr("d", function (d) { - return lineFunction(d); - }) + if (data.blobs) { + alert("blobs updating 2"); + blobsGroup = blobsGroup.data(data.blobs); - .attr("stroke", "black") - .attr("stroke-width", 1) - .attr("fill", "orange") - .attr("class", "blobs") - .style("opacity", 0.4) - .style("visibility", "visible") - ; - blobsGroup.exit().remove(); + blobsGroup.enter().append("path") + .attr("d", function (d) { + return lineFunction(d); + }) + .attr("stroke", "black") + .attr("stroke-width", 1) + .attr("fill", "orange") + .attr("class", "blobs") + .style("opacity", 0.4) + .style("visibility", "visible") + ; + blobsGroup.exit().remove(); + } connectionlineGroup = connectionlineGroup.data(data.d3ConnectionLines); @@ -658,7 +664,8 @@ app.directive('d3Map', ['$rootScope', '$window', '$timeout', 'toolbar', 'toolbar var scale = zoom.scale(), translate = zoom.translate(); return [coordinates[0] * scale + translate[0], coordinates[1] * scale + translate[1]]; } - + var element= document.getElementById("blobclick"); + element.onclick=function(){alert("hello blob")}; /** * Deselects all nodes @@ -1043,7 +1050,6 @@ app.directive('d3Map', ['$rootScope', '$window', '$timeout', 'toolbar', 'toolbar */ scope.displayBlobs = function () { if (showblobs) { - alert("visible"); d3.selectAll(".blobs").style("visibility", "visible"); showblobs=false; selectAllNodes(); @@ -1177,6 +1183,7 @@ app.directive('d3Map', ['$rootScope', '$window', '$timeout', 'toolbar', 'toolbar } }); scope.pointsMoved = true; + if (connection_visible){ scope.$emit('map.showConnectionLines'); } @@ -1186,6 +1193,7 @@ app.directive('d3Map', ['$rootScope', '$window', '$timeout', 'toolbar', 'toolbar if(!connection_visible && !error_visible){ scope.$emit('map.nudgeTriggeredOnLine',avoidErrorLineCalculation); } + scope.pointsMoved = true; cfpLoadingBar.complete(); }); /** diff --git a/src/app/components/toolbar/toolbarItems.js b/src/app/components/toolbar/toolbarItems.js index e057abb..65d3257 100644 --- a/src/app/components/toolbar/toolbarItems.js +++ b/src/app/components/toolbar/toolbarItems.js @@ -45,7 +45,8 @@ FLIP_MAP_LEFT: 18, FLIP_MAP_HORIZENTAL: 19, UPDATE_TABLE: 20, - COMPUTE_BLOBS: 21 + COMPUTE_BLOBS: 21, + DUPLICATE_MAP: 22 }; } From c557f5a8878937ff6de4f7062e6fe9e2ff9d798a Mon Sep 17 00:00:00 2001 From: idrissou Date: Wed, 7 Sep 2016 19:50:47 +0200 Subject: [PATCH 7/9] blobs front end functionality + backend functionalit complete #387 --- src/app/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/app.js b/src/app/app.js index d14bb3a..dc15e80 100644 --- a/src/app/app.js +++ b/src/app/app.js @@ -213,7 +213,7 @@ app.run(function ($rootScope, toolbar, toolbarItems, appMenuService) { { id: toolbarItems.COMPUTE_BLOBS, caption: 'Get Blobs', - icon: 'glyphicon glyphicon-bold', + icon: ' glyphicon glyphicon-duplicate', callback: function () { $rootScope.$broadcast('map.duplicate'); } From 546546cd94629f92767b95e3de38e65478ac247f Mon Sep 17 00:00:00 2001 From: idrissou Date: Thu, 8 Sep 2016 11:33:50 +0200 Subject: [PATCH 8/9] blobs updating bug fixed #387 --- src/app/app.js | 2 +- .../components/filehandling/fileHandlingService.js | 4 +--- src/app/components/map/mapController.js | 7 +++++-- src/app/components/map/mapDirective.js | 12 ++++++++---- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/app/app.js b/src/app/app.js index dc15e80..d424ffa 100644 --- a/src/app/app.js +++ b/src/app/app.js @@ -212,7 +212,7 @@ app.run(function ($rootScope, toolbar, toolbarItems, appMenuService) { }, { id: toolbarItems.COMPUTE_BLOBS, - caption: 'Get Blobs', + caption: 'Duplicate Map', icon: ' glyphicon glyphicon-duplicate', callback: function () { $rootScope.$broadcast('map.duplicate'); diff --git a/src/app/components/filehandling/fileHandlingService.js b/src/app/components/filehandling/fileHandlingService.js index 97c48ae..b7c26ef 100644 --- a/src/app/components/filehandling/fileHandlingService.js +++ b/src/app/components/filehandling/fileHandlingService.js @@ -340,7 +340,6 @@ if (blobsvalue==true){ getblobs=true; } - cfpLoadingBar.start(); var list = []; @@ -557,7 +556,6 @@ .then(function (filename) { $rootScope.$broadcast('open-file', filename.output_acd1); cfpLoadingBar.complete(); - $rootScope.$emit('map.showErrorLines'); @@ -743,7 +741,7 @@ y1: from.y, x2: to.x, y2: to.y, - stroke: "grey", + stroke: colour, width: 0.4, opacity: 1.0 }); diff --git a/src/app/components/map/mapController.js b/src/app/components/map/mapController.js index 19896a5..b6f457e 100644 --- a/src/app/components/map/mapController.js +++ b/src/app/components/map/mapController.js @@ -98,9 +98,14 @@ fileHandling.getNewProjection($scope.data,true).then(function (result) { $scope.pointsMoved = false; $scope.data = result; + $scope.data.blobs=result.blobs; fileHandling.setMapIsChanged(true); cfpLoadingBar.complete(); $scope.displayBlobs() + $rootScope.$emit('map.zoomIn'); + $rootScope.$emit('map.zoomOut'); + + }); } @@ -183,14 +188,12 @@ * Watches for Get Blob event */ $scope.$on('map.get_blobs', function () { - alert($scope.pointsMoved); if(!$scope.blobsLoaded()){ getBlobsProjection() $scope.setBloabsFlag(true); } else { if ($scope.pointsMoved) { - alert("casenotworking"); getBlobsProjection() } else { $scope.displayBlobs() diff --git a/src/app/components/map/mapDirective.js b/src/app/components/map/mapDirective.js index aa109ab..e2be277 100644 --- a/src/app/components/map/mapDirective.js +++ b/src/app/components/map/mapDirective.js @@ -37,7 +37,7 @@ app.directive('d3Map', ['$rootScope', '$window', '$timeout', 'toolbar', 'toolbar template: '

Stress: {{(data.stress || "Undefined Value") | number: 3}}

' + '
' + '
' + - ' ' + + ' ' + '
' + ' ' + ''+ @@ -357,7 +357,6 @@ app.directive('d3Map', ['$rootScope', '$window', '$timeout', 'toolbar', 'toolbar if (data.blobs) { - alert("blobs updating 2"); blobsGroup = blobsGroup.data(data.blobs); blobsGroup.enter().append("path") @@ -664,9 +663,14 @@ app.directive('d3Map', ['$rootScope', '$window', '$timeout', 'toolbar', 'toolbar var scale = zoom.scale(), translate = zoom.translate(); return [coordinates[0] * scale + translate[0], coordinates[1] * scale + translate[1]]; } - var element= document.getElementById("blobclick"); - element.onclick=function(){alert("hello blob")}; + var element= document.getElementById("blobclick"); + element.onclick=function() { + var blobs_stress = document.getElementById("blobs_stress"); + alert("Functionality not yet complete"); + var smoothing = document.getElementById("smoothing"); + + } /** * Deselects all nodes */ From 62dffbe233b064d9074df946451e7c733640825d Mon Sep 17 00:00:00 2001 From: idrissou Date: Thu, 8 Sep 2016 11:48:30 +0200 Subject: [PATCH 9/9] code clean up and removing un-finished functionality --- src/app/app.js | 8 -------- src/app/components/map/mapDirective.js | 11 ----------- 2 files changed, 19 deletions(-) diff --git a/src/app/app.js b/src/app/app.js index d424ffa..c20de23 100644 --- a/src/app/app.js +++ b/src/app/app.js @@ -209,14 +209,6 @@ app.run(function ($rootScope, toolbar, toolbarItems, appMenuService) { callback: function () { $rootScope.$broadcast('map.get_blobs'); } - }, - { - id: toolbarItems.COMPUTE_BLOBS, - caption: 'Duplicate Map', - icon: ' glyphicon glyphicon-duplicate', - callback: function () { - $rootScope.$broadcast('map.duplicate'); - } } ]); diff --git a/src/app/components/map/mapDirective.js b/src/app/components/map/mapDirective.js index 1eef396..a0bb95b 100644 --- a/src/app/components/map/mapDirective.js +++ b/src/app/components/map/mapDirective.js @@ -36,11 +36,6 @@ app.directive('d3Map', ['$rootScope', '$window', '$timeout', 'toolbar', 'toolbar controller: 'mapCtrl', template: '

Stress: {{(data.stress || "Undefined Value") | number: 3}}

' + '
' + - '
' + - ' ' + - '
' + - ' ' + - ''+ '
', @@ -682,13 +677,7 @@ app.directive('d3Map', ['$rootScope', '$window', '$timeout', 'toolbar', 'toolbar return [coordinates[0] * scale + translate[0], coordinates[1] * scale + translate[1]]; } - var element= document.getElementById("blobclick"); - element.onclick=function() { - var blobs_stress = document.getElementById("blobs_stress"); - alert("Functionality not yet complete"); - var smoothing = document.getElementById("smoothing"); - } /** * Deselects all nodes */