UNPKG

realchart

Version:

Wooritech charting library

8 lines (6 loc) 10.1 kB
/** * RealChart Wordcloud v1.3.17 * Copyright (C) 2023-2025 WooriTech Inc. * All Rights Reserved. */ import{WordCloudSeriesType as t,extend as e,WidgetSeries as i,calcPercent as s,parsePercentSize as n,Utils as o,toStr as r,WidgetSeriesPoint as a,RcElement as h,SeriesView as l,RectElement as c,TextElement as _,WidgetSeriesView as d,LayerElement as x,ElementPool as u,SeriesAnimation as m,TextAnchor as p,pixel as M,pickNum as g}from"./index.mjs";class y extends a{}class f extends y{constructor(t,e){super(t),this.points=e}}class w extends i{$_denormalizeFontSize(t,e,i){let o,r;return"min"==t?(o=s(n(w.MinFontSize,!1),e),r=s(n(w.MaxMinFontSize,!1),e)):(o=s(n(w.MinMaxFontSize,!1),e),r=s(n(w.MaxFontSize,!1),e)),i>1?r:i<0?o:i*(r-o)+o}calcFontRatio(t,e,i,n){return s(e,i,n)}getMinFontSize(t,e){const{fixed:i,size:o}=this._minFontSizeDim,r=i&&o<=1?this.$_denormalizeFontSize("min",t,o):s(this._minFontSizeDim,t,e);return Math.max(s(n(w.MinFontSize,!1),t),r)}getMaxFontSize(t,e){const{fixed:i,size:o}=this._maxFontSizeDim,r=i&&o<=1?this.$_denormalizeFontSize("max",t,o):s(this._maxFontSizeDim,t,e);return Math.min(s(n(w.MaxFontSize,!1),t),r)}getLogFunc(){const t=this._op.logBase;return t>=2?function(e){return Math.max(Math.log(e)/Math.log(t))}:function(t){return t}}_colorByPoint(){return this._op.colorByPoint}_createPoint(t){return new y(t)}_createOthersPoint(t,e){return t.y=e.map((t=>t.y)).reduce(((t,e)=>t+e)),new f(t,e)}_doApply(t){var e;super._doApply(t),(t.text!==this._text||o.equalArrays(this._excludes,t.excludes))&&(this._text=t.text,this._excludes=null===(e=t.excludes)||void 0===e?void 0:e.slice(),this._dataSourceDirty=!0),this._setDims(t,"minFontSize","maxFontSize")}_doLoadPoints(t){const e=this._op,i=e.text;let s=[];if(i){const t=Math.max(e.minLength||1,1),n={};let o=e.excludes,r=i.split(/\s+/g);Array.isArray(o)&&o.length>0&&(r=r.filter((t=>o.indexOf(t)<0))),r.forEach((e=>{e.length>=t&&(e in n?n[e]++:n[e]=1)}));for(const t in n)s.push({x:t,y:n[t]})}else if(Array.isArray(t)&&!(t.length>0&&"object"==typeof t[0]&&null!==t[0]))for(let e=0;e<t.length;e+=2)s.push({x:r(t[e]),y:t[e+1]||0});s.length>0&&(t=s.sort(((t,e)=>e.y-t.y))),super._doLoadPoints(t)}isPointLabelVisible(t){return!1}_prepareRender(){super._prepareRender(),this.collectValues(null,null),this.prepareReferents(null),this.collectRanges(null)}}w.type=t,w.MinFontSize=8,w.MaxMinFontSize=15,w.MaxFontSize="15%",w.MinMaxFontSize="5%",w.defaults=e(i.defaults,{frame:"rectangle",maxCount:100,maxFontSize:1,minFontSize:0,colorByPoint:!0,autoScale:!0});const S=Math.floor;class P{constructor(t){this._options=t}start(t,e,i,s,n,r){this._container=t;const a="circle"===i.frame||"ellipse"===i.frame,h=i.autoScale,l=g(i.seed,0)*Math.PI*2/360,c=Math.max(0,g(i.wordGap,0));let _=s,d=0,x=n,u=0,m=0;this.$_prepare(i,s,n),this._unit,e.forEach((t=>{const e=t.point;if(this.$_findPos(t,a,i.shuffle,this._radius,l,c)){const{x:i,y:s,width:n,height:o}=t.box.bounds;this.$_placeWord(t),e.xPos=i+n/2,e.yPos=s,_=Math.min(_,i),d=Math.max(d,i+n),x=Math.min(x,s),u=Math.max(u,s+o),m++}else t.setVis(!1)})),o.log("Words placed.",m,"of",e.length);const p=d-_,M=u-x,y=s/2,f=n/2,w=h?1/(Math.max(p/s,M/n)+.02):1,S=~~((_+p/2-y)*w),P=~~((x+M/2-f)*w);return this._trans={x:S,y:P,cx:y,cy:f,rate:w},e.forEach((t=>{const e=t.point;e.xPos=y-S+(e.xPos-y)*w,e.yPos=f-P+(e.yPos-f)*w})),this.$_transform(),null==r||r(e),this}stop(){}$_transform(t=1){let{x:e,y:i,cx:s,cy:n,rate:o}=this._trans;e=~~(e*t),i=~~(i*t),this._container.dom.setAttribute("transform-origin",`${s} ${n}`),this._container.trans(-e,-i),this._container.scale(o*t)}$_prepare(t,e,i){const s=this._unit=8;this._grid=[],this._cols=S(e/s),this._rows=S(i/s),this._radius=S(Math.sqrt(this._cols*this._cols+this._rows*this._rows)/2);const n=2*this._radius;this._center={c:this._radius,r:this._radius};for(let t=0;t<n;t++)this._grid.push([]);this._rdPoints=[],this._ellipticity="ellipse"===t.frame||"rectangle"===t.frame?i/e:1}$_isOverlapping(t){const e=this._grid;for(let i=t.r1;i<=t.r2;i++)for(let s=t.c1;s<=t.c2;s++)if(e[i]||(e[i]=[]),e[i][s])return!0;return!1}$_placeWord(t){const e=this._grid,i=t.box;for(let s=i.r1;s<=i.r2;s++)for(let n=i.c1;n<=i.c2;n++)e[s][n]=t}$_getPoints(t,e,i){if(this._rdPoints[t])return this._rdPoints[t];const s=this._center,n=this._ellipticity,o=t*this._unit;let r=0,a=[];for(0===t&&a.push([s.c,s.r]);r<o;){const h=r/o*2*Math.PI+i;let l=t*Math.cos(h)/n,c=t*Math.sin(h);if(!e){const t=Math.max(Math.abs(Math.cos(h)),Math.abs(Math.sin(h)));l/=t,c/=t}a.push([~~(s.c+l),~~(s.r+c)]),r++}return this._rdPoints[t]=a}$_rotatePoint(t,e,i){const s=e*Math.PI/180,n=Math.cos(s),o=Math.sin(s),{x:r,y:a,width:h,height:l}=t,c=r+h,_=a+l,d=r+h/2,x=a+l/2,u=[{x:r,y:a},{x:c,y:a},{x:r,y:_},{x:c,y:_}].map((t=>({x:d+(t.x-d)*n-(t.y-x)*o,y:x+(t.x-d)*o+(t.y-x)*n}))),m=Math.min(...u.map((t=>t.x))),p=Math.min(...u.map((t=>t.y))),M=Math.max(...u.map((t=>t.x))),g=Math.max(...u.map((t=>t.y))),y=this._unit,f=M-m,w=g-p;return{c1:Math.max(0,~~(m/y)),r1:Math.max(0,~~(p/y)),c2:~~(M/y),r2:~~(g/y)+i,bounds:{x:m,y:p,width:f,height:w}}}$_getBox(t,e,i,s,n=0){const o=this._unit,{width:r}=t.getBBox(),a=t.hText,h=r/o,l=a/o,c=Math.ceil(h/2),_=Math.ceil(l/2),d=Math.max(0,e-c),x=Math.max(0,i-_),u=d+Math.ceil(h),m=x+Math.ceil(l),p={x:(e-c)*o,y:(i-_)*o,width:r,height:a};return n?this.$_rotatePoint(p,n,s):{c1:d,r1:x,c2:u+s,r2:m,bounds:p}}$_drawDebugBox(t,e){const{doc:i}=this._container,{x:s,y:n,width:o,height:r}=t.bounds,a=c.create(i,"",s,n,o,r);a.setFill((null==e?void 0:e.fill)||"#ff000055"),a.setStroke((null==e?void 0:e.stroke)||"none"),a.setAttr("stroke-dasharray",(null==e?void 0:e.strokeDashArray)||"4"),this._container.add(a)}$_findPos(t,e,i,s,n,r){let a=0,h=0;s=Math.max(s,this._grid.length+1);const l=[0,-90],c=l.length;for(;a<s;){const s=this.$_getPoints(a,e,n+h++%4*(Math.PI/4));i&&o.shuffle(s);if(s.some(((e,i)=>{let s=this._options.rotation?l[~~(o.randomLike(i+n)*c)]:0;const a=this.$_getBox(t,e[0],e[1],r,s);if(!this.$_isOverlapping(a)){if(a.bounds.x<0||a.bounds.y<0)return!1;const i=this.$_getBox(t,e[0],e[1],r),{bounds:n}=i,o={x:n.width/2,y:n.height/2};return t.wx=n.x,t.wy=n.y,t.setRotation(o.x,o.y,s),t.box=a,!0}})))return!0;a++}}}class $ extends P{$_findPos(t,e,i,s,n,o){if(this.$_getPoints(s,e,i?Math.random()*Math.PI*2:n).some((e=>{const i=this.$_getBox(t,e[0],e[1],o);if(!this.$_isOverlapping(i))return t.box=i,!0})))return!0}$_getPoints(t,e,i){const s=this._center,n=this._ellipticity,o=2*t*this._unit;let r=-1,a=[];0===t&&a.push([s.c,s.r]);const h=i>Math.PI?1:-1;if(e)for(;++r<o;){const e=r/o,l=i+r*e*h,c=t*e,_=c*Math.cos(l)/n,d=c*Math.sin(l),x=s.c+_,u=s.r+d;a.push([~~x,~~u])}else{let e=this._unit>>1,o=e/n,l=s.c+o*Math.cos(i),c=s.r+e*Math.sin(i);const _=Math.max(1,this._unit>>1),d=_-Math.max(1,_>>1),x=.99;for(;++r>=0;){e=1+d*Math.pow(x,r),o=e/n;switch(3&(h*Math.sqrt(1+8*r)-1)/2){case 0:l+=o;break;case 1:c+=e;break;case 2:l-=o;break;default:c-=e}if(Math.max(Math.abs(l-t),Math.abs(c-t))>t)break;a.push([~~l,~~c])}}return a}$_getBox(t,e,i,s){const n=this._unit,o=t.getBBox(),r=t.hText,a=Math.min(2*this._radius,Math.max(0,e-S(o.width/2/n))),h=Math.min(2*this._radius,Math.max(0,i-S(r/2/n)));return{c1:a,r1:h,c2:a+S(o.width/n)+s,r2:h+S(r/n),w:t.width,h:r}}}class z extends h{constructor(t){super(t,l.POINT_CLASS),this.add(this.hintView=new c(t)),this.hintView.setStyles({stroke:"none",fill:"transparent"}),this.add(this.textView=new _(t)),this.textView.setStyle("pointerEvents","none")}layout(){const t=this.getBBox();this.hintView.setRect({x:0,y:this.yText*z.TOP_PAD,width:t.width,height:this.hText-this.yText}),this.textView.transY(-this.yText*z.TOP_PAD)}}z.TOP_PAD=.5;class F extends d{constructor(t){super(t,"rct-wordcloud-series"),this._pointContainer.add(this._wordContainer=new x(t,null)),this._words=new u(this._wordContainer,z)}_getPointPool(){return this._words}needFronting(){return!1}isEmptyView(){return this._empty}_renderSeries(t,e){const i=this.model.options,s=i.text;if(t!==this._wSave||e!==this._hSave||s!==this._tSave){const n=+new Date;let r=this._visPoints.slice();if(i.minWeight>0&&(r=r.filter((t=>t.yValue>=i.minWeight))),i.minLength>1&&(r=r.filter((t=>t.x.length>=i.minLength))),i.maxCount<r.length&&(r.length=Math.max(0,i.maxCount)),this.$_prepareWords(this.doc,this.model,r),"spiral"===i.placer)this._placer=new $(i).start(this._wordContainer,this._words._internalItems(),i,t,e,(i=>{this.$_layoutWords(t,e)}));else this._placer=new P(i).start(this._wordContainer,this._words._internalItems(),i,t,e,(i=>{this.$_layoutWords(t,e)}));this._wSave=t,this._hSave=e,this._tSave=s,this._empty=r.length<1,o.log(r.length+" words placed in "+(+new Date-n)+"ms.")}else this.$_layoutWords(t,e)}_runShowEffect(t){t&&m.spread(this,(()=>{}))}_doPosRateChanged(t){this.$_layoutWords(this.width,this.height)}$_prepareWords(t,e,i){const s=e._minY,n=e._maxY,o=n-s,r=this.height,a=e.getMaxFontSize(r,1);let h=Math.min(a,e.getMinFontSize(r,0));const l=s===n||h===a,c=l?NaN:e.options.logBase,_=getComputedStyle(this._wordContainer.dom).fontFamily,d=Math.min(2,Math.max(.1,+e.options.textHeight)),x=isNaN(d)?t.createElement("canvas").getContext("2d"):null,u=1-z.TOP_PAD;let m;this._words.prepare(i.length,((n,r)=>{const g=n.point=i[r],y=n.textView;let f=(g.y-s)/o;c>1&&(f=1-(Math.pow(c,1-f)-1)/(c-1));let w=h+(l?(a-h)/2:f*(a-h));const S=g.x;this._preparePoint(t,e,g,n),delete n.box,y.text=S,y.anchor=p.START,y.setStyles({fontSize:M(w)}),y.layoutText(),x?(x.font=`${M(w)} ${_}`,m=x.measureText(S),n.yText=.9*Math.max(0,m.fontBoundingBoxAscent-m.actualBoundingBoxAscent),n.hText=Math.ceil((m.actualBoundingBoxAscent+m.actualBoundingBoxDescent)*(w<=10?1.1:1.08)-.1)+n.yText*u):(n.yText=0,n.hText=n.getBBox().height*d),n.layout(),n.setVis(!0)}))}$_layoutWords(t,e){var i;let s=this._getPosRate();null===(i=this._placer)||void 0===i||i.$_transform(s),s=1-s,this._words.forEach((i=>{const{bounds:n}=i.box,o=n.width,r=n.height,a=(t-o)/2;let h=(e-r)/2;i.trans(i.wx-(i.wx-a)*s,i.wy-(i.wy-h)*s)}))}}function b(t){(function(t){return t.Series&&t.SeriesView})(t)&&(t.Series.register(w),t.SeriesView.register([w,F]))}export{w as WordCloudSeries,b as default};