diff --git a/dDashboardServer/static/js/network-graph.js b/dDashboardServer/static/js/network-graph.js index 34616dbd9..9ac8d65d9 100644 --- a/dDashboardServer/static/js/network-graph.js +++ b/dDashboardServer/static/js/network-graph.js @@ -20,7 +20,7 @@ var COLUMNS = [0, 1, 2, 3, 4]; // game clients | auth, chat, worlds, others | master | dashboard, UGC | web clients // An open group's box: its header, the filter, the rows (at most MAX_ROWS in view, the rest scroll) and a margin - var GROUP = { head: 44, filter: 30, row: 30, maxRows: 8, foot: 6 }; + var GROUP = { head: 58, filter: 30, row: 30, maxRows: 8, foot: 6 }; // head: a name on up to two lines and one line under it function num(v) { return typeof v === 'number' && isFinite(v) ? v : 0; } function rates(r) { r = r || {}; return { packets_in: num(r.packets_in), packets_out: num(r.packets_out), bytes_in: num(r.bytes_in), bytes_out: num(r.bytes_out) }; } @@ -266,7 +266,7 @@ * when closed), h its whole height; an open box's list starts at lists[id].top and anchors are the rows in view. */ function layout(graph, totalWidth, moved, scroll) { - var nodeWidth = Math.max(110, Math.min(170, Math.floor(totalWidth / 6.4))), nodeHeight = 54, rowHeight = 74, pad = 16; + var nodeWidth = Math.max(140, Math.min(240, Math.floor(totalWidth / 5.4))), nodeHeight = 68, rowHeight = 88, pad = 16; var byColumn = COLUMNS.map(function () { return []; }); graph.nodes.forEach(function (n) { byColumn[n.column].push(n); }); var rows = Math.max.apply(null, byColumn.map(function (c) { return c.length; }).concat([1])); diff --git a/dDashboardServer/templates/network.jinja2 b/dDashboardServer/templates/network.jinja2 index e17f52c31..0b5bcf9dd 100644 --- a/dDashboardServer/templates/network.jinja2 +++ b/dDashboardServer/templates/network.jinja2 @@ -268,6 +268,23 @@ try { moved = JSON.parse(localStorage.getItem('network.positions') || '{}') || {}; } catch (e) { moved = {}; } function saveMoved() { try { localStorage.setItem('network.positions', JSON.stringify(moved)); } catch (e) { /* private window */ } } var busiest = 0; + // Splits text into at most `maxLines` lines of about `width` characters at spaces; the last line ends with … if cut + function wrapText(text, width, maxLines) { + var words = String(text).split(/\s+/), lines = [], line = ''; + words.forEach(function (word) { + if (!line) line = word; + else if ((line + ' ' + word).length <= width) line += ' ' + word; + else { lines.push(line); line = word; } + }); + if (line) lines.push(line); + lines = lines.map(function (l) { return l.length > width ? l.slice(0, width - 1) + '…' : l; }); + if (lines.length > maxLines) { + var last = lines.slice(maxLines - 1).join(' '); + lines = lines.slice(0, maxLines - 1).concat([last.length > width ? last.slice(0, width - 1) + '…' : last]); + } + return lines; + } + function renderDiagram(width) { var before = animateNext && lastLayout ? lastLayout.nodes : null; animateNext = false; @@ -297,12 +314,14 @@ var chars = Math.floor((L.nodeWidth - 16) / 6.6); var toggle = canToggle(n), open = isOpen(n); var nameChars = toggle ? chars - 5 : chars; - var name = n.label.length > nameChars ? n.label.slice(0, nameChars - 1) + '…' : n.label; + var nameLines = wrapText(n.label, nameChars, 2); html += '' + '' + - '' + esc(name) + ''; + nameLines.map(function (line, i) { return '' + esc(line) + ''; }).join(''); + var metaTop = y + 32 + (nameLines.length - 1) * 14; + if (nameLines.length > 1 && !n.open) meta = meta.slice(0, 2); meta.forEach(function (line, i) { - html += '' + esc(line.length > chars + 4 ? line.slice(0, chars + 3) + '…' : line) + ''; + html += '' + esc(line.length > chars + 4 ? line.slice(0, chars + 3) + '…' : line) + ''; }); if (n.noSplit && !toggle) html += 'This server reports only totals: its links are estimated≈'; else if (toggle) {