UNPKG

react-wordcloud-fork

Version:

Simple React + D3 wordcloud component with powerful features.

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