feat: move git graph legend to top-right corner to avoid overlap with graph
Deploy PR-Helper / deploy (push) Successful in 26s
Deploy PR-Helper / deploy (push) Successful in 26s
This commit is contained in:
@@ -129,6 +129,10 @@ const GitGraph = {
|
||||
// Draw branch labels on the right side
|
||||
this._drawBranchLabels(g, nodeMap, this._laneBranchMap, laneWidth, maxLane);
|
||||
|
||||
// Draw legend in top-right corner
|
||||
const svgWidth = Math.max(width, graphWidth);
|
||||
this._drawLegend(svg, this._laneBranchMap, svgWidth);
|
||||
|
||||
// Store for updates
|
||||
this._nodeMap = nodeMap;
|
||||
|
||||
@@ -429,6 +433,81 @@ const GitGraph = {
|
||||
});
|
||||
},
|
||||
|
||||
// Draw legend in top-right corner of SVG
|
||||
_drawLegend(svg, laneBranchMap, svgWidth) {
|
||||
const legendPadding = 12;
|
||||
const itemHeight = 20;
|
||||
const circleRadius = 5;
|
||||
const fontSize = 11;
|
||||
|
||||
// Collect unique branches
|
||||
const branches = [];
|
||||
const seen = new Set();
|
||||
Object.values(laneBranchMap).forEach(info => {
|
||||
if (!seen.has(info.name)) {
|
||||
seen.add(info.name);
|
||||
branches.push(info);
|
||||
}
|
||||
});
|
||||
|
||||
if (branches.length === 0) return;
|
||||
|
||||
// Create legend group
|
||||
const legend = svg.append('g')
|
||||
.attr('class', 'graph-legend');
|
||||
|
||||
// Calculate legend dimensions
|
||||
const tempText = svg.append('text')
|
||||
.attr('font-size', `${fontSize}px`)
|
||||
.attr('font-family', 'system-ui, -apple-system, sans-serif');
|
||||
|
||||
let maxTextWidth = 0;
|
||||
branches.forEach(b => {
|
||||
tempText.text(b.name);
|
||||
maxTextWidth = Math.max(maxTextWidth, tempText.node().getBBox().width);
|
||||
});
|
||||
tempText.remove();
|
||||
|
||||
const legendWidth = circleRadius * 2 + 8 + maxTextWidth + legendPadding * 2;
|
||||
const legendHeight = branches.length * itemHeight + legendPadding * 2;
|
||||
|
||||
// Position in top-right
|
||||
const legendX = svgWidth - legendWidth - 10;
|
||||
const legendY = 10;
|
||||
|
||||
legend.attr('transform', `translate(${legendX},${legendY})`);
|
||||
|
||||
// Background
|
||||
legend.append('rect')
|
||||
.attr('width', legendWidth)
|
||||
.attr('height', legendHeight)
|
||||
.attr('rx', 6)
|
||||
.attr('ry', 6)
|
||||
.attr('fill', 'white')
|
||||
.attr('stroke', '#e5e7eb')
|
||||
.attr('stroke-width', 1)
|
||||
.attr('opacity', 0.95);
|
||||
|
||||
// Legend items
|
||||
branches.forEach((branch, i) => {
|
||||
const itemY = legendPadding + i * itemHeight + itemHeight / 2;
|
||||
|
||||
legend.append('circle')
|
||||
.attr('cx', legendPadding + circleRadius)
|
||||
.attr('cy', itemY)
|
||||
.attr('r', circleRadius)
|
||||
.attr('fill', branch.color);
|
||||
|
||||
legend.append('text')
|
||||
.attr('x', legendPadding + circleRadius * 2 + 8)
|
||||
.attr('y', itemY + 4)
|
||||
.text(branch.name)
|
||||
.attr('font-size', `${fontSize}px`)
|
||||
.attr('fill', '#374151')
|
||||
.attr('font-family', 'system-ui, -apple-system, sans-serif');
|
||||
});
|
||||
},
|
||||
|
||||
_updateSelectionVisuals() {
|
||||
if (!this._nodes || !this._lanes) return;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user