Trying in-tree D3 treemap

This commit is contained in:
thomasjm 2024-02-13 01:05:02 -08:00
parent 02e62d08d9
commit 89219e7b35
4 changed files with 51 additions and 210 deletions

181
package-lock.json generated
View File

@ -12,6 +12,7 @@
"@codedown/react-d3-treemap": "^1.0.31",
"@material-ui/core": "^4.12.3",
"apexcharts": "^3.27.3",
"d3-array": "^3.2.4",
"d3-hierarchy": "^3.1.2",
"d3-interpolate": "^3.0.1",
"d3-scale": "^4.0.2",
@ -26,6 +27,7 @@
"typescript": "^4.3.5"
},
"devDependencies": {
"@types/d3-array": "^3.2.1",
"@types/d3-hierarchy": "^3.1.6",
"@types/d3-interpolate": "^3.0.4",
"@types/d3-scale": "^4.0.8",
@ -221,11 +223,6 @@
"react-dom": "15.x.x || 17.x.x"
}
},
"node_modules/@codedown/react-d3-treemap/node_modules/@types/d3-array": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz",
"integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg=="
},
"node_modules/@codedown/react-d3-treemap/node_modules/@types/d3-format": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.4.tgz",
@ -2214,6 +2211,11 @@
"node": ">=10.13.0"
}
},
"node_modules/@types/d3-array": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz",
"integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg=="
},
"node_modules/@types/d3-color": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz",
@ -2584,96 +2586,6 @@
"hyphenate-style-name": "^1.0.3"
}
},
"node_modules/css-select": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
"integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
"optional": true,
"peer": true,
"dependencies": {
"boolbase": "^1.0.0",
"css-what": "^6.1.0",
"domhandler": "^5.0.2",
"domutils": "^3.0.1",
"nth-check": "^2.0.1"
},
"funding": {
"url": "https://github.com/sponsors/fb55"
}
},
"node_modules/css-select/node_modules/dom-serializer": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
"optional": true,
"peer": true,
"dependencies": {
"domelementtype": "^2.3.0",
"domhandler": "^5.0.2",
"entities": "^4.2.0"
},
"funding": {
"url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
}
},
"node_modules/css-select/node_modules/domhandler": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
"optional": true,
"peer": true,
"dependencies": {
"domelementtype": "^2.3.0"
},
"engines": {
"node": ">= 4"
},
"funding": {
"url": "https://github.com/fb55/domhandler?sponsor=1"
}
},
"node_modules/css-select/node_modules/domutils": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
"integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==",
"optional": true,
"peer": true,
"dependencies": {
"dom-serializer": "^2.0.0",
"domelementtype": "^2.3.0",
"domhandler": "^5.0.3"
},
"funding": {
"url": "https://github.com/fb55/domutils?sponsor=1"
}
},
"node_modules/css-select/node_modules/entities": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
"optional": true,
"peer": true,
"engines": {
"node": ">=0.12"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/css-tree": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz",
"integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==",
"optional": true,
"peer": true,
"dependencies": {
"mdn-data": "2.0.30",
"source-map-js": "^1.0.1"
},
"engines": {
"node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
}
},
"node_modules/css-vendor": {
"version": "2.0.8",
"resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.8.tgz",
@ -2694,42 +2606,6 @@
"url": "https://github.com/sponsors/fb55"
}
},
"node_modules/csso": {
"version": "5.0.5",
"resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz",
"integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==",
"optional": true,
"peer": true,
"dependencies": {
"css-tree": "~2.2.0"
},
"engines": {
"node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0",
"npm": ">=7.0.0"
}
},
"node_modules/csso/node_modules/css-tree": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz",
"integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==",
"optional": true,
"peer": true,
"dependencies": {
"mdn-data": "2.0.28",
"source-map-js": "^1.0.1"
},
"engines": {
"node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0",
"npm": ">=7.0.0"
}
},
"node_modules/csso/node_modules/mdn-data": {
"version": "2.0.28",
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz",
"integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==",
"optional": true,
"peer": true
},
"node_modules/csstype": {
"version": "2.6.21",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.21.tgz",
@ -3637,13 +3513,6 @@
"node": ">=10"
}
},
"node_modules/mdn-data": {
"version": "2.0.30",
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz",
"integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==",
"optional": true,
"peer": true
},
"node_modules/micromatch": {
"version": "4.0.5",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
@ -4181,16 +4050,6 @@
"node": ">=0.10.0"
}
},
"node_modules/source-map-js": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
"optional": true,
"peer": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/srcset": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/srcset/-/srcset-4.0.0.tgz",
@ -4371,32 +4230,6 @@
"node": ">= 0.8.0"
}
},
"node_modules/svgo": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/svgo/-/svgo-3.2.0.tgz",
"integrity": "sha512-4PP6CMW/V7l/GmKRKzsLR8xxjdHTV4IMvhTnpuHwwBazSIlw5W/5SmPjN8Dwyt7lKbSJrRDgp4t9ph0HgChFBQ==",
"optional": true,
"peer": true,
"dependencies": {
"@trysound/sax": "0.2.0",
"commander": "^7.2.0",
"css-select": "^5.1.0",
"css-tree": "^2.3.1",
"css-what": "^6.1.0",
"csso": "^5.0.5",
"picocolors": "^1.0.0"
},
"bin": {
"svgo": "bin/svgo"
},
"engines": {
"node": ">=14.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/svgo"
}
},
"node_modules/tachyons": {
"version": "4.12.0",
"resolved": "https://registry.npmjs.org/tachyons/-/tachyons-4.12.0.tgz",

View File

@ -7,7 +7,7 @@
},
"scripts": {
"build": "rimraf ./dist && parcel build ./src/index.html --public-url '/'",
"start": "parcel ./src/index.html"
"start": "parcel ./src/index_test.html"
},
"repository": {
"type": "git",
@ -20,6 +20,7 @@
},
"homepage": "https://github.com/codedownio/time-ghc-modules#readme",
"devDependencies": {
"@types/d3-array": "^3.2.1",
"@types/d3-hierarchy": "^3.1.6",
"@types/d3-interpolate": "^3.0.4",
"@types/d3-scale": "^4.0.8",
@ -35,6 +36,7 @@
"@codedown/react-d3-treemap": "^1.0.31",
"@material-ui/core": "^4.12.3",
"apexcharts": "^3.27.3",
"d3-array": "^3.2.4",
"d3-hierarchy": "^3.1.2",
"d3-interpolate": "^3.0.1",
"d3-scale": "^4.0.2",

28
src/CleanTreeMap.tsx Normal file
View File

@ -0,0 +1,28 @@
import { type TreemapLayout, hierarchy, treemap, treemapBinary } from "d3-hierarchy";
import { interpolateRgb } from "d3-interpolate";
import { scaleOrdinal } from "d3-scale";
import { schemeCategory10 } from "d3-scale-chromatic";
import { select } from "d3-selection";
import { isEqual, keys } from "lodash";
import { PureComponent } from "react";
interface Props<D> {
data: Tree<D>;
width: number;
height: number;
labelFn: (d: D) => string;
subLabelFn: (d: D) => string;
valueFn: (d: D) => number;
}
export default function CleanTreeMap<D>({data, width, height, labelFn, subLabelFn, valueFn}: Props<D>) {
return (
<p>
TODO
</p>
)
}

View File

@ -4,12 +4,14 @@ import * as chromatic from "d3-scale-chromatic";
import { debounce } from "lodash";
import { CSSProperties, useEffect, useMemo, useRef, useState} from "react";
import CleanTreeMap from "./CleanTreeMap";
import buildNestedData, {removeEmptyNodes} from "./TreeMap/BuildData";
import {formatBytes, formatTime} from "./Util";
// import SimpleD3TreeMap from "./D3TreeMap";
import D3TreeMap, { ColorModel, NumberOfChildrenPlacement } from "@codedown/react-d3-treemap";
// import D3TreeMap, { ColorModel, NumberOfChildrenPlacement } from "react-d3-treemap";
interface Props {
@ -62,41 +64,17 @@ export default function TreeMap({aggregate, data}: Props) {
return (
<div ref={ref}
style={wrapperStyle}>
{dimensions &&
<D3TreeMap<Tree<TreeNode>>
key={aggregate}
id="myTreeMap"
width={dimensions.width + paddingPx}
svgStyle={svgStyle}
height={dimensions.height}
data={nestedData}
valueUnit=""
levelsToDisplay={2}
paddingInner={paddingPx}
paddingOuter={constZero}
paddingTop={constZero}
nodeClassName="AppTreeMap__node"
nodeStyle={{
fontSize: 12,
paddingTop: 2,
paddingLeft: 5,
paddingRight: 5,
fontFamily: "Roboto, Helvetica, Arial, sans-serif",
}}
hideNumberOfChildren={true}
customD3ColorScale={scaleSequential(
chromatic.interpolateSpectral
)}
colorModel={ColorModel.OneEachChildren}
darkNodeBorderColor="silver"
darkNodeTextColor="white"
lightNodeBorderColor="brown"
lightNodeTextColor="brown"
valueFn={aggregate === "time" ? formatTime : formatBytes}
breadCrumbClassName="ba b--silver pa1 mv1"
{dimensions &&
<CleanTreeMap
width={dimensions.width}
height={dimensions.height}
data={nestedData}
labelFn={(x) => x.name}
subLabelFn={(d, value) => aggregate === "time" ? formatTime(value) : formatBytes(value)}
valueFn={(x) => x.value}
childrenFn={(x) => x.children}
/>
}
}
</div>
);
}