@d3plus/core 3.0.5 → 3.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  /*
2
- @d3plus/core v3.0.5
2
+ @d3plus/core v3.0.6
3
3
  Data visualization made easy. A javascript library that extends the popular D3.js to enable fast and beautiful visualizations.
4
4
  Copyright (c) 2025 D3plus - https://d3plus.org
5
5
  @license MIT
@@ -3971,7 +3971,7 @@ function uf(t,n){t!==n&&(t&&(t.p=n),n)&&(n.n=t)}af||(af=1,ch.exports=((dh=rf.pro
3971
3971
  @desc Renders the legend if this._legend is not falsy.
3972
3972
  @param {Array} data The filtered data array to be displayed.
3973
3973
  @private
3974
- */function pf(t=[]){let e=[],i=(t,n,e)=>{var i=this._shape(t,n),i=("fill"===e&&"Line"===i&&(e="stroke"),(this._shapeConfig[i]&&this._shapeConfig[i][e]?this._shapeConfig[i]:this._shapeConfig)[e]);return"function"==typeof i?i.bind(this)(t,n):i};var n=(n,e)=>df.map(t=>i(n,e,t)).join("_"),a=(qi(this._colorScale?t.filter((t,n)=>void 0===this._colorScale(t,n)):t,t=>e.push(_u(t,this._aggs)),n),e.sort(this._legendSort),e.map((t,n)=>this._ids(t,n).slice(0,this._drawDepth+1)));for(let n=this._legendDepth=0;n<=this._drawDepth;n++){var r=a.map(t=>t[n]);if(!r.some(t=>t instanceof Array)&&Array.from(new Set(r)).length===e.length){this._legendDepth=n;break}}let o=(t,n)=>{let e=this._id(t,n);return e instanceof Array&&(e=e[0]),this._hidden.includes(e)||this._solo.length&&!this._solo.includes(e)};var t=this._legendClass.outerBounds(),s=this.config();let l=this._legendPosition.bind(this)(s);[!1,"top","bottom","left","right"].includes(l)||(l="bottom");var h=["top","bottom"].includes(l),u=this._legendPadding()?this._padding:{top:0,right:0,bottom:0,left:0},c={transform:`translate(${h?this._margin.left+u.left:this._margin.left}, ${h?this._margin.top:this._margin.top+u.top})`},s=this._legend.bind(this)(s,e),c=Nt("g.d3plus-viz-legend",{condition:s&&!this._legendConfig.select,enter:c,parent:this._select,duration:this._duration,update:c}).node();this._legendClass.id(n).align(h?"center":l).direction(h?"row":"column").duration(this._duration).data(s?e:[]).height(h?this._height-(this._margin.bottom+this._margin.top):this._height-(this._margin.bottom+this._margin.top+u.bottom+u.top)).locale(this._locale).parent(this).select(c).verticalAlign(h?l:"middle").width(h?this._width-(this._margin.left+this._margin.right+u.left+u.right):this._width-(this._margin.left+this._margin.right)).shapeConfig(Lt.bind(this)(this._shapeConfig,"legend")).shapeConfig({fill:(t,n)=>o(t,n)?this._hiddenColor(t,n):i(t,n,"fill"),labelConfig:{fontOpacity:(t,n)=>o(t,n)?this._hiddenOpacity(t,n):1}}).config(this._legendConfig).render(),!this._legendConfig.select&&t.height&&(this._margin[l]+=h?t.height+2*this._legendClass.padding():t.width+2*this._legendClass.padding())}
3974
+ */function pf(t=[]){let e=[],i=(t,n,e)=>{var i=this._shape(t,n),i=("fill"===e&&"Line"===i&&(e="stroke"),(this._shapeConfig[i]&&this._shapeConfig[i][e]?this._shapeConfig[i]:this._shapeConfig)[e]);return"function"==typeof i?i.bind(this)(t,n):i};var n=(n,e)=>df.map(t=>i(n,e,t)).join("_"),a=(qi(this._colorScale?t.filter((t,n)=>void 0===this._colorScale(t,n)):t,t=>e.push(_u(t,this._aggs)),n),e.sort(this._legendSort),e.map((t,n)=>this._ids(t,n).slice(0,this._drawDepth+1)));for(let n=this._legendDepth=0;n<=this._drawDepth;n++){var r=a.map(t=>t[n]);if(!r.some(t=>t instanceof Array)&&Array.from(new Set(r)).length===e.length){this._legendDepth=n;break}}let o=(t,n)=>{let e=this._id(t,n);return e instanceof Array&&(e=e[0]),this._hidden.includes(e)||this._solo.length&&!this._solo.includes(e)};var t=this._legendClass.outerBounds(),s=this.config();let l=this._legendPosition.bind(this)(s);[!1,"top","bottom","left","right"].includes(l)||(l="bottom");var h=["top","bottom"].includes(l),u=this._legendPadding()?this._padding:{top:0,right:0,bottom:0,left:0},c={transform:`translate(${h?this._margin.left+u.left:this._margin.left}, ${h?this._margin.top:this._margin.top+u.top})`},s=this._legend.bind(this)(s,e),c=Nt("g.d3plus-viz-legend",{condition:s&&!this._legendConfig.select,enter:c,parent:this._select,duration:this._duration,update:c}).node();this._legendClass.id(n).align(h?"center":l).direction(h?"row":"column").duration(this._duration).data(s?e:[]).height(h?this._height-(this._margin.bottom+this._margin.top):this._height-(this._margin.bottom+this._margin.top+u.bottom+u.top)).locale(this._locale).parent(this).select(c).shape((t,n)=>"Circle"===this._shape(t,n)?"Circle":"Rect").verticalAlign(h?l:"middle").width(h?this._width-(this._margin.left+this._margin.right+u.left+u.right):this._width-(this._margin.left+this._margin.right)).shapeConfig(Lt.bind(this)(this._shapeConfig,"legend")).shapeConfig({fill:(t,n)=>o(t,n)?this._hiddenColor(t,n):i(t,n,"fill"),labelConfig:{fontOpacity:(t,n)=>o(t,n)?this._hiddenOpacity(t,n):1}}).config(this._legendConfig).render(),!this._legendConfig.select&&t.height&&(this._margin[l]+=h?t.height+2*this._legendClass.padding():t.width+2*this._legendClass.padding())}
3975
3975
  /**
3976
3976
  @function _drawSubtitle
3977
3977
  @desc Draws a subtitle if this._subtitle is defined.
@@ -4325,13 +4325,9 @@ return H("body").on("touchstart."+this._uuid,
4325
4325
  */fontFamily(t){if(arguments.length){let n={fontFamily:t},e={titleConfig:n,shapeConfig:{labelConfig:n}};return this.shapeConfig({labelConfig:n}),this.colorScaleConfig({axisConfig:e}),["axis","column","row","timeline","x","y","x2","y2"].forEach(t=>{t+="Config";this[t]&&this[t](e)}),["back","title","total","subtitle"].forEach(t=>{t+="Config";this[t]&&this[t](n)}),this.tooltipConfig({tooltipStyle:{"font-family":ze(t)}}),this._fontFamily=t,this}return this._fontFamily}
