webtreemap-cdt
Advanced tools
Comparing version 3.1.1 to 3.2.0
@@ -75,2 +75,3 @@ /** | ||
} | ||
// TODO: update to use either SI units or Kibibytes | ||
function humanSizeCaption(n) { | ||
@@ -101,2 +102,12 @@ let units = ['', 'k', 'm', 'g']; | ||
const title = args.title || 'webtreemap'; | ||
let inlineScript = ` | ||
const data = ${JSON.stringify(node)}; | ||
const container = document.getElementById("treemap"); | ||
const treemap = new webtreemap.TreeMap(data, { | ||
caption: ${humanSizeCaption}, | ||
}); | ||
treemap.render(container); | ||
const resizeObserver = new ResizeObserver(() => treemap.layout(data, container)); | ||
resizeObserver.observe(container); | ||
`; | ||
let output = `<!doctype html> | ||
@@ -109,4 +120,5 @@ <title>${title}</title> | ||
#treemap { | ||
width: 800px; | ||
height: 600px; | ||
width: 95vw; | ||
max-width: 1300px; | ||
height: 80vh; | ||
} | ||
@@ -116,7 +128,6 @@ ${treemapCSS} | ||
<div id='treemap'></div> | ||
<script>const data = ${JSON.stringify(node)}</script> | ||
<script>${treemapJS}</script> | ||
<script>webtreemap.render(document.getElementById("treemap"), data, { | ||
caption: ${humanSizeCaption}, | ||
});</script> | ||
<script> | ||
${inlineScript} | ||
</script> | ||
`; | ||
@@ -123,0 +134,0 @@ if (args.output) { |
@@ -87,6 +87,8 @@ /** | ||
dom.className = NODE_CSS_CLASS; | ||
dom.setAttribute('role', 'treeitem'); | ||
dom.tabIndex = -1; | ||
if (this.options.caption) { | ||
const caption = document.createElement('div'); | ||
caption.className = CSS_PREFIX + 'caption'; | ||
caption.innerText = this.options.caption(node); | ||
caption.textContent = this.options.caption(node); | ||
dom.appendChild(caption); | ||
@@ -202,5 +204,7 @@ } | ||
style.height = px(heightPx - spacing); | ||
dom.setAttribute('aria-level', (level + 1).toString()); | ||
if (needsAppend) { | ||
node.dom.appendChild(dom); | ||
} | ||
this.associateCaptionWithLabelledBy(dom); | ||
this.layoutChildren(child, level + 1, widthPx, heightPx); | ||
@@ -240,4 +244,48 @@ // -1 so inner borders overlap. | ||
}; | ||
dom.onkeydown = e => { | ||
if (!(e.target instanceof HTMLElement)) | ||
return; | ||
let elem; | ||
switch (e.key) { | ||
// zoom to selection | ||
case 'Enter': | ||
const address = getAddress(e.target); | ||
this.zoom(address); | ||
return; | ||
// move selection focus | ||
case 'ArrowUp': | ||
elem = e.target.parentElement; | ||
// You cannot 'up' past the root | ||
if (elem === dom.parentElement) | ||
return; | ||
break; | ||
case 'ArrowDown': | ||
elem = e.target.querySelector('.webtreemap-node'); | ||
break; | ||
case 'ArrowLeft': | ||
elem = e.target.previousElementSibling; | ||
break; | ||
case 'ArrowRight': | ||
elem = e.target.nextElementSibling; | ||
break; | ||
} | ||
if (!elem) | ||
return; | ||
elem = elem; // lol | ||
// Reset tabIndex as we have a new focused item | ||
const tabIndex0Elems = Array.from(dom.querySelectorAll('*[tabindex="0"]')); | ||
for (const elem of tabIndex0Elems) { | ||
elem.tabIndex = -1; | ||
} | ||
e.preventDefault(); | ||
elem.tabIndex = 0; // most recently focused element should retain focusability | ||
elem.focus(); | ||
}; | ||
container.appendChild(dom); | ||
this.layout(this.node, container); | ||
// initialize root node | ||
this.associateCaptionWithLabelledBy(dom); | ||
dom.tabIndex = 0; | ||
dom.setAttribute('role', 'tree'); | ||
// calling elem.focus() on initial render isn't done here and is up to the library consumer. | ||
} | ||
@@ -272,2 +320,4 @@ layout(node, container) { | ||
style.zIndex = '1'; | ||
// TODO, tabindex 0 follows focus as the user moves around https://github.com/paulirish/webtreemap-cdt/pull/1#discussion_r316867244 | ||
// ... | ||
// See discussion in layout() about positioning. | ||
@@ -281,2 +331,7 @@ style.left = px(padLeft - 1); | ||
} | ||
associateCaptionWithLabelledBy(dom) { | ||
const captionId = '_wtm-cap-' + getAddress(dom).join('-'); | ||
dom.firstElementChild.id = captionId; | ||
dom.setAttribute('aria-labelledby', captionId); | ||
} | ||
} | ||
@@ -283,0 +338,0 @@ /** Main entry point; renders a tree into an HTML container. */ |
/** | ||
* webtreemap-cdt | ||
* v3.1.1 | ||
* v3.2.0 | ||
* https://github.com/paulirish/webtreemap-cdt | ||
@@ -186,6 +186,8 @@ */ | ||
dom.className = NODE_CSS_CLASS; | ||
dom.setAttribute('role', 'treeitem'); | ||
dom.tabIndex = -1; | ||
if (this.options.caption) { | ||
const caption = document.createElement('div'); | ||
caption.className = CSS_PREFIX + 'caption'; | ||
caption.innerText = this.options.caption(node); | ||
caption.textContent = this.options.caption(node); | ||
dom.appendChild(caption); | ||
@@ -301,5 +303,7 @@ } | ||
style.height = px(heightPx - spacing); | ||
dom.setAttribute('aria-level', (level + 1).toString()); | ||
if (needsAppend) { | ||
node.dom.appendChild(dom); | ||
} | ||
this.associateCaptionWithLabelledBy(dom); | ||
this.layoutChildren(child, level + 1, widthPx, heightPx); | ||
@@ -339,4 +343,48 @@ // -1 so inner borders overlap. | ||
}; | ||
dom.onkeydown = e => { | ||
if (!(e.target instanceof HTMLElement)) | ||
return; | ||
let elem; | ||
switch (e.key) { | ||
// zoom to selection | ||
case 'Enter': | ||
const address = getAddress(e.target); | ||
this.zoom(address); | ||
return; | ||
// move selection focus | ||
case 'ArrowUp': | ||
elem = e.target.parentElement; | ||
// You cannot 'up' past the root | ||
if (elem === dom.parentElement) | ||
return; | ||
break; | ||
case 'ArrowDown': | ||
elem = e.target.querySelector('.webtreemap-node'); | ||
break; | ||
case 'ArrowLeft': | ||
elem = e.target.previousElementSibling; | ||
break; | ||
case 'ArrowRight': | ||
elem = e.target.nextElementSibling; | ||
break; | ||
} | ||
if (!elem) | ||
return; | ||
elem = elem; // lol | ||
// Reset tabIndex as we have a new focused item | ||
const tabIndex0Elems = Array.from(dom.querySelectorAll('*[tabindex="0"]')); | ||
for (const elem of tabIndex0Elems) { | ||
elem.tabIndex = -1; | ||
} | ||
e.preventDefault(); | ||
elem.tabIndex = 0; // most recently focused element should retain focusability | ||
elem.focus(); | ||
}; | ||
container.appendChild(dom); | ||
this.layout(this.node, container); | ||
// initialize root node | ||
this.associateCaptionWithLabelledBy(dom); | ||
dom.tabIndex = 0; | ||
dom.setAttribute('role', 'tree'); | ||
// calling elem.focus() on initial render isn't done here and is up to the library consumer. | ||
} | ||
@@ -371,2 +419,4 @@ layout(node, container) { | ||
style.zIndex = '1'; | ||
// TODO, tabindex 0 follows focus as the user moves around https://github.com/paulirish/webtreemap-cdt/pull/1#discussion_r316867244 | ||
// ... | ||
// See discussion in layout() about positioning. | ||
@@ -380,2 +430,7 @@ style.left = px(padLeft - 1); | ||
} | ||
associateCaptionWithLabelledBy(dom) { | ||
const captionId = '_wtm-cap-' + getAddress(dom).join('-'); | ||
dom.firstElementChild.id = captionId; | ||
dom.setAttribute('aria-labelledby', captionId); | ||
} | ||
} | ||
@@ -382,0 +437,0 @@ /** Main entry point; renders a tree into an HTML container. */ |
{ | ||
"name": "webtreemap-cdt", | ||
"version": "3.1.1", | ||
"version": "3.2.0", | ||
"description": "treemap visualization", | ||
@@ -24,3 +24,6 @@ "main": "dist/webtreemap.js", | ||
"build": "tsc && rollup -c", | ||
"demo": "gdu -ab node_modules/ | node build/cli.js --title 'node_modules for webtreemap' > docs/index.html", | ||
"demo": "mkdir -p public; du -a node_modules/ | node build/cli.js --title 'node_modules for webtreemap' > public/index.html", | ||
"build:demo": "yarn build && yarn tsc --module commonjs && yarn demo", | ||
"watch": "find src | entr yarn build:demo", | ||
"clean": "rm -rf build dist public", | ||
"roll": "yarn build; gcp -f dist/webtreemap.js ~/chromium/src/third_party/third_party/devtools-frontend/src/front_end/third_party/webtreemap/webtreemap.js" | ||
@@ -27,0 +30,0 @@ }, |
@@ -53,8 +53,8 @@ # webtreemap | ||
I broke the CLI. Only working output is the dist/webtreemap.js now. | ||
Run `yarn run build` to compile TS -> build/JS (as esm) and then run rollup to make the dist (iife). | ||
Run `yarn run build` to compile TS -> build/JS with tsc and run rollup to make the dist. | ||
Run `yarn run build:demo` to create a `public/index.html` demo page. | ||
Run `yarn watch` to use `entr` to do _`build:demo`_ on a watchloop. | ||
## License | ||
@@ -67,3 +67,3 @@ | ||
* I like the breadcrumb navigation in the plotly treemap. https://plotly.com/javascript/treemaps/ | ||
* I like the breadcrumb navigation in the plotly treemap. https://plotly.com/javascript/treemaps/ | ||
* The _imported path_ in [rollup-plugin-visualizer](https://github.com/btd/rollup-plugin-visualizer) is nice, but the interation aint. [eg1](https://obeisant-horses.surge.sh/stats.html), [eg2](https://obeisant-horses.surge.sh/stats-old-rxjs.html) |
57406
10
1075