Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiline legend items #173

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
83 changes: 68 additions & 15 deletions docs/radar.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ function radar_visualization(config) {
config.title_offset = config.title_offset || { x: -675, y: -420 };
config.footer_offset = config.footer_offset || { x: -155, y: 450 };
config.legend_column_width = config.legend_column_width || 140
config.line_height = 10

// custom random number generator, to make random sequence reproducible
// source: https://stackoverflow.com/questions/521295
Expand Down Expand Up @@ -164,7 +165,7 @@ function radar_visualization(config) {

// partition entries according to segments
var segmented = new Array(4);
for (var quadrant = 0; quadrant < 4; quadrant++) {
for (let quadrant = 0; quadrant < 4; quadrant++) {
segmented[quadrant] = new Array(4);
for (var ring = 0; ring < 4; ring++) {
segmented[quadrant][ring] = [];
Expand All @@ -177,7 +178,7 @@ function radar_visualization(config) {

// assign unique sequential id to each entry
var id = 1;
for (var quadrant of [2,3,1,0]) {
for (quadrant of [2,3,1,0]) {
for (var ring = 0; ring < 4; ring++) {
var entries = segmented[quadrant][ring];
entries.sort(function(a,b) { return a.label.localeCompare(b.label); })
Expand Down Expand Up @@ -272,12 +273,14 @@ function radar_visualization(config) {
}
}

function legend_transform(quadrant, ring, legendColumnWidth, index=null) {
var dx = ring < 2 ? 0 : legendColumnWidth;
var dy = (index == null ? -16 : index * 12);
function legendTransform(quadrant, ring, legendColumnWidth, index=null, previousHeight = null) {
const dx = ring < 2 ? 0 : legendColumnWidth;
let dy = (index == null ? -16 : index * config.line_height);

if (ring % 2 === 1) {
dy = dy + 36 + segmented[quadrant][ring-1].length * 12;
dy = dy + 36 + previousHeight;
}

return translate(
config.legend_offset[quadrant].x + dx,
config.legend_offset[quadrant].y + dy
Expand All @@ -286,7 +289,6 @@ function radar_visualization(config) {

// draw title and legend (only in print layout)
if (config.print_layout) {

// title
radar.append("a")
.attr("href", config.repo_url)
Expand Down Expand Up @@ -316,8 +318,8 @@ function radar_visualization(config) {
.style("font-size", "12px");

// legend
var legend = radar.append("g");
for (var quadrant = 0; quadrant < 4; quadrant++) {
const legend = radar.append("g");
for (let quadrant = 0; quadrant < 4; quadrant++) {
legend.append("text")
.attr("transform", translate(
config.legend_offset[quadrant].x,
Expand All @@ -327,9 +329,13 @@ function radar_visualization(config) {
.style("font-family", config.font_family)
.style("font-size", "18px")
.style("font-weight", "bold");
for (var ring = 0; ring < 4; ring++) {
let previousLegendHeight = 0
for (let ring = 0; ring < 4; ring++) {
if (ring % 2 === 0) {
previousLegendHeight = 0
}
legend.append("text")
.attr("transform", legend_transform(quadrant, ring, config.legend_column_width))
.attr("transform", legendTransform(quadrant, ring, config.legend_column_width, null, previousLegendHeight))
.text(config.rings[ring].name)
.style("font-family", config.font_family)
.style("font-size", "12px")
Expand All @@ -347,18 +353,65 @@ function radar_visualization(config) {
return (d.link && config.links_in_new_tabs) ? "_blank" : null;
})
.append("text")
.attr("transform", function(d, i) { return legend_transform(quadrant, ring, config.legend_column_width, i); })
.attr("transform", function(d, i) { return legendTransform(quadrant, ring, config.legend_column_width, i, previousLegendHeight); })
.attr("class", "legend" + quadrant + ring)
.attr("id", function(d, i) { return "legendItem" + d.id; })
.text(function(d, i) { return d.id + ". " + d.label; })
.text(function(d) { return d.id + ". " + d.label; })
.style("font-family", config.font_family)
.style("font-size", "11px")
.on("mouseover", function(d) { showBubble(d); highlightLegendItem(d); })
.on("mouseout", function(d) { hideBubble(d); unhighlightLegendItem(d); });
.on("mouseout", function(d) { hideBubble(d); unhighlightLegendItem(d); })
.call(wrapText)
.each(function() {
previousLegendHeight += d3.select(this).node().getBBox().height;
});
}
}
}

function wrapText(text) {
let heightForNextElement = 0;

text.each(function() {
const textElement = d3.select(this);
const words = textElement.text().split(" ");
let line = [];

// Use '|' at the end of the string so that spaces are not trimmed during rendering.
const number = `${textElement.text().split(".")[0]}. |`;
const legendNumberText = textElement.append("tspan").text(number);
const legendBar = textElement.append("tspan").text('|');
const numberWidth = legendNumberText.node().getComputedTextLength() - legendBar.node().getComputedTextLength();

textElement.text(null);

let tspan = textElement
.append("tspan")
.attr("x", 0)
.attr("y", heightForNextElement)
.attr("dy", 0);

for (let i = 0; i < words.length; i++) {
line.push(words[i]);
tspan.text(line.join(" "));

if (tspan.node().getComputedTextLength() > config.legend_column_width) {
line.pop();
tspan.text(line.join(" "));
line = [words[i]];

tspan = textElement.append("tspan")
.attr("x", numberWidth)
.attr("dy", config.line_height)
.text(words[i]);
}
}

const textBoundingBox = textElement.node().getBBox();
heightForNextElement = textBoundingBox.y + textBoundingBox.height;
});
}

// layer for entries
var rink = radar.append("g")
.attr("id", "rink");
Expand Down Expand Up @@ -425,7 +478,7 @@ function radar_visualization(config) {
.enter()
.append("g")
.attr("class", "blip")
.attr("transform", function(d, i) { return legend_transform(d.quadrant, d.ring, config.legend_column_width, i); })
.attr("transform", function(d, i) { return legendTransform(d.quadrant, d.ring, config.legend_column_width, i); })
.on("mouseover", function(d) { showBubble(d); highlightLegendItem(d); })
.on("mouseout", function(d) { hideBubble(d); unhighlightLegendItem(d); });

Expand Down