From d6a260d8b45d23b13f2910b7b151dcf4e8f5d1cb Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Tue, 4 Jun 2013 12:51:09 +0200 Subject: [PATCH] GraphViewer: The label<-> colour list is now displayed right to the SVG --- .../js/graphViewer/graph/colourMapper.js | 14 ++++ html/admin/js/graphViewer/graph/nodeShaper.js | 4 ++ .../specColourMapper/colourMapperSpec.js | 14 ++++ .../specGraphViewer/graphViewerUISpec.js | 31 ++++++++ .../specNodeShaper/nodeShaperSpec.js | 43 +++++++++++ .../specNodeShaper/nodeShaperUISpec.js | 72 +++++++++++-------- html/admin/js/graphViewer/ui/graphViewerUI.js | 34 ++++++--- .../js/graphViewer/ui/nodeShaperControls.js | 40 +++++++---- 8 files changed, 201 insertions(+), 51 deletions(-) diff --git a/html/admin/js/graphViewer/graph/colourMapper.js b/html/admin/js/graphViewer/graph/colourMapper.js index 6273a0a969..e54ee5d844 100644 --- a/html/admin/js/graphViewer/graph/colourMapper.js +++ b/html/admin/js/graphViewer/graph/colourMapper.js @@ -34,6 +34,8 @@ function ColourMapper() { mapping = {}, reverseMapping = {}, colours = [], + listener, + self = this, nextColour = 0; colours.push("navy"); @@ -69,18 +71,30 @@ function ColourMapper() { nextColour = 0; } } + if (listener !== undefined) { + listener(self.getList()); + } return mapping[value]; }; + + this.reset = function() { mapping = {}; reverseMapping = {}; nextColour = 0; + if (listener !== undefined) { + listener(self.getList()); + } }; this.getList = function() { return reverseMapping; }; + this.setChangeListener = function(callback) { + listener = callback; + }; + this.reset(); } \ No newline at end of file diff --git a/html/admin/js/graphViewer/graph/nodeShaper.js b/html/admin/js/graphViewer/graph/nodeShaper.js index da7c769f75..a95b53b71c 100644 --- a/html/admin/js/graphViewer/graph/nodeShaper.js +++ b/html/admin/js/graphViewer/graph/nodeShaper.js @@ -460,6 +460,10 @@ function NodeShaper(parent, flags, idfunc) { return colourMapper.getList(); }; + self.setColourMappingListener = function(callback) { + colourMapper.setChangeListener(callback); + }; + } NodeShaper.shapes = Object.freeze({ diff --git a/html/admin/js/graphViewer/jasmine_test/specColourMapper/colourMapperSpec.js b/html/admin/js/graphViewer/jasmine_test/specColourMapper/colourMapperSpec.js index aa89c7b749..21cd4b2363 100644 --- a/html/admin/js/graphViewer/jasmine_test/specColourMapper/colourMapperSpec.js +++ b/html/admin/js/graphViewer/jasmine_test/specColourMapper/colourMapperSpec.js @@ -130,6 +130,20 @@ }); }); + + it('should be possible to add a change listener', function() { + var res = {}, + correct = {}, + listener = function(mapping) { + res = mapping; + }; + + mapper.setChangeListener(listener); + mapper.getColour("1"); + correct = mapper.getList(); + + expect(res).toEqual(correct); + }); }); }()); \ No newline at end of file diff --git a/html/admin/js/graphViewer/jasmine_test/specGraphViewer/graphViewerUISpec.js b/html/admin/js/graphViewer/jasmine_test/specGraphViewer/graphViewerUISpec.js index 60a8c35806..a061610ca1 100644 --- a/html/admin/js/graphViewer/jasmine_test/specGraphViewer/graphViewerUISpec.js +++ b/html/admin/js/graphViewer/jasmine_test/specGraphViewer/graphViewerUISpec.js @@ -341,6 +341,37 @@ }); }); + describe('checking the node colour mapping list', function() { + + var map; + + beforeEach(function() { + map = $("#contentDiv #node_colour_list"); + }); + + it('should append the list', function() { + expect(map.length).toEqual(1); + }); + + it('should be positioned in the top-right corner of the svg', function() { + expect(map.css("position")).toEqual("absolute"); + var leftPos = $("#contentDiv svg").position().left, + topPos = $("#contentDiv svg").position().top; + leftPos += $("#contentDiv svg").width(); + if (leftPos === Math.round(leftPos)) { + expect(map.css("left")).toEqual(leftPos + "px"); + } else { + expect(map.css("left")).toEqual(leftPos.toFixed(1) + "px"); + } + if (topPos === Math.round(topPos)) { + expect(map.css("top")).toEqual(topPos + "px"); + } else { + expect(map.css("top")).toEqual(topPos.toFixed(1) + "px"); + } + }); + + }); + describe('checking to load a graph', function() { var waittime = 200; diff --git a/html/admin/js/graphViewer/jasmine_test/specNodeShaper/nodeShaperSpec.js b/html/admin/js/graphViewer/jasmine_test/specNodeShaper/nodeShaperSpec.js index ca6414ec32..d76e5cc81f 100644 --- a/html/admin/js/graphViewer/jasmine_test/specNodeShaper/nodeShaperSpec.js +++ b/html/admin/js/graphViewer/jasmine_test/specNodeShaper/nodeShaperSpec.js @@ -320,6 +320,49 @@ }); }); + it('should be possible to add a change listener for the mapping', function() { + var nodes = [ + { + _id: 1, + _data: { + label: "lbl1" + } + }, { + _id: 2, + _data: { + label: "lbl2" + } + }, { + _id: 3, + _data: { + label: "lbl3" + } + }, { + _id: 4, + _data: { + label: "lbl1" + } + }], + shaper = new NodeShaper(d3.select("svg"), + { + color: { + type: "attribute", + key: "label" + } + }), + testee, + colorList; + shaper.setColourMappingListener(function(mapping) { + testee = mapping; + }); + + shaper.drawNodes(nodes); + + colorList = shaper.getColourMapping(); + + expect(testee).toEqual(colorList); + }); + }); describe('when nodes are already drawn', function() { diff --git a/html/admin/js/graphViewer/jasmine_test/specNodeShaper/nodeShaperUISpec.js b/html/admin/js/graphViewer/jasmine_test/specNodeShaper/nodeShaperUISpec.js index eed11a8d9a..3ec6f3b3d5 100644 --- a/html/admin/js/graphViewer/jasmine_test/specNodeShaper/nodeShaperUISpec.js +++ b/html/admin/js/graphViewer/jasmine_test/specNodeShaper/nodeShaperUISpec.js @@ -1,6 +1,6 @@ /*jslint indent: 2, nomen: true, maxlen: 100, white: true plusplus: true */ /*global beforeEach, afterEach */ -/*global describe, it, expect*/ +/*global describe, it, expect, jasmine*/ /*global runs, waitsFor, spyOn */ /*global window, eb, loadFixtures, document */ /*global $, _, d3*/ @@ -56,6 +56,7 @@ "green": ["gr", "een"] }; }); + spyOn(shaper, "setColourMappingListener"); this.addMatchers({ toBeTag: function(name) { var el = this.actual; @@ -263,32 +264,6 @@ }); - it('should be able to add a switch colour on attribute control to the list', function() { - runs(function() { - shaperUI.addControlOpticLabelAndColour(); - - expect($("#control_node_list #control_node_labelandcolour").length).toEqual(1); - expect($("#control_node_list #control_node_labelandcolour")[0]).toConformToListCSS(); - - helper.simulateMouseEvent("click", "control_node_labelandcolour"); - $("#control_node_labelandcolour_key").attr("value", "label"); - helper.simulateMouseEvent("click", "control_node_labelandcolour_submit"); - - expect(shaper.changeTo).toHaveBeenCalledWith({ - label: "label", - color: { - type: "attribute", - key: "label" - } - }); - }); - - waitsFor(function() { - return $("#control_node_attributecolour_modal").length === 0; - }, 2000, "The modal dialog should disappear."); - - }); - it('should be able to add all optic controls to the list', function () { shaperUI.addAllOptics(); @@ -324,18 +299,57 @@ blue = list.children[0], green = list.children[1]; expect(shaper.getColourMapping).wasCalled(); + expect(shaper.setColourMappingListener).wasCalledWith(jasmine.any(Function)); expect(div).toBeTag("div"); + expect($(div).attr("id")).toEqual("node_colour_list"); expect(list).toBeTag("ul"); expect(blue).toBeTag("li"); expect($(blue).text()).toEqual("bl, ue"); expect(blue.style.backgroundColor).toEqual("blue"); - + expect(green).toBeTag("li"); expect($(green).text()).toEqual("gr, een"); expect(green.style.backgroundColor).toEqual("green"); - + }); + describe('checking to change colour and label at once', function() { + + it('should be able to add the control and create the mapping list', function() { + runs(function() { + shaperUI.addControlOpticLabelAndColour(); + spyOn(shaperUI, "createColourMappingList").andCallThrough(); + + expect($("#control_node_list #control_node_labelandcolour").length).toEqual(1); + expect($("#control_node_list #control_node_labelandcolour")[0]).toConformToListCSS(); + + helper.simulateMouseEvent("click", "control_node_labelandcolour"); + $("#control_node_labelandcolour_key").attr("value", "label"); + helper.simulateMouseEvent("click", "control_node_labelandcolour_submit"); + + + + expect(shaper.changeTo).toHaveBeenCalledWith({ + label: "label", + color: { + type: "attribute", + key: "label" + } + }); + expect(shaperUI.createColourMappingList).wasCalled(); + expect(shaper.setColourMappingListener).wasCalledWith(jasmine.any(Function)); + }); + + waitsFor(function() { + return $("#control_node_attributecolour_modal").length === 0; + }, 2000, "The modal dialog should disappear."); + + runs(function() { + expect(true).toBeTruthy(); + }); + + }); + }); }); }()); \ No newline at end of file diff --git a/html/admin/js/graphViewer/ui/graphViewerUI.js b/html/admin/js/graphViewer/ui/graphViewerUI.js index 11bf126987..66ae8e8751 100644 --- a/html/admin/js/graphViewer/ui/graphViewerUI.js +++ b/html/admin/js/graphViewer/ui/graphViewerUI.js @@ -48,6 +48,9 @@ function GraphViewerUI(container, adapterConfig, optWidth, optHeight, viewerConf height = optHeight || container.offsetHeight, menubar = document.createElement("ul"), background = document.createElement("div"), + colourList, + nodeShaperUI, + adapterUI, mousePointerBox = document.createElement("div"), svg, @@ -152,15 +155,6 @@ function GraphViewerUI(container, adapterConfig, optWidth, optHeight, viewerConf ), */ - nodeShaperUI = new NodeShaperControls( - configureList, - graphViewer.nodeShaper - ), - adapterUI = new ArangoAdapterControls( - configureList, - graphViewer.adapter - ), - searchFunction = function() { if (searchAttrField.value === "" || searchAttrField.value === undefined) { @@ -173,6 +167,15 @@ function GraphViewerUI(container, adapterConfig, optWidth, optHeight, viewerConf } }; + nodeShaperUI = new NodeShaperControls( + configureList, + graphViewer.nodeShaper + ); + adapterUI = new ArangoAdapterControls( + configureList, + graphViewer.adapter + ); + menubar.id = "menubar"; menubar.className = "thumbnails2"; @@ -244,6 +247,16 @@ function GraphViewerUI(container, adapterConfig, optWidth, optHeight, viewerConf layouterUI.addAll(); adapterUI.addAll(); */ + + }, + + createColourList = function() { + colourList = nodeShaperUI.createColourMappingList(); + colourList.style.position = "absolute"; + var intSVG = $("#graphViewerSVG"); + colourList.style.top = intSVG.position().top.toFixed(1) + "px"; + colourList.style.left = (intSVG.position().left + intSVG.width()).toFixed(1) + "px"; + container.appendChild(colourList); }; container.appendChild(menubar); container.appendChild(background); @@ -253,7 +266,8 @@ function GraphViewerUI(container, adapterConfig, optWidth, optHeight, viewerConf viewerConfig = viewerConfig || {}; viewerConfig.zoom = true; graphViewer = new GraphViewer(svg, width, height, adapterConfig, viewerConfig); - + createToolbox(); createMenu(); + createColourList(); } \ No newline at end of file diff --git a/html/admin/js/graphViewer/ui/nodeShaperControls.js b/html/admin/js/graphViewer/ui/nodeShaperControls.js index 5da59f7d9c..9ccb8b4914 100644 --- a/html/admin/js/graphViewer/ui/nodeShaperControls.js +++ b/html/admin/js/graphViewer/ui/nodeShaperControls.js @@ -38,7 +38,22 @@ function NodeShaperControls(list, shaper) { throw "The NodeShaper has to be given."; } var self = this, - baseClass = "graph"; + baseClass = "graph", + colourDiv, + + fillColourDiv = function(mapping) { + while (colourDiv.hasChildNodes()) { + colourDiv.removeChild(colourDiv.lastChild); + } + var list = document.createElement("ul"); + colourDiv.appendChild(list); + _.each(mapping, function(els, col) { + var li = document.createElement("li"); + li.style.backgroundColor = col; + li.appendChild(document.createTextNode(els.join(", "))); + list.appendChild(li); + }); + }; this.addControlOpticShapeNone = function() { uiComponentsHelper.createButton(baseClass, list, "None", "control_node_none", function() { @@ -213,6 +228,10 @@ function NodeShaperControls(list, shaper) { key: key } }); + if (colourDiv === undefined) { + colourDiv = self.createColourMappingList(); + } + } ); }); @@ -246,16 +265,13 @@ function NodeShaperControls(list, shaper) { ////////////////////////////////////////////////////////////////// this.createColourMappingList = function() { - var div = document.createElement("div"), - list = document.createElement("ul"), - mapping = shaper.getColourMapping(); - div.appendChild(list); - _.each(mapping, function(els, col) { - var li = document.createElement("li"); - li.style.backgroundColor = col; - li.appendChild(document.createTextNode(els.join(", "))); - list.appendChild(li); - }); - return div; + if (colourDiv !== undefined) { + return colourDiv; + } + colourDiv = document.createElement("div"); + colourDiv.id = "node_colour_list"; + fillColourDiv(shaper.getColourMapping()); + shaper.setColourMappingListener(fillColourDiv); + return colourDiv; }; } \ No newline at end of file