d3-voronoi-map
Version:
D3 plugin which computes a map (one-level treemap), based on Voronoi tesselation
1 lines • 7.08 kB
JavaScript
!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports,require("d3-polygon"),require("d3-timer"),require("d3-dispatch"),require("d3-weighted-voronoi")):"function"==typeof define&&define.amd?define(["exports","d3-polygon","d3-timer","d3-dispatch","d3-weighted-voronoi"],n):n(t.d3=t.d3||{},t.d3,t.d3,t.d3,t.d3)}(this,function(t,n,e,r,i){"use strict";function o(){this.growthChangesLength=p,this.totalAvailableArea=NaN,this.lastAreaError=NaN,this.lastGrowth=NaN,this.growthChanges=[],this.growthChangeWeights=h(this.growthChangesLength),this.growthChangeWeightsSum=s(this.growthChangeWeights)}function a(t,n){return t>=n?1:-1}function h(t){for(var n=3,e=1,r=1,i=n,o=[],a=0;a<t;a++)o.push(i),i-=e,i<r&&(i=r);return o}function s(t){for(var n=0,e=0;e<t.length;e++)n+=t[e];return n}function g(){function t(t,a,s,l){var c,f,p=!1;for(r!==l.clip()&&(r=l.clip(),i=l.extent(),p=!0),p&&e(),c=o+g*l.prng()(),f=h+u*l.prng()();!n.polygonContains(r,[c,f]);)c=o+g*l.prng()(),f=h+u*l.prng()();return[c,f]}function e(){o=i[0][0],a=i[1][0],h=i[0][1],s=i[1][1],g=a-o,u=s-h}var r,i,o,a,h,s,g,u;return t}function u(){function t(t,n,r,i){var h=!1;return o!==i.clip()&&(o=i.clip(),h|=!0),a!==r&&(a=r,h|=!0),h&&e(),[s[0]+Math.cos(l+n*u)*g+.001*(i.prng()()-.5),s[1]+Math.sin(l+n*u)*g+.001*(i.prng()()-.5)]}function e(){s=n.polygonCentroid(o),g=r(s,o)/2,h=a.length,u=2*Math.PI/h}function r(t,n){for(var e,r=1/0,o=0,a=n[n.length-1],h=n[o];o<n.length;)e=i(t,a,h),e<r&&(r=e),o++,a=h,h=n[o];return r}function i(t,n,e){var r=t[0],i=t[1],o=n[0],a=n[1],h=e[0],s=e[1],g=r-o,u=i-a,l=h-o,c=s-a,f=g*l+u*c,p=l*l+c*c,w=-1;0!=p&&(w=f/p);var d,v;w<0?(d=o,v=a):w>1?(d=h,v=s):(d=o+w*l,v=a+w*c);var C=r-d,y=i-v;return Math.sqrt(C*C+y*y)}var o,a,h,s,g,u,l=0;return t.startAngle=function(n){return arguments.length?(l=n,t):l},t}function l(){function t(t,n,o,a){var s=!1;return r!==a.clip()&&(r=a.clip(),s|=!0),i!==o&&(i=o,s|=!0),s&&e(),h}function e(){o=i.length,a=n.polygonArea(r),h=a/o/2}var r,i,o,a,h;return t}function c(t){this.message=t,this.stack=(new Error).stack}function f(t){function a(t){return Math.pow(t,2)}function h(t,n){return a(n.x-t.x)+a(n.y-t.y)}function s(){u(),U.call("tick",P),k&&(T.stop(),U.call("end",P))}function u(){k||(Q&&f(),W=d(W,K.ratio()),b++,E=A(W),K.add(E),L=E<N,k=L||b>=V)}function f(){m(),M=t.length,x=Math.abs(n.polygonArea(J.clip())),N=z*x,K.clear().totalArea(x),b=0,L=!1,W=p(t,P),k=!1,Q=!1}function p(t,n){var e,r,i=t.reduce(function(t,n){return Math.max(t,R(n))},-(1/0)),o=i*_;return e=t.map(function(t,e,r){return{index:e,weight:Math.max(R(t),o),initialPosition:B(t,e,r,n),initialWeight:H(t,e,r,n),originalData:t}}),r=w(e,n),Y(r),J(r)}function w(t,e){var r,i=t.reduce(function(t,n){return t+=n.weight},0);return t.map(function(t,o,a){return r=t.initialPosition,n.polygonContains(J.clip(),r)||(r=q(t,o,a,e)),{index:t.index,targetedArea:x*t.weight/i,data:t,x:r[0],y:r[1],weight:t.initialWeight}})}function d(t,n){var e;if(v(t,n),e=t.map(function(t){return t.site.originalObject}),t=J(e),t.length<M)throw new c("at least 1 site has no area, which is not supposed to arise");if(C(t,n),e=t.map(function(t){return t.site.originalObject}),t=J(e),t.length<M)throw new c("at least 1 site has no area, which is not supposed to arise");return t}function v(t,e){var r,i,o,a,h,s,g,u=[],l=.5;r=l*e,i=1-r;for(var c=0;c<M;c++)o=t[c],a=o.site.originalObject,h=n.polygonCentroid(o),s=h[0]-a.x,g=h[1]-a.y,s*=i,g*=i,a.x+=s,a.y+=g,u.push(a);Y(u)}function C(t,e){var r,i,o,a,h,s,g=[],u=.1;r=u*e;for(var l=0;l<M;l++)i=t[l],o=i.site.originalObject,a=n.polygonArea(i),h=o.targetedArea/a,h=Math.max(h,1-u+r),h=Math.min(h,1+u-r),s=o.weight*h,s=Math.max(s,F),o.weight=s,g.push(o);Y(g)}function y(t){var n,e,r,i,o,a,s,g=0;do{if(g>X)throw new c("handleOverweighted1 is looping too much");n=!1;for(var u=0;u<M;u++){e=t[u];for(var l=u+1;l<M;l++)if(r=t[l],e.weight>r.weight?(i=e,o=r):(i=r,o=e),a=h(e,r),a<i.weight-o.weight){s=i.weight-o.weight-a,o.weight+=s+F,n=!0,g++;break}if(n)break}}while(n)}function A(t){for(var e,r,i,o=0,a=0;a<M;a++)e=t[a],r=e.site.originalObject,i=n.polygonArea(e),o+=Math.abs(r.targetedArea-i);return o}function m(){Y=y}var M,x,N,b,W,E,L,k,P,j=.01,O=50,G=.01,I=Math.random,q=g(),S=l(),F=(g(),1e-10),R=function(t){return t.weight},z=j,V=O,_=G,D=I,B=q,H=S,J=i.weightedVoronoi(),K=new o,Q=!0,T=e.timer(s),U=r.dispatch("tick","end");const X=1e3;var Y;return P={tick:u,restart:function(){return T.restart(s),P},stop:function(){return T.stop(),P},weight:function(t){return arguments.length?(R=t,Q=!0,P):R},convergenceRatio:function(t){return arguments.length?(z=t,Q=!0,P):z},maxIterationCount:function(t){return arguments.length?(V=t,P):V},minWeightRatio:function(t){return arguments.length?(_=t,Q=!0,P):_},clip:function(t){return arguments.length?(J.clip(t),Q=!0,P):J.clip()},extent:function(t){return arguments.length?(J.extent(t),Q=!0,P):J.extent()},size:function(t){return arguments.length?(J.size(t),Q=!0,P):J.size()},prng:function(t){return arguments.length?(D=t,Q=!0,P):D},initialPosition:function(t){return arguments.length?(B=t,Q=!0,P):B},initialWeight:function(t){return arguments.length?(H=t,Q=!0,P):H},state:function(){return Q&&f(),{ended:k,iterationCount:b,convergenceRatio:E/x,polygons:W}},on:function(t,n){return 1===arguments.length?U.on(t):(U.on(t,n),P)}}}var p=10;o.prototype.reset=function(){return this.lastAreaError=NaN,this.lastGrowth=NaN,this.growthChanges=[],this.growthChangesLength=p,this.growthChangeWeights=h(this.growthChangesLength),this.growthChangeWeightsSum=s(this.growthChangeWeights),this.totalAvailableArea=NaN,this},o.prototype.clear=function(){return this.lastAreaError=NaN,this.lastGrowth=NaN,this.growthChanges=[],this},o.prototype.length=function(t){return arguments.length?(parseInt(t)>0?(this.growthChangesLength=Math.floor(parseInt(t)),this.growthChangeWeights=h(this.growthChangesLength),this.growthChangeWeightsSum=s(this.growthChangeWeights)):console.warn("FlickeringMitigation.length() accepts only positive integers; unable to handle "+t),this):this.growthChangesLength},o.prototype.totalArea=function(t){return arguments.length?(parseFloat(t)>0?this.totalAvailableArea=parseFloat(t):console.warn("FlickeringMitigation.totalArea() accepts only positive numbers; unable to handle "+t),this):this.totalAvailableArea},o.prototype.add=function(t){var n,e;return n=this.lastAreaError,this.lastAreaError=t,isNaN(n)||(e=this.lastGrowth,this.lastGrowth=a(this.lastAreaError,n)),isNaN(e)||this.growthChanges.unshift(this.lastGrowth!=e),this.growthChanges.length>this.growthChangesLength&&this.growthChanges.pop(),this},o.prototype.ratio=function(){var t,n=0;if(this.growthChanges.length<this.growthChangesLength)return 0;if(this.lastAreaError>this.totalAvailableArea/10)return 0;for(var e=0;e<this.growthChangesLength;e++)this.growthChanges[e]&&(n+=this.growthChangeWeights[e]);return t=n/this.growthChangeWeightsSum},c.prototype.name="d3VoronoiMapError",c.prototype=new Error,t.voronoiMapSimulation=f,t.voronoiMapInitialPositionRandom=g,t.voronoiMapInitialPositionPie=u,t.d3VoronoiMapError=c,Object.defineProperty(t,"__esModule",{value:!0})});