UNPKG

react-wordcloud-fork

Version:

Simple React + D3 wordcloud component with powerful features.

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