4326
4326
  /**
4327
4327
  @memberof Viz
4328
- @desc If *value* is specified, sets the group accessor(s) to the specified string, function, or array of values and returns the current class instance.
4328
+ @desc Defines the mapping between data and shape. The value can be a String matching a key in each data point (default is "id"), or an accessor Function that returns a unique value for each data point. Additionally, an Array of these values may be provided if the visualization supports nested hierarchies.
4329
4329
  @param {String|Function|Array} [*value*]
4330
4330
  @chainable
4331
- @example
4332
- function value(d) {
4333
- return d.id;
4334
- }
4335
4331
  */groupBy(t){return arguments.length?((this._groupByRaw=t)instanceof Array||(t=[t]),this._groupBy=t.map(t=>"function"==typeof t?t:(this._aggs[t]||(this._aggs[t]=(t,n)=>{t=pu(t.map(n));return 1===t.length?t[0]:t}),p(t))),this):this._groupBy}
4336
4332
  /**
4337
4333
  @memberof Viz
@@ -4461,8 +4457,8 @@ return H("body").on("touchstart."+this._uuid,
4461
4457
  */select(t){return arguments.length?(this._select=H(t),this):this._select}
4462
4458
  /**
4463
4459
  @memberof Viz
4464
- @desc If *value* is specified, sets the shape accessor to the specified function or number and returns the current class instance.
4465
- @param {Function|String} [*value*]
4460
+ @desc Changes the primary shape used to represent each data point in a visualization. Not all visualizations support changing shapes, this method can be provided the String name of a D3plus shape class (for example, "Rect" or "Circle"), or an accessor Function that returns the String class name to be used for each individual data point.
4461
+ @param {String|Function} [*value*]
4466
4462
  @chainable
4467
4463
  */shape(t){return arguments.length?(this._shape="function"==typeof t?t:Bt(t),this):this._shape}
4468
4464
  /**
@@ -7255,15 +7251,15 @@ r=r<0?r%U9+U9:r)?this._+="A"+e+","+e+",0,1,"+u+","+(t-o)+","+(n-s)+"A"+e+","+e+"
7255
7251
  /**
7256
7252
  Extends the draw behavior of the abstract Viz class.
7257
7253
  @private
7258
- */_draw(t){super._draw(t);let n="vertical"===this._orient?this._height-this._margin.top-this._margin.bottom:this._width-this._margin.left-this._margin.right,r="vertical"===this._orient?"left":"top",e=this,i=`translate(${this._margin.left}, ${this._margin.top})`,o="horizontal"===this._orient?this._height-this._margin.top-this._margin.bottom:this._width-this._margin.left-this._margin.right;t=this._treeData=this._tree.separation(this._separation).size([o,n])(B6({key:"root",values:mu(this._filteredData,this._groupBy.slice(0,this._drawDepth+1))},t=>t.key&&t.values?t.values:null).sort(this._sort)).descendants().filter(t=>t.depth<=this._groupBy.length&&t.parent);
7254
+ */_draw(t){super._draw(t);let o="vertical"===this._orient,r="horizontal"===this._orient,n=o?this._height-this._margin.top-this._margin.bottom:this._width-this._margin.left-this._margin.right,s=o?"left":"top",e=this,i=`translate(${this._margin.left}, ${this._margin.top})`,l=r?this._height-this._margin.top-this._margin.bottom:this._width-this._margin.left-this._margin.right;t=this._treeData=this._tree.separation(this._separation).size([l,n])(B6({key:"root",values:mu(this._filteredData,this._groupBy.slice(0,this._drawDepth+1))},t=>t.key&&t.values?t.values:null).sort(this._sort)).descendants().filter(t=>t.depth<=this._groupBy.length&&t.parent);
7259
7255
  /**
7260
7256
  Merges the values of a given nest branch.
7261
7257
  @private
7262
- */t.forEach((t,n)=>{t.data.key&&t.data.values&&(t.data=function n(t){return _u(t.values.map(t=>t.key&&t.values?n(t):t),e._aggs)}(t.data)),t.__d3plus__=!0,t.i=n});let a=this._shapeConfig.r;"function"!=typeof a&&(a=Bt(a));var s=Ot(t,t=>1===t.depth?a(t.data,t.i):0),l=Ot(t,t=>t.children?0:a(t.data,t.i)),h=Hi(t,t=>t.y);this._labelHeight=Dt(["vertical"===this._orient?50:100,(h[1]-s-l)/(this._groupBy.length+1)]),this._labelWidths=mu(t,t=>t.depth).map(a=>a.values.reduce((t,n,e)=>{var i=e<a.values.length-1?a.values[e+1].x:o+this._margin[r],e=e?a.values[e-1].x:this._margin[r];return Dt([t,i-n.x,n.x-e])},o));let u=$a().domain(h).range([s+this._labelHeight,n-l-this._labelHeight]);t.forEach(t=>{var n=u(t.y);"horizontal"===this._orient?(t.y=t.x,t.x=n):t.y=n});h={parent:this._select,enter:{transform:i},update:{transform:i}};return this._shapes.push((new zc).data(t.filter(t=>1<t.depth)).select(Nt("g.d3plus-Tree-Links",h).node()).config(Lt.bind(this)(this._shapeConfig,"shape","Path")).config({d:t=>{let n=this._shapeConfig.r;"function"==typeof n&&(n=n(t.data,t.i));var e=t.parent.x-t.x+("vertical"===this._orient?0:n),t=t.parent.y-t.y+("vertical"===this._orient?n:0),i="vertical"===this._orient?0:-n,a="vertical"===this._orient?-n:0;return"vertical"===this._orient?`M${i},${a}C${i},${(a+t)/2} ${e},${(a+t)/2} ${e},`+t:`M${i},${a}C${(i+e)/2},${a} ${(i+e)/2},${t} ${e},`+t},id:(t,n)=>this._ids(t,n).join("-")}).render()),this._shapes.push((new xc).data(t).select(Nt("g.d3plus-Tree-Shapes",h).node()).config(Lt.bind(this)(this._shapeConfig,"shape","Circle")).config({id:(t,n)=>this._ids(t,n).join("-"),label:(t,n)=>this._label?this._label(t.data,n):(n=this._ids(t,n).slice(0,t.depth))[n.length-1],labelConfig:{textAnchor:t=>"vertical"===this._orient?"middle":t.data.children&&t.data.depth!==this._groupBy.length?"end":"start",verticalAlign:t=>"vertical"===this._orient?1===t.data.depth?"bottom":"top":"middle"},hitArea:(t,n,e)=>{var i=this._labelHeight,a=this._labelWidths[t.depth-1];return{width:"vertical"===this._orient?a:2*e.r+a,height:"horizontal"===this._orient?i:2*e.r+i,x:"vertical"===this._orient?-a/2:t.children&&t.depth!==this._groupBy.length?-(e.r+a):-e.r,y:"horizontal"===this._orient?-i/2:t.children&&t.depth!==this._groupBy.length?-(e.r+this._labelHeight):-e.r}},labelBounds:(t,n,e)=>{var i=this._labelHeight,a="vertical"===this._orient?"height":"width",r=this._labelWidths[t.depth-1];return{["vertical"===this._orient?"width":"height"]:r,[a]:i,["vertical"===this._orient?"x":"y"]:-r/2,["vertical"===this._orient?"y":"x"]:t.children&&t.depth!==this._groupBy.length?-(e.r+i):e.r}}}).render()),this}
7258
+ */t.forEach((t,n)=>{t.data.key&&t.data.values&&(t.data=function n(t){return _u(t.values.map(t=>t.key&&t.values?n(t):t),e._aggs)}(t.data)),t.__d3plus__=!0,t.i=n});let a=this._shapeConfig.r;"function"!=typeof a&&(a=Bt(a));var h=Ot(t,t=>1===t.depth?a(t.data,t.i):0),u=Ot(t,t=>t.children?0:a(t.data,t.i)),c=Hi(t,t=>t.y);this._labelHeight=Dt([o?50:100,(c[1]-h-u)/(this._groupBy.length+1)]),this._labelWidths=mu(t,t=>t.depth).map(a=>a.values.reduce((t,n,e)=>{var i=e<a.values.length-1?a.values[e+1].x:l+this._margin[s],e=e?a.values[e-1].x:this._margin[s];return Dt([t,i-n.x,n.x-e])},l));let g=$a().domain(c).range([h+this._labelHeight,n-u-this._labelHeight]),d=(t.forEach(t=>{var n=g(t.y);r?(t.y=t.x,t.x=n):t.y=n}),{parent:this._select,enter:{transform:i},update:{transform:i}}),f=(this._shapes.push((new zc).data(t.filter(t=>1<t.depth).map(t=>Et({},t))).select(Nt("g.d3plus-Tree-Links",d).node()).config(Lt.bind(this)(this._shapeConfig,"shape","Path")).config({d:t=>{let n=this._shapeConfig.r;"function"==typeof n&&(n=n(t.data,t.i));var e=t.parent.x-t.x+(o?0:n),t=t.parent.y-t.y+(o?n:0),i=o?0:-n,a=o?-n:0;return o?`M${i},${a}C${i},${(a+t)/2} ${e},${(a+t)/2} ${e},`+t:`M${i},${a}C${(i+e)/2},${a} ${(i+e)/2},${t} ${e},`+t},id:(t,n)=>this._ids(t,n)[t.depth-1]}).render()),{id:(t,n)=>this._ids(t,n)[t.depth-1],label:(t,n)=>this._label?this._label(t.data,n):(n=this._ids(t,n).slice(0,t.depth))[n.length-1],labelConfig:{textAnchor:(t,n,e)=>o?"middle":e.children&&e.depth!==this._drawDepth+1?"end":"start",verticalAlign:(t,n,e)=>o?1===e.depth?"bottom":"top":"middle"},hitArea:(t,n,e)=>{var i=this._labelHeight,e=e.r||(o?e.height/2:e.width/2),a=this._labelWidths[t.depth-1];return{width:o?a:2*e+a,height:r?i:2*e+i,x:o?-a/2:t.children&&t.depth!==this._groupBy.length?-(e+a):-e,y:r?-i/2:t.children&&t.depth!==this._groupBy.length?-(e+this._labelHeight):-e}},labelBounds:(t,n,e)=>{var i=this._labelHeight,a=o?"height":"width",e=e.r||(o?e.height/2:e.width/2),r=this._labelWidths[t.depth-1];return{[o?"width":"height"]:r,[a]:i,[o?"x":"y"]:-r/2,[o?"y":"x"]:t.children&&t.depth!==this._groupBy.length?-(e+i):e}}});c=mu(t,t=>this._shape(t.data));let p=c.map(t=>t.key);h=this._previousShapes.filter(t=>!p.includes(t));return c.concat(h.map(t=>({key:t,values:[]}))).forEach(({key:t,values:n})=>{this._shapes.push((new Tc[t]).data(n).select(Nt("g.d3plus-Tree-"+t,d).node()).config(Lt.bind(this)(this._shapeConfig,"shape",t)).config(f).render())}),this._previousShapes=p,this}
7263
7259
  /**
7264
7260
  @memberof Tree
7265
- @desc If *value* is specified, sets the orientation to the specified value. If *value* is not specified, returns the current orientation.
7266
- @param {String} [*value* = "vertical"] Accepts either "vertical" or "horizontal".
7261
+ @desc Changes the orientation of the entire Tree, either "vertical" (top to bottom) or "horizontal" (left to right).
7262
+ @param {'vertical'|'horizontal'} [*value* = "vertical"] Accepts either "vertical" or "horizontal".
7267
7263
  */orient(t){return arguments.length?(this._orient=t,this):this._orient}
7268
7264
  /**
7269
7265
  @memberof Tree
@@ -7281,7 +7277,7 @@ r=r<0?r%U9+U9:r)?this._+="A"+e+","+e+",0,1,"+u+","+(t-o)+","+(n-s)+"A"+e+","+e+"
7281
7277
  @memberof Tree
7282
7278
  @desc Invoked when creating a new class instance, and sets any default parameters.
7283
7279
  @private
7284
- */constructor(){super(),this._orient="vertical",this._separation=(t,n)=>t.parent===n.parent?1:2,this._shape=Bt("Circle"),this._shapeConfig=Et(this._shapeConfig,{ariaLabel:(t,n)=>this._treeData?`${this._treeData[n].depth}. ${this._drawLabel(t,n)}.`:"",labelConfig:{fontColor:"#444"},Path:{fill:"none",stroke:"#ccc",strokeWidth:1},r:Bt(5),width:Bt(10),height:Bt(10)}),this._tree=f9()}}let hx={treemapBinary:function(t,n,e,i,a){var r,o,p=t.children,s=p.length,_=new Array(s+1);for(_[0]=o=r=0;r<s;++r)_[r+1]=o+=p[r].value;!function t(n,e,i,a,r,o,s){if(e-1<=n)return(l=p[n]).x0=a,l.y0=r,l.x1=o,void(l.y1=s);var l=_[n],h=i/2+l,u=n+1,c=e-1;for(;u<c;){var g=u+c>>>1;_[g]<h?u=1+g:c=g}h-_[u-1]<_[u]-h&&n+1<u&&--u;var l=_[u]-l,d=i-l;{var f;s-r<o-a?(t(n,u,l,a,r,f=i?(a*d+o*l)/i:o,s),t(u,e,d,f,r,o,s)):(t(n,u,l,a,r,o,f=i?(r*d+s*l)/i:s),t(u,e,d,a,f,o,s))}}(0,s,t.value,n,e,i,a)},treemapDice:h9,treemapSlice:p9,treemapSliceDice:function(t,n,e,i,a){(1&t.depth?p9:h9)(t,n,e,i,a)},treemapSquarify:m9,treemapResquarify:y9};class ux extends zf{
7280
+ */constructor(){super(),this._orient="vertical",this._separation=(t,n)=>t.parent===n.parent?1:2,this._legendTooltip=Et(this._legendTooltip,{title:ff.bind(this)}),this._previousShapes=[],this._shape=Bt("Circle"),this._shapeConfig=Et(this._shapeConfig,{ariaLabel:(t,n)=>this._treeData?`${this._treeData[n].depth}. ${this._drawLabel(t,n)}.`:"",labelConfig:{fontColor:Rh.dark},Path:{fill:"none",stroke:Rh.missing,strokeWidth:2},r:Bt(7),width:Bt(12),height:Bt(12)}),this._tooltipConfig=Et(this._tooltipConfig,{title:(t,n,e)=>this._drawLabel(t,n,e.depth-1)}),this._tree=f9()}}let hx={treemapBinary:function(t,n,e,i,a){var r,o,p=t.children,s=p.length,_=new Array(s+1);for(_[0]=o=r=0;r<s;++r)_[r+1]=o+=p[r].value;!function t(n,e,i,a,r,o,s){if(e-1<=n)return(l=p[n]).x0=a,l.y0=r,l.x1=o,void(l.y1=s);var l=_[n],h=i/2+l,u=n+1,c=e-1;for(;u<c;){var g=u+c>>>1;_[g]<h?u=1+g:c=g}h-_[u-1]<_[u]-h&&n+1<u&&--u;var l=_[u]-l,d=i-l;{var f;s-r<o-a?(t(n,u,l,a,r,f=i?(a*d+o*l)/i:o,s),t(u,e,d,f,r,o,s)):(t(n,u,l,a,r,o,f=i?(r*d+s*l)/i:s),t(u,e,d,a,f,o,s))}}(0,s,t.value,n,e,i,a)},treemapDice:h9,treemapSlice:p9,treemapSliceDice:function(t,n,e,i,a){(1&t.depth?p9:h9)(t,n,e,i,a)},treemapSquarify:m9,treemapResquarify:y9};class ux extends zf{
7285
7281
  /**
7286
7282
  @memberof Treemap
7287
7283
  @desc Extends the draw behavior of the abstract Viz class.
@@ -1,5 +1,5 @@
1
1
  /*
2
- @d3plus/core v3.0.5
2
+ @d3plus/core v3.0.6
3
3
  Data visualization made easy. A javascript library that extends the popular D3.js to enable fast and beautiful visualizations.
4
4
  Copyright (c) 2025 D3plus - https://d3plus.org
5
5
  @license MIT
@@ -6851,7 +6851,7 @@
6851
6851
  duration: this._duration,
6852
6852
  update: transform
6853
6853
  }).node();
6854
- this._legendClass.id(fill).align(wide ? "center" : position).direction(wide ? "row" : "column").duration(this._duration).data(visible ? legendData : []).height(wide ? this._height - (this._margin.bottom + this._margin.top) : this._height - (this._margin.bottom + this._margin.top + padding.bottom + padding.top)).locale(this._locale).parent(this).select(legendGroup).verticalAlign(!wide ? "middle" : position).width(wide ? this._width - (this._margin.left + this._margin.right + padding.left + padding.right) : this._width - (this._margin.left + this._margin.right)).shapeConfig(configPrep.bind(this)(this._shapeConfig, "legend")).shapeConfig({
6854
+ this._legendClass.id(fill).align(wide ? "center" : position).direction(wide ? "row" : "column").duration(this._duration).data(visible ? legendData : []).height(wide ? this._height - (this._margin.bottom + this._margin.top) : this._height - (this._margin.bottom + this._margin.top + padding.bottom + padding.top)).locale(this._locale).parent(this).select(legendGroup).shape((d, i)=>this._shape(d, i) === "Circle" ? "Circle" : "Rect").verticalAlign(!wide ? "middle" : position).width(wide ? this._width - (this._margin.left + this._margin.right + padding.left + padding.right) : this._width - (this._margin.left + this._margin.right)).shapeConfig(configPrep.bind(this)(this._shapeConfig, "legend")).shapeConfig({
6855
6855
  fill: (d, i)=>hidden(d, i) ? this._hiddenColor(d, i) : getAttr(d, i, "fill"),
6856
6856
  labelConfig: {
6857
6857
  fontOpacity: (d, i)=>hidden(d, i) ? this._hiddenOpacity(d, i) : 1
@@ -8110,13 +8110,9 @@
8110
8110
  }
8111
8111
  /**
8112
8112
  @memberof Viz
8113
- @desc If *value* is specified, sets the group accessor(s) to the specified string, function, or array of values and returns the current class instance.
8113
+ @desc Defines the mapping between data and shape. The value can be a String matching a key in each data point (default is "id"), or an accessor Function that returns a unique value for each data point. Additionally, an Array of these values may be provided if the visualization supports nested hierarchies.
8114
8114
  @param {String|Function|Array} [*value*]
8115
8115
  @chainable
8116
- @example
8117
- function value(d) {
8118
- return d.id;
8119
- }
8120
8116
  */ groupBy(_) {
8121
8117
  if (!arguments.length) return this._groupBy;
8122
8118
  this._groupByRaw = _;
@@ -8324,8 +8320,8 @@
8324
8320
  }
8325
8321
  /**
8326
8322
  @memberof Viz
8327
- @desc If *value* is specified, sets the shape accessor to the specified function or number and returns the current class instance.
8328
- @param {Function|String} [*value*]
8323
+ @desc Changes the primary shape used to represent each data point in a visualization. Not all visualizations support changing shapes, this method can be provided the String name of a D3plus shape class (for example, "Rect" or "Circle"), or an accessor Function that returns the String class name to be used for each individual data point.
8324
+ @param {String|Function} [*value*]
8329
8325
  @chainable
8330
8326
  */ shape(_) {
8331
8327
  return arguments.length ? (this._shape = typeof _ === "function" ? _ : constant(_), this) : this._shape;
@@ -14000,7 +13996,9 @@
14000
13996
  @private
14001
13997
  */ _draw(callback) {
14002
13998
  super._draw(callback);
14003
- const height = this._orient === "vertical" ? this._height - this._margin.top - this._margin.bottom : this._width - this._margin.left - this._margin.right, left = this._orient === "vertical" ? "left" : "top", that = this, transform = `translate(${this._margin.left}, ${this._margin.top})`, width = this._orient === "horizontal" ? this._height - this._margin.top - this._margin.bottom : this._width - this._margin.left - this._margin.right;
13999
+ const isVertical = this._orient === "vertical";
14000
+ const isHorizontal = this._orient === "horizontal";
14001
+ const height = isVertical ? this._height - this._margin.top - this._margin.bottom : this._width - this._margin.left - this._margin.right, left = isVertical ? "left" : "top", that = this, transform = `translate(${this._margin.left}, ${this._margin.top})`, width = isHorizontal ? this._height - this._margin.top - this._margin.bottom : this._width - this._margin.left - this._margin.right;
14004
14002
  const treeData = this._treeData = this._tree.separation(this._separation).size([
14005
14003
  width,
14006
14004
  height
@@ -14025,7 +14023,7 @@
14025
14023
  const rBufferEnd = d3Array.max(treeData, (d)=>d.children ? 0 : r(d.data, d.i));
14026
14024
  const yExtent = d3Array.extent(treeData, (d)=>d.y);
14027
14025
  this._labelHeight = d3Array.min([
14028
- this._orient === "vertical" ? 50 : 100,
14026
+ isVertical ? 50 : 100,
14029
14027
  (yExtent[1] - rBufferRoot - rBufferEnd) / (this._groupBy.length + 1)
14030
14028
  ]);
14031
14029
  this._labelWidths = data.nest(treeData, (d)=>d.depth).map((d)=>d.values.reduce((num, v, i)=>{
@@ -14042,7 +14040,7 @@
14042
14040
  ]);
14043
14041
  treeData.forEach((d)=>{
14044
14042
  const val = yScale(d.y);
14045
- if (this._orient === "horizontal") {
14043
+ if (isHorizontal) {
14046
14044
  d.y = d.x;
14047
14045
  d.x = val;
14048
14046
  } else d.y = val;
@@ -14056,51 +14054,61 @@
14056
14054
  transform
14057
14055
  }
14058
14056
  };
14059
- this._shapes.push(new Path().data(treeData.filter((d)=>d.depth > 1)).select(dom.elem("g.d3plus-Tree-Links", elemObject).node()).config(configPrep.bind(this)(this._shapeConfig, "shape", "Path")).config({
14057
+ this._shapes.push(new Path().data(treeData.filter((d)=>d.depth > 1).map((d)=>dom.assign({}, d))).select(dom.elem("g.d3plus-Tree-Links", elemObject).node()).config(configPrep.bind(this)(this._shapeConfig, "shape", "Path")).config({
14060
14058
  d: (d)=>{
14061
14059
  let r = this._shapeConfig.r;
14062
14060
  if (typeof r === "function") r = r(d.data, d.i);
14063
- const px = d.parent.x - d.x + (this._orient === "vertical" ? 0 : r), py = d.parent.y - d.y + (this._orient === "vertical" ? r : 0), x = this._orient === "vertical" ? 0 : -r, y = this._orient === "vertical" ? -r : 0;
14064
- return this._orient === "vertical" ? `M${x},${y}C${x},${(y + py) / 2} ${px},${(y + py) / 2} ${px},${py}` : `M${x},${y}C${(x + px) / 2},${y} ${(x + px) / 2},${py} ${px},${py}`;
14061
+ const px = d.parent.x - d.x + (isVertical ? 0 : r), py = d.parent.y - d.y + (isVertical ? r : 0), x = isVertical ? 0 : -r, y = isVertical ? -r : 0;
14062
+ return isVertical ? `M${x},${y}C${x},${(y + py) / 2} ${px},${(y + py) / 2} ${px},${py}` : `M${x},${y}C${(x + px) / 2},${y} ${(x + px) / 2},${py} ${px},${py}`;
14065
14063
  },
14066
- id: (d, i)=>this._ids(d, i).join("-")
14064
+ id: (d, i)=>this._ids(d, i)[d.depth - 1]
14067
14065
  }).render());
14068
- this._shapes.push(new Circle().data(treeData).select(dom.elem("g.d3plus-Tree-Shapes", elemObject).node()).config(configPrep.bind(this)(this._shapeConfig, "shape", "Circle")).config({
14069
- id: (d, i)=>this._ids(d, i).join("-"),
14066
+ const shapeConfig = {
14067
+ id: (d, i)=>this._ids(d, i)[d.depth - 1],
14070
14068
  label: (d, i)=>{
14071
14069
  if (this._label) return this._label(d.data, i);
14072
14070
  const ids = this._ids(d, i).slice(0, d.depth);
14073
14071
  return ids[ids.length - 1];
14074
14072
  },
14075
14073
  labelConfig: {
14076
- textAnchor: (d)=>this._orient === "vertical" ? "middle" : d.data.children && d.data.depth !== this._groupBy.length ? "end" : "start",
14077
- verticalAlign: (d)=>this._orient === "vertical" ? d.data.depth === 1 ? "bottom" : "top" : "middle"
14074
+ textAnchor: (d, i, x)=>isVertical ? "middle" : x.children && x.depth !== this._drawDepth + 1 ? "end" : "start",
14075
+ verticalAlign: (d, i, x)=>isVertical ? x.depth === 1 ? "bottom" : "top" : "middle"
14078
14076
  },
14079
14077
  hitArea: (d, i, s)=>{
14080
- const h = this._labelHeight, w = this._labelWidths[d.depth - 1];
14078
+ const h = this._labelHeight, offset = s.r ? s.r : isVertical ? s.height / 2 : s.width / 2, w = this._labelWidths[d.depth - 1];
14081
14079
  return {
14082
- width: this._orient === "vertical" ? w : s.r * 2 + w,
14083
- height: this._orient === "horizontal" ? h : s.r * 2 + h,
14084
- x: this._orient === "vertical" ? -w / 2 : d.children && d.depth !== this._groupBy.length ? -(s.r + w) : -s.r,
14085
- y: this._orient === "horizontal" ? -h / 2 : d.children && d.depth !== this._groupBy.length ? -(s.r + this._labelHeight) : -s.r
14080
+ width: isVertical ? w : offset * 2 + w,
14081
+ height: isHorizontal ? h : offset * 2 + h,
14082
+ x: isVertical ? -w / 2 : d.children && d.depth !== this._groupBy.length ? -(offset + w) : -offset,
14083
+ y: isHorizontal ? -h / 2 : d.children && d.depth !== this._groupBy.length ? -(offset + this._labelHeight) : -offset
14086
14084
  };
14087
14085
  },
14088
14086
  labelBounds: (d, i, s)=>{
14089
- const h = this._labelHeight, height = this._orient === "vertical" ? "height" : "width", w = this._labelWidths[d.depth - 1], width = this._orient === "vertical" ? "width" : "height", x = this._orient === "vertical" ? "x" : "y", y = this._orient === "vertical" ? "y" : "x";
14087
+ const h = this._labelHeight, height = isVertical ? "height" : "width", offset = s.r ? s.r : isVertical ? s.height / 2 : s.width / 2, w = this._labelWidths[d.depth - 1], width = isVertical ? "width" : "height", x = isVertical ? "x" : "y", y = isVertical ? "y" : "x";
14090
14088
  return {
14091
14089
  [width]: w,
14092
14090
  [height]: h,
14093
14091
  [x]: -w / 2,
14094
- [y]: d.children && d.depth !== this._groupBy.length ? -(s.r + h) : s.r
14092
+ [y]: d.children && d.depth !== this._groupBy.length ? -(offset + h) : offset
14095
14093
  };
14096
14094
  }
14097
- }).render());
14095
+ };
14096
+ const shapeData = data.nest(treeData, (d)=>this._shape(d.data));
14097
+ const dataShapes = shapeData.map((d)=>d.key);
14098
+ const exitShapes = this._previousShapes.filter((d)=>!dataShapes.includes(d));
14099
+ shapeData.concat(exitShapes.map((key)=>({
14100
+ key,
14101
+ values: []
14102
+ }))).forEach(({ key, values })=>{
14103
+ this._shapes.push(new shapes[key]().data(values).select(dom.elem(`g.d3plus-Tree-${key}`, elemObject).node()).config(configPrep.bind(this)(this._shapeConfig, "shape", key)).config(shapeConfig).render());
14104
+ });
14105
+ this._previousShapes = dataShapes;
14098
14106
  return this;
14099
14107
  }
14100
14108
  /**
14101
14109
  @memberof Tree
14102
- @desc If *value* is specified, sets the orientation to the specified value. If *value* is not specified, returns the current orientation.
14103
- @param {String} [*value* = "vertical"] Accepts either "vertical" or "horizontal".
14110
+ @desc Changes the orientation of the entire Tree, either "vertical" (top to bottom) or "horizontal" (left to right).
14111
+ @param {'vertical'|'horizontal'} [*value* = "vertical"] Accepts either "vertical" or "horizontal".
14104
14112
  */ orient(_) {
14105
14113
  return arguments.length ? (this._orient = _, this) : this._orient;
14106
14114
  }
@@ -14126,20 +14134,27 @@
14126
14134
  super();
14127
14135
  this._orient = "vertical";
14128
14136
  this._separation = (a, b)=>a.parent === b.parent ? 1 : 2;
14137
+ this._legendTooltip = dom.assign(this._legendTooltip, {
14138
+ title: legendLabel.bind(this)
14139
+ });
14140
+ this._previousShapes = [];
14129
14141
  this._shape = constant("Circle");
14130
14142
  this._shapeConfig = dom.assign(this._shapeConfig, {
14131
14143
  ariaLabel: (d, i)=>this._treeData ? `${this._treeData[i].depth}. ${this._drawLabel(d, i)}.` : "",
14132
14144
  labelConfig: {
14133
- fontColor: "#444"
14145
+ fontColor: color.colorDefaults.dark
14134
14146
  },
14135
14147
  Path: {
14136
14148
  fill: "none",
14137
- stroke: "#ccc",
14138
- strokeWidth: 1
14149
+ stroke: color.colorDefaults.missing,
14150
+ strokeWidth: 2
14139
14151
  },
14140
- r: constant(5),
14141
- width: constant(10),
14142
- height: constant(10)
14152
+ r: constant(7),
14153
+ width: constant(12),
14154
+ height: constant(12)
14155
+ });
14156
+ this._tooltipConfig = dom.assign(this._tooltipConfig, {
14157
+ title: (d, i, x)=>this._drawLabel(d, i, x.depth - 1)
14143
14158
  });
14144
14159
  this._tree = d3Hierarchy.tree();
14145
14160
  }