diff --git a/html/admin/js/graphViewer/graph/nodeShaper.js b/html/admin/js/graphViewer/graph/nodeShaper.js index 0062fc95c9..810829ee1a 100644 --- a/html/admin/js/graphViewer/graph/nodeShaper.js +++ b/html/admin/js/graphViewer/graph/nodeShaper.js @@ -67,6 +67,24 @@ function NodeShaper(parent, flags, idfunc) { communityRegEx = /^\*community/, nodes = [], visibleLabels = true, + + splitLabel = function(label) { + if (label === undefined) { + return [""]; + } + if (typeof label !== "string") { + + label = String(label); + } + var chunks = label.match(/[\w\W]{1,10}(\s|$)|\S+?(\s|$)/g); + chunks[0] = $.trim(chunks[0]); + chunks[1] = $.trim(chunks[1]); + if (chunks.length > 2) { + chunks.length = 2; + chunks[1] += "..."; + } + return chunks; + }, noop = function (node) { }, @@ -243,21 +261,43 @@ function NodeShaper(parent, flags, idfunc) { parseLabelFlag = function (label) { if (_.isFunction(label)) { addLabel = function (node) { - node.append("text") // Append a label for the node + var textN = node.append("text") // Append a label for the node .attr("text-anchor", "middle") // Define text-anchor .attr("fill", "black") // Force a black color - .attr("stroke", "none") // Make it readable - .text(label); + .attr("stroke", "none"); // Make it readable + textN.each(function(d) { + var chunks = splitLabel(label(d)); + d3.select(this).append("tspan") + .attr("x", "0") + .attr("dy", "0") + .text(chunks[0]); + if (chunks.length === 2) { + d3.select(this).append("tspan") + .attr("x", "0") + .attr("dy", "20") + .text(chunks[1]); + } + }); }; } else { addLabel = function (node) { - node.append("text") // Append a label for the node + var textN = node.append("text") // Append a label for the node .attr("text-anchor", "middle") // Define text-anchor .attr("fill", "black") // Force a black color - .attr("stroke", "none") // Make it readable - .text(function(d) { - return d._data[label] !== undefined ? d._data[label] : ""; - }); + .attr("stroke", "none"); // Make it readable + textN.each(function(d) { + var chunks = splitLabel(d._data[label]); + d3.select(this).append("tspan") + .attr("x", "0") + .attr("dy", "0") + .text(chunks[0]); + if (chunks.length === 2) { + d3.select(this).append("tspan") + .attr("x", "0") + .attr("dy", "20") + .text(chunks[1]); + } + }); }; } }, diff --git a/html/admin/js/graphViewer/jasmine_test/specNodeShaper/nodeShaperSpec.js b/html/admin/js/graphViewer/jasmine_test/specNodeShaper/nodeShaperSpec.js index 02fdfa7769..7d58cc3bd7 100644 --- a/html/admin/js/graphViewer/jasmine_test/specNodeShaper/nodeShaperSpec.js +++ b/html/admin/js/graphViewer/jasmine_test/specNodeShaper/nodeShaperSpec.js @@ -691,9 +691,6 @@ textEl = $("svg .node text"); expect(textEl.attr("fill")).toEqual("black"); expect(textEl.attr("stroke")).toEqual("none"); - - - }); it('should ignore other attributes', function () { @@ -786,6 +783,45 @@ }); + it('should automatically line-break long multi-word labels', function() { + var node = [{ + _id: 1, + _data: { + label: "Label with many words" + } + }], + textEl, + spans; + shaper.drawNodes(node); + textEl = $("svg .node text"); + spans = $("tspan", textEl); + + expect($(spans.get(0)).text()).toEqual("Label with"); + expect($(spans.get(0)).attr("x")).toEqual("0"); + expect($(spans.get(0)).attr("dy")).toEqual("0"); + + expect($(spans.get(1)).text()).toEqual("many words"); + expect($(spans.get(1)).attr("x")).toEqual("0"); + expect($(spans.get(1)).attr("dy")).toEqual("20"); + }); + + it('should automatically cut labels with more then 20 characters', function() { + var node = [{ + _id: 1, + _data: { + label: "The quick brown foxx is jumping lazy over the fence" + } + }], + textEl, + spans; + shaper.drawNodes(node); + textEl = $("svg .node text"); + spans = $("tspan", textEl); + + expect($(spans.get(0)).text()).toEqual("The quick"); + expect($(spans.get(1)).text()).toEqual("brown foxx..."); + }); + }); describe('using a function for labels', function () {