Skip to content

Commit

Permalink
feat: add visual debug mode
Browse files Browse the repository at this point in the history
Fixes #4
  • Loading branch information
kevinschaul committed Jul 2, 2023
1 parent 2382d60 commit b44a42a
Show file tree
Hide file tree
Showing 7 changed files with 1,036 additions and 570 deletions.
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,20 @@ This module exports two types of overlap avoider functions, depending on how you

In both cases, you'll pass in the parent Element, an array of label groups that define how to resolve overlaps, and global options.

### `avoidOverlapNudge()`
### `AvoidOverlapNudge`

Use this when you want any overlapping labels to be nudged in a certain direction. This can be helpful if the thing you're labeling is large. The lower-priority label will be nudged until it no longer overlaps.

```js
import { avoidOverlapNudge } from 'avoid-overlap';
import { AvoidOverlapNudge } from 'avoid-overlap';
import { select, selectAll } from 'd3-selection';

const parent = select('.chart');
const headers = selectAll('.label-header');
const subheads = selectAll('.label-subhead');

avoidOverlapNudge(
const avoidOverlapNudge = new AvoidOverlapNudge();
avoidOverlapNudge.run(
parent,
[
{
Expand Down Expand Up @@ -63,7 +64,7 @@ avoidOverlapNudge(
| parentMargin | object | `{ top: 0, right: 0, bottom: 0, left: 0 }` | How much extra spacing to consider for collisions with the parent |
| maxAttempts | number | 3 | How many iterations to try finding collisions before giving up |

### `avoidOverlapChoices()`
### `AvoidOverlapChoices`

Use this when you have a few valid choices for positining labels. This can be helpful for drawing arrows, for example, when you could put the label above or below the thing you're labeling.

Expand All @@ -81,7 +82,8 @@ const arrowBottom = (node) => {
/* TODO draw the arrow at the bottom */
};

avoidOverlapChoices(
const avoidOverlapChoices = new AvoidOverlapChoices();
avoidOverlapChoices.run(
parent,
[
{
Expand Down
65 changes: 65 additions & 0 deletions dist/debug.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
const scale = (domain, range, value)=>{
const result = range[0] + (range[1] - range[0]) / (domain[1] - domain[0]) * (value - domain[0]);
if (isNaN(result)) {
return range[0];
} else {
return result;
}
};
export const defaultDebugFunc = (tree, parentBounds, uid)=>{
const bodies = tree.all();
// TODO build a unique class name so we can support multiple instances on the same page
const debugClassName = `avoid-overlap-debugger-${uid}`;
const root = document.querySelector('body');
if (root) {
let debugEl = root.querySelector(`.${debugClassName}`);
if (!debugEl) {
debugEl = document.createElement('div');
root.append(debugEl);
}
const colors = [
'#e41a1c',
'#377eb8',
'#4daf4a',
'#984ea3',
'#ff7f00',
'#ffff33',
'#a65628',
'#f781bf',
'#999999'
];
// TODO rewrite this by actually creating nodes, adding attributes, etc.
debugEl.outerHTML = `
<div class="${debugClassName}" style="position: absolute; top:${parentBounds.y + window.scrollY}px; left:${parentBounds.x + window.scrollX}px; z-index: 10000;">
<svg width="${parentBounds.width}" height="${parentBounds.height}">
${bodies.map((body, bodyI)=>{
const nPositions = body.positionHistory.length;
const color = colors[bodyI % colors.length];
return `<g data-text="${body.node.textContent}">
${body.positionHistory.map((position, positionI)=>{
const opacity = scale([
nPositions - 1,
0
], [
0.7,
0.4
], positionI);
return `
<path d="
M${position.minX},${position.minY}
L${position.maxX},${position.minY}
L${position.maxX},${position.maxY}
L${position.minX},${position.maxY}
Z
"
style="stroke: #000; fill: ${color}; opacity: ${opacity};"
/>
<text x=${position.minX + 2} y=${position.minY + 13} style="font-size: 14px">${bodyI}:${positionI}</text>
`;
}).join('')}</g>`;
}).join('')}
</svg>
</div>
`;
}
};
Loading

0 comments on commit b44a42a

Please sign in to comment.