UNPKG

react-wordcloud

Version:

Simple React + D3 wordcloud component with powerful features.

3 lines (2 loc) 10.2 kB
import t from"lodash.debounce";import n,{useRef as r,useState as e,useEffect as o}from"react";import{select as a,event as i}from"d3-selection";import u from"resize-observer-polyfill";import"d3-transition";import{range as f,min as l,max as s,descending as c}from"d3-array";import h from"d3-cloud";import d from"lodash.clonedeep";import m from"seedrandom";import y from"tippy.js";import{dispatch as p}from"d3-dispatch";import{scaleOrdinal as x,scaleLinear as v,scaleSqrt as g,scaleLog as b}from"d3-scale";import{schemeCategory10 as w}from"d3-scale-chromatic";function M(){return(M=Object.assign||function(t){for(var n=1;n<arguments.length;n++){var r=arguments[n];for(var e in r)Object.prototype.hasOwnProperty.call(r,e)&&(t[e]=r[e])}return t}).apply(this,arguments)}var z=Math.PI/180;function k(t){return t.text}function W(){return"serif"}function S(){return"normal"}function O(t){return Math.sqrt(t.value)}function T(){return 30*(~~(6*Math.random())-3)}function j(){return 1}function A(t,n,r,e){if(!n.sprite){var o=t.context,a=t.ratio;o.clearRect(0,0,2048/a,2048/a);var i=0,u=0,f=0,l=r.length;for(--e;++e<l;){n=r[e],o.save(),o.font=n.style+" "+n.weight+" "+~~((n.size+1)/a)+"px "+n.font;var s=o.measureText(n.text+"m").width*a,c=n.size<<1;if(n.rotate){var h=Math.sin(n.rotate*z),d=Math.cos(n.rotate*z),m=s*d,y=s*h,p=c*d,x=c*h;s=Math.max(Math.abs(m+x),Math.abs(m-x))+31>>5<<5,c=~~Math.max(Math.abs(y+p),Math.abs(y-p))}else s=s+31>>5<<5;if(c>f&&(f=c),i+s>=2048&&(i=0,u+=f,f=0),u+c>=2048)break;o.translate((i+(s>>1))/a,(u+(c>>1))/a),n.rotate&&o.rotate(n.rotate*z),o.fillText(n.text,0,0),n.padding&&(o.lineWidth=2*n.padding,o.strokeText(n.text,0,0)),o.restore(),n.width=s,n.height=c,n.xoff=i,n.yoff=u,n.x1=s>>1,n.y1=c>>1,n.x0=-n.x1,n.y0=-n.y1,n.hasText=!0,i+=s}for(var v=o.getImageData(0,0,2048/a,2048/a).data,g=[];--e>=0;)if((n=r[e]).hasText){for(var b=(s=n.width)>>5,w=(c=n.y1-n.y0,0);w<c*b;w++)g[w]=0;if(null==(i=n.xoff))return;u=n.yoff;for(var M=0,k=-1,W=0;W<c;W++){for(w=0;w<s;w++){var S=v[2048*(u+W)+(i+w)<<2]?1<<31-w%32:0;g[b*W+(w>>5)]|=S,M|=S}M?k=W:(n.y0++,c--,W--,u++)}n.y1=n.y0+k,n.sprite=g.slice(0,(n.y1-n.y0)*b)}}}function I(t,n,r){for(var e,o=t.sprite,a=t.width>>5,i=t.x-(a<<4),u=127&i,f=32-u,l=t.y1-t.y0,s=(t.y+t.y0)*(r>>=5)+(i>>5),c=0;c<l;c++){e=0;for(var h=0;h<=a;h++)if((e<<f|(h<a?(e=o[c*a+h])>>>u:0))&n[s+h])return!0;s+=r}return!1}function q(t,n){var r=t[0],e=t[1];n.x+n.x0<r.x&&(r.x=n.x+n.x0),n.y+n.y0<r.y&&(r.y=n.y+n.y0),n.x+n.x1>e.x&&(e.x=n.x+n.x1),n.y+n.y1>e.y&&(e.y=n.y+n.y1)}function E(t){var n=t[0]/t[1];return function(t){return[n*(t*=.1)*Math.cos(t),t*Math.sin(t)]}}function C(){return document.createElement("canvas")}function D(t){return"function"==typeof t?t:function(){return t}}var F={archimedean:E,rectangular:function(t){var n=4*t[0]/t[1],r=0,e=0;return function(t){var o=t<0?-1:1;switch(Math.sqrt(1+4*o*t)-o&3){case 0:r+=n;break;case 1:e+=4;break;case 2:r-=n;break;default:e-=4}return[r,e]}}};function P(t,n){return t[Math.floor(n()*t.length)]}function L(t){return t.size+"px"}function N(t){return t.text}function R(t){return"translate("+t.x+", "+t.y+")"+("number"==typeof t.rotate?"rotate("+t.rotate+")":"")}function U(t){var n,r=t.callbacks,e=t.maxWords,o=t.options,a=t.selection,u=t.size,f=o.deterministic,x=o.enableOptimizations,w=o.fontFamily,z=o.fontStyle,U=o.fontSizes,H=o.fontWeight,B=o.padding,G=o.randomSeed,J=o.rotations,K=o.rotationAngles,Q=o.spiral,V=o.scale,X=t.words.concat().sort(function(t,n){return c(t.value,n.value)}).slice(0,e),Y=m(f?G||"deterministic":null);(n=x?function(){var t=[256,256],n=k,r=W,e=O,o=S,a=S,i=T,u=j,f=E,l=[],s=Infinity,c=p("word","end"),h=Math.random,d={},m=C,y=!1;function x(n,r,e){for(var o,a,i,u,l,s=r.x,c=r.y,d=Math.sqrt(t[0]*t[0]+t[1]*t[1]),m=f(t),y=h()<.5?1:-1,p=-y;(o=m(p+=y))&&(a=~~o[0],i=~~o[1],!(Math.min(Math.abs(a),Math.abs(i))>=d));)if(r.x=s+a,r.y=c+i,!(r.x+r.x0<0||r.y+r.y0<0||r.x+r.x1>t[0]||r.y+r.y1>t[1]||e&&I(r,n,t[0])||e&&!((u=r).x+u.x1>(l=e)[0].x&&u.x+u.x0<l[1].x&&u.y+u.y1>l[0].y&&u.y+u.y0<l[1].y))){for(var x,v=r.sprite,g=r.width>>5,b=t[0]>>5,w=r.x-(g<<4),M=127&w,z=32-M,k=r.y1-r.y0,W=(r.y+r.y0)*b+(w>>5),S=0;S<k;S++){x=0;for(var O=0;O<=g;O++)n[W+O]|=x<<z|(O<g?(x=v[S*g+O])>>>M:0);W+=b}return delete r.sprite,!0}return!1}return d.canvas=function(t){return arguments.length?(m=D(t),d):m},d.start=function(){var f=function(t){t.width=t.height=1;var n=Math.sqrt(t.getContext("2d").getImageData(0,0,1,1).data.length>>2);t.width=2048/n,t.height=2048/n;var r=t.getContext("2d");return r.fillStyle=r.strokeStyle="red",r.textAlign="center",{context:r,ratio:n}}(m()),s=new Uint32Array((t[0]>>5)*t[1]),p=null,v=[],g=l.map(function(t,f){return t.text=n.call(this,t,f),t.font=r.call(this,t,f),t.style=o.call(this,t,f),t.weight=a.call(this,t,f),t.rotate=i.call(this,t,f),t.size=~~e.call(this,t,f),t.padding=u.call(this,t,f),t}).sort(function(t,n){return n.size-t.size});return setTimeout(function(){return function n(r){var e=50*r,o=Math.min(50*(r+1),l.length);!function(n,r){for(var e=n;e<r;e+=1){var o=g[e];o.x=t[0]*(h()+.5)>>1,o.y=t[1]*(h()+.5)>>1,A(f,o,g,e),o.hasText&&x(s,o,p)&&(v.push(o),c.call("word",d,o),p?q(p,o):p=[{x:o.x+o.x0,y:o.y+o.y0},{x:o.x+o.x1,y:o.y+o.y1}],o.x-=t[0]>>1,o.y-=t[1]>>1)}}(e,o),y||(o<l.length?setTimeout(function(){return n(r+1)},0):(d.stop(),c.call("end",d,v,p)))}(0)},0),d},d.revive=function(){return y=!1,d},d.stop=function(){return y=!0,d},d.timeInterval=function(t){return arguments.length?(s=null==t?Infinity:t,d):s},d.words=function(t){return arguments.length?(l=t,d):l},d.size=function(n){return arguments.length?(t=[+n[0],+n[1]],d):t},d.font=function(t){return arguments.length?(r=D(t),d):r},d.fontStyle=function(t){return arguments.length?(o=D(t),d):o},d.fontWeight=function(t){return arguments.length?(a=D(t),d):a},d.rotate=function(t){return arguments.length?(i=D(t),d):i},d.text=function(t){return arguments.length?(n=D(t),d):n},d.spiral=function(t){return arguments.length?(f=F[t]||t,d):f},d.fontSize=function(t){return arguments.length?(e=D(t),d):e},d.padding=function(t){return arguments.length?(u=D(t),d):u},d.random=function(t){return arguments.length?(h=t,d):h},d.on=function(){var t=c.on.apply(c,arguments);return t===c?d:t},d}():h()).size(u).padding(B).words(d(X)).rotate(function(){return void 0===J?30*(~~(6*Y())-3):function(t,n,r){if(t<1)return 0;var e=[];if(1===t)e=[n[0]];else{e=[].concat(n);for(var o=(n[1]-n[0])/(t-1),a=n[0]+o;a<n[1];)e.push(a),a+=o}return P(e,r)}(J,K,Y)}).spiral(Q).random(Y).text(N).font(w).fontStyle(z).fontWeight(H),function t(e,u){void 0===u&&(u=1),x&&n.revive(),n.fontSize(function(t){return function(t,n,r){var e,o=l(t,function(t){return Number(t.value)}),a=s(t,function(t){return Number(t.value)});switch(r){case"log":e=b;break;case"sqrt":e=g;break;case"linear":default:e=v}return e().domain([o,a]).range(n)}(X,e,V)(t.value)}).on("end",function(n){if(X.length!==n.length&&u<=10){10===u&&console.warn("Unable to layout "+(X.length-n.length)+" word(s) after "+u+" attempts. Consider: (1) Increasing the container/component size. (2) Lowering the max font size. (3) Limiting the rotation angles.");var f=Math.max(.95*e[0],1);t([f,Math.max(.95*e[1],f)],u+1)}else!function(t){var n,r=t.callbacks,e=t.options,o=t.random,a=t.words,u=r.getWordColor,f=r.getWordTooltip,l=r.onWordClick,s=r.onWordMouseOver,c=r.onWordMouseOut,h=e.colors,d=e.enableTooltip,m=e.fontStyle,p=e.fontWeight,x=e.textAttributes,v=e.tooltipOptions,g=e.fontFamily,b=e.transitionDuration;function w(t){return u?u(t):P(h,o)}t.selection.selectAll("text").data(a).join(function(t){var r=t.append("text").on("click",function(t){l&&l(t,i)}).on("mouseover",function(t){d&&(n=y(i.target,M({animation:"scale",arrow:!0,content:function(){return f(t)}},v))),s&&s(t,i)}).on("mouseout",function(t){n&&n.destroy(),c&&c(t,i)}).attr("cursor",l?"pointer":"default").attr("fill",w).attr("font-family",g).attr("font-style",m).attr("font-weight",p).attr("text-anchor","middle").attr("transform","translate(0, 0) rotate(0)");"object"==typeof x&&Object.keys(x).forEach(function(t){r=r.attr(t,x[t])}),r=r.call(function(t){return t.transition().duration(b).attr("font-size",L).attr("transform",R).text(N)})},function(t){t.transition().duration(b).attr("fill",w).attr("font-family",g).attr("font-size",L).attr("transform",R).text(N)},function(t){t.transition().duration(b).attr("fill-opacity",0).remove()})}({callbacks:r,options:o,random:Y,selection:a,words:n})}).start()}(U)}var H={getWordTooltip:function(t){return t.text+" ("+t.value+")"}},B={colors:f(20).map(function(t){return t.toString()}).map(x(w)),deterministic:!1,enableOptimizations:!1,enableTooltip:!0,fontFamily:"times new roman",fontSizes:[4,32],fontStyle:"normal",fontWeight:"normal",padding:1,rotationAngles:[-90,90],scale:"sqrt",spiral:"rectangular",tooltipOptions:{},transitionDuration:600};function G(i){var f=i.callbacks,l=i.maxWords,s=void 0===l?100:l,c=i.minSize,h=i.options,d=i.size,m=i.words,y=function(t,n){if(null==t)return{};var r,e,o={},a=Object.keys(t);for(e=0;e<a.length;e++)n.indexOf(r=a[e])>=0||(o[r]=t[r]);return o}(i,["callbacks","maxWords","minSize","options","size","words"]),p=M({},H,f),x=M({},B,h),v=function(t,n,i){var f=r(),l=e(n),s=l[0],c=l[1],h=e(null),d=h[0],m=h[1];return o(function(){var r=f.current,e=a(r).append("svg").style("display","block");"object"==typeof i&&Object.keys(i).forEach(function(t){e=e.attr(t,i[t])});var o=e.append("g");function l(t,n){e.attr("height",n).attr("width",t),o.attr("transform","translate("+t/2+", "+n/2+")"),c([t,n])}m(o);var s=0,h=0;void 0===n?(s=r.parentElement.offsetWidth,h=r.parentElement.offsetHeight):(s=n[0],h=n[1]),l(s=Math.max(s,t[0]),h=Math.max(h,t[1]));var d=new u(function(t){if(t&&0!==t.length&&void 0===n){var r=t[0].contentRect;l(r.width,r.height)}});return d.observe(r),function(){d.unobserve(r),a(r).selectAll("*").remove()}},[n,t,i]),[f,d,s]}(c,d,h.svgAttributes),g=v[0],b=v[1],w=v[2],z=r(t(U,100));return o(function(){b&&z.current({callbacks:p,maxWords:s,options:x,selection:b,size:w,words:m})},[s,p,x,b,w,m]),n.createElement("div",M({ref:g,style:{height:"100%",width:"100%"}},y))}G.defaultProps={callbacks:H,maxWords:100,minSize:[300,300],options:B};export default G;export{H as defaultCallbacks,B as defaultOptions}; //# sourceMappingURL=index.module.js.map