bubble-chart-js 1.0.19 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bubbleChart.cjs.js +1 -1
- package/dist/bubbleChart.esm.js +1 -1
- package/dist/bubbleChart.umd.js +1 -1
- package/examples/test.html +194 -0
- package/package.json +6 -3
- package/scripts/generate-fixtures.ts +45 -0
- package/spec/config-defaults.json +16 -0
- package/spec/fixtures/3-bubbles.input.json +10 -0
- package/spec/fixtures/equal-values.input.json +11 -0
- package/spec/fixtures/many-bubbles.input.json +17 -0
- package/spec/fixtures/single-bubble.input.json +8 -0
- package/spec/physics.json +11 -0
- package/dist/canvas.d.ts +0 -5
- package/dist/constants/app-constants.d.ts +0 -3
- package/dist/constants/physics.d.ts +0 -10
- package/dist/core/renderer.d.ts +0 -2
- package/dist/features/text-wrapper.d.ts +0 -2
- package/dist/features/tooltip.d.ts +0 -6
- package/dist/index.d.ts +0 -8
- package/dist/models/internal/data-item-info.d.ts +0 -7
- package/dist/models/public/bubble-chart.d.ts +0 -6
- package/dist/models/public/config/bubble-appearance.d.ts +0 -26
- package/dist/models/public/config/font-options.d.ts +0 -46
- package/dist/models/public/config/interaction-options.d.ts +0 -6
- package/dist/models/public/config/tooltip-config.d.ts +0 -4
- package/dist/models/public/config/tooltip-options.d.ts +0 -170
- package/dist/models/public/configuration.d.ts +0 -30
- package/dist/models/public/data-item.d.ts +0 -8
- package/dist/services/chart-service.d.ts +0 -5
- package/dist/services/render-service.d.ts +0 -3
- package/dist/utils/config.d.ts +0 -12
- package/dist/utils/helper.d.ts +0 -2
- package/dist/utils/validation.d.ts +0 -5
package/dist/bubbleChart.cjs.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{"use strict";var t={d:(e,n)=>{for(var o in n)t.o(n,o)&&!t.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:n[o]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};t.r(e),t.d(e,{BubbleChart:()=>h,initializeChart:()=>c});let n="default";function o(t,e){if(!e)return console.error("Invalid containerId."),null;const n=document.getElementById(e);if(!n)return console.error("Container not found."),null;const o=n.parentElement;return o?o.querySelector("#bubbleChartTooltip")||(o.prepend(t),t):(console.error("Parent container not found."),null)}function i(t,e){const n=e.getBoundingClientRect();return{mouseX:t.clientX-n.left,mouseY:t.clientY-n.top}}function a(t,e,n){return n.find(n=>Math.hypot(t-n.x,e-n.y)<n.radius)||null}class r{}r.TRANSPARENT="transparent";const l={forceStrength:.008,iterations:1e3,damping:.65,boundaryForce:.02,centerForce:.12,centerAttraction:.8,centerDamping:.3,centerRadiusBuffer:35};function s(t,e=14,n=400,o=6){const i=n>=700?1.25:n>=500?1.1:1,a=Math.min(t/o,t/1.2);let r=Math.min(e*i,a,.8*t);return r=Math.max(r,Math.max(8,t/6)),Math.round(r)}function d(t){if(!function(t){return t?!(!Array.isArray(t.data)||0===t.data.length)||(console.error("Invalid or empty data array"),!1):(console.error("Invalid config object"),!1)}(t))return;let e=function(t){var e,n;const o=document.getElementById(t.canvasContainerId);if(!o)return console.error(`Canvas container with ID '${t.canvasContainerId}' not found.`),null;if(o.querySelector("canvas"))return console.error("A canvas already exists inside the container."),null;const i=document.createElement("canvas");return Object.assign(i.style,{border:(null===(e=t.canvasBorderColor)||void 0===e?void 0:e.trim())?`1px solid #${t.canvasBorderColor}`:r.TRANSPARENT,background:(null===(n=t.canvasBackgroundColor)||void 0===n?void 0:n.trim())?`#${t.canvasBackgroundColor}`:r.TRANSPARENT,width:"100%",height:"100%",display:"block",imageRendering:"crisp-edges",aspectRatio:"1 / 1"}),i.style.setProperty("image-rendering","-moz-crisp-edges"),i.style.setProperty("image-rendering","-webkit-optimize-contrast"),i.style.setProperty("-ms-interpolation-mode","nearest-neighbor"),o.appendChild(i),i}(t);if(!e)return;const d=e.getContext("2d");if(!d)return void console.error("Invalid context");const{width:u,height:c}=m(e,d),h=function(t,e,n){const o=Math.min((e-10)/2,(n-10)/2),i=e/2,a=n/2,r=[...t.data].sort((t,e)=>e.value-t.value).map(t=>Object.assign(Object.assign({},t),{radius:0,x:0,y:0,fixed:!1})),s=r[0].value,d=Math.min(.5*o,.2*Math.min(e,n)),u=Math.max(.3*d,.05*Math.min(e,n));r.forEach(t=>{const o=t.value/s;t.radius=u+o*(d-u),t.radius=Math.min(t.radius,(e-10)/2,(n-10)/2)}),r.forEach((t,o)=>{if(0===o)t.x=i,t.y=a,t.fixed=!0;else{const l=r[0].radius+t.radius+3,s=Math.PI*(3-Math.sqrt(5)),d=e-5-t.radius,u=n-5-t.radius;t.x=Math.min(d,Math.max(5+t.radius,i+Math.cos(s*o)*l)),t.y=Math.min(u,Math.max(5+t.radius,a+Math.sin(s*o)*l)),t.fixed=!1}});for(let t=0;t<l.iterations;t++)r.forEach((t,n)=>{if(0===n){const e=i-t.x,n=a-t.y;return void(Math.hypot(e,n)>2&&(t.x+=e*l.centerDamping,t.y+=n*l.centerDamping))}let o=0,d=0;const u=t.radius+5;t.x<u?o+=(u-t.x)*l.boundaryForce:t.x>e-u&&(o+=(e-u-t.x)*l.boundaryForce),r.forEach(e=>{if(t===e)return;const n=t.x-e.x,r=t.y-e.y,u=Math.hypot(n,r),c=t.radius+e.radius;if(u<1.5*c){const t=l.forceStrength*(c/Math.max(u,.1));o+=n/u*t,d+=r/u*t}const h=i-t.x,f=a-t.y,m=Math.hypot(h,f),y=t.value/s*.02;t.x+=h/m*y,t.y+=f/m*y});const c=i-t.x,h=a-t.y,f=Math.hypot(c,h),m=r[0].radius+t.radius+l.centerRadiusBuffer,y=(l.centerForce,Math.pow(t.value/s,.3),l.centerAttraction*(1-t.value/s)*(1-Math.min(1,f/m)));t.x+=c*y,t.y+=h*y,t.x+=o*(1-l.damping),t.y+=d*(1-l.damping)}),r.forEach((t,e)=>{r.forEach((n,o)=>{if(e>=o)return;if(0===e||0===o){const o=0===e?t:n,i=0===e?n:t,a=i.x-o.x,r=i.y-o.y,l=Math.hypot(a,r),s=o.radius+i.radius+2;if(l<s){const t=s-l,e=Math.atan2(r,a);i.x+=Math.cos(e)*t*.7,i.y+=Math.sin(e)*t*.7}return}const i=t.x-n.x,a=t.y-n.y,r=Math.hypot(i,a),s=t.radius+n.radius-5;if(r<s){const e=(s-r)*(.3+5*l.forceStrength),o=Math.atan2(a,i),d=n.radius/(t.radius+n.radius);t.fixed||(t.x+=Math.cos(o)*e*d,t.y+=Math.sin(o)*e*d),n.fixed||(n.x-=Math.cos(o)*e*(1-d),n.y-=Math.sin(o)*e*(1-d))}})});return r.forEach(t=>{const o=Math.max(5+t.radius,Math.min(e-5-t.radius,t.x)),i=Math.max(5+t.radius,Math.min(n-5-t.radius,t.y));(!t.fixed||Math.hypot(t.x-o,t.y-i)>2)&&(t.x=o,t.y=i)}),r}(t,u,c);function f(){e&&d?(m(e,d),d.clearRect(0,0,e.width,e.height),h.forEach(e=>{const{x:n,y:o,radius:i,bubbleColor:a,borderColor:r,borderThickness:l,opacity:u,fontColor:c,fontFamily:h,fontSize:f,fontStyle:m,fontWeight:y,textAlign:v,textTransform:g,textBaseline:p}=function(t,e){var n,o,i,a,r,l,d,u,c,h,f,m;return{x:t.x,y:t.y,radius:Math.max(t.radius||0,e.minRadius||10),bubbleColor:null!==(o=null!==(n=t.bubbleColor)&&void 0!==n?n:e.defaultBubbleColor)&&void 0!==o?o:"#3498db",borderColor:null!==(i=t.borderColor)&&void 0!==i?i:"black",borderThickness:Math.max(null!==(a=t.borderThickness)&&void 0!==a?a:.25,0),opacity:void 0!==t.opacity?Math.max(0,Math.min(1,t.opacity)):1,fontStyle:t.fontStyle||"normal",fontWeight:"number"==typeof t.fontWeight&&t.fontWeight>=100&&t.fontWeight<=900?t.fontWeight:400,textAlign:null!==(r=t.textAlign)&&void 0!==r?r:"center",textTransform:null!==(l=t.textTransform)&&void 0!==l?l:"none",fontColor:null!==(u=null!==(d=t.fontColor)&&void 0!==d?d:e.defaultFontColor)&&void 0!==u?u:"#000",textBaseline:null!==(c=t.textBaseline)&&void 0!==c?c:"middle",fontSize:Math.max(s(t.radius||e.minRadius||10,null!==(h=e.fontSize)&&void 0!==h?h:14,null!==(f=t.fontWeight)&&void 0!==f?f:400),8),fontFamily:t.fontFamily&&"string"==typeof t.fontFamily&&"Arial"!==t.fontFamily?`${t.fontFamily}, Arial, sans-serif`:`${null!==(m=e.defaultFontFamily)&&void 0!==m?m:"Arial"}, sans-serif`}}(e,t);d.beginPath(),d.arc(n,o,i,0,2*Math.PI),d.fillStyle=a,d.fill(),d.strokeStyle=r,d.lineWidth=l,d.stroke();const x=`${m} ${y} ${f}px ${h}`;d.fillStyle=c,d.font=x,d.imageSmoothingEnabled=!0,d.imageSmoothingQuality="high",d.textAlign=v,d.textBaseline=p;let b=e.label||"";if("uppercase"===g?b=b.toUpperCase():"lowercase"===g?b=b.toLowerCase():"capitalize"===g&&(b=b.replace(/\b\w/g,t=>t.toUpperCase())),t.textWrap){const a=1.5*i-10,r=1.4*f,l=function(t,e,n,o,i,a=14,r=400,l="normal",s="Arial",d=0,u=5,c=1.2){const h=1.5*(i-u),f=a*c,m=Math.max(1,Math.floor(h/f)),y="auto"===o||void 0===o?m:Math.min(o,m);n=Math.max(0,n-2*d);const v=e.split(" ");let g="";const p=[];let x=!1,b=!1;t.font=`${r||""} ${l||""} ${a}px ${s}`,t.imageSmoothingEnabled=!0,t.imageSmoothingQuality="high";for(const e of v){const o=g?`${g} ${e}`:e;if(t.measureText(o).width<=n)g=o;else if(g.trim()&&p.push(g),g=e,t.measureText(g).width>n){let e=g;for(;t.measureText(e+"...").width>n&&e.length>0;)e=e.slice(0,-1);p.push(e+"..."),b=!0;break}if(p.length>=y){x=!0;break}}if(g&&p.length<y&&!b&&p.push(g),x&&p.length>0){let e=p[p.length-1];for(;t.measureText(e+"...").width>n&&e.length>0;)e=e.slice(0,-1);p[p.length-1]=e+"..."}return p}(d,e.label,a,t.maxLines,i,f,y,m,h),s=o-(l.length-1)*r/2;l.forEach((t,e)=>{const o=Math.round(n),i=Math.round(s+e*r);d.fillText(t,o,i)})}else d.fillText(e.label,Math.round(n),Math.round(o))})):console.warn("canvas or ctx is not valid")}function m(t,e){const n=window.devicePixelRatio||1,o=t.getBoundingClientRect();return t.width=o.width*n,t.height=o.height*n,t.style.width=`${o.width}px`,t.style.height=`${o.height}px`,e.setTransform(1,0,0,1,0,0),e.scale(n,n),{width:o.width,height:o.height,dpr:n}}function y(){const n=document.getElementById(t.canvasContainerId);n&&e&&(e.width=n.offsetWidth,e.height=n.offsetHeight,e.getContext("2d"),f())}let v;t.isResizeCanvasOnWindowSizeChange&&(y(),window.addEventListener("resize",y)),f(),t.showToolTip&&(v=function(t){var e,n,i,a,r,l,s,d,u,c,h,f,m,y,v,g,p,x;const b=null===(n=null===(e=t.data[0].toolTipConfig)||void 0===e?void 0:e.tooltipFormattedData)||void 0===n?void 0:n.trim();if(b){const e=document.createElement("div");e.innerHTML=b.trim();const n=e.firstElementChild;return n.style.display="none",n.style.visibility="hidden",n.style.opacity="0",n.style.position="absolute",o(n,t.canvasContainerId)}const M=document.createElement("div");M.id="bubbleChartTooltip",M.style.display="none";const C=null!==(i=null==t?void 0:t.tooltipOptions)&&void 0!==i?i:{},S=(t,e)=>"number"==typeof t?`${t}px`:null!=t?t:e;return Object.assign(M.style,{position:"absolute",padding:S(C.padding,"8px"),margin:S(C.margin,"0"),background:null!==(a=C.backgroundColor)&&void 0!==a?a:"rgba(0, 0, 0, 0.85)",color:null!==(r=C.fontColor)&&void 0!==r?r:"white",borderRadius:"4px",pointerEvents:null!==(l=C.pointerEvents)&&void 0!==l?l:"none",fontFamily:null!==(s=C.fontFamily)&&void 0!==s?s:"Arial, sans-serif",fontSize:S(C.fontSize,"14px"),fontWeight:String(null!==(d=C.fontWeight)&&void 0!==d?d:"400"),fontStyle:null!==(u=C.fontStyle)&&void 0!==u?u:"normal",textAlign:null!==(c=C.textAlign)&&void 0!==c?c:"left",textDecoration:null!==(h=C.textDecoration)&&void 0!==h?h:"none",textTransform:null!==(f=C.textTransform)&&void 0!==f?f:"none",letterSpacing:S(C.letterSpacing,"normal"),border:(()=>{var t;if(!C.borderStyle)return"none";const e=S(C.borderWidth,"1px"),n=null!==(t=C.borderColor)&&void 0!==t?t:"transparent";return`${e} ${C.borderStyle} ${n}`})(),boxShadow:null!==(m=C.boxShadow)&&void 0!==m?m:"none",maxWidth:S(C.maxWidth,"200px"),minWidth:S(C.minWidth,"auto"),maxHeight:S(C.maxHeight,"none"),minHeight:S(C.minHeight,"auto"),zIndex:String(null!==(y=C.zIndex)&&void 0!==y?y:1e3),transition:null!==(v=C.transition)&&void 0!==v?v:"opacity 0.2s",transform:null!==(g=C.transform)&&void 0!==g?g:"none",backdropFilter:null!==(p=C.backdropFilter)&&void 0!==p?p:"none",opacity:String(null!==(x=C.opacity)&&void 0!==x?x:1),display:"none",visibility:"hidden"}),o(M,t.canvasContainerId),M}(t));let g=null;if(e.addEventListener("mousemove",o=>{g||(g=requestAnimationFrame(()=>{(function(t,e,o,r,l){const{mouseX:s,mouseY:d}=i(t,o),u=a(s,d,e);n=(null==l?void 0:l.cursorType)||"pointer",o.style.cursor="default",r&&(u?function(t,e,o,i){if(e&&e.value&&o&&i){o.style.cursor=n,i.style.display="block",i.innerHTML=function(t){var e,n,o;if(!t)return"";const i=null===(n=null===(e=t.toolTipConfig)||void 0===e?void 0:e.tooltipText)||void 0===n?void 0:n.trim();if(i)return`<div>${i}</div>`;const a=null===(o=t.label)||void 0===o?void 0:o.trim();return a?`<div>${a}<br>Value: ${t.value}</div>`:`<div>${t.value}</div>`}(e);const a=o.getBoundingClientRect();i.style.left=t.clientX-a.left+15+"px",i.style.top=t.clientY-a.top+15+"px",i.style.zIndex="999999",i.style.visibility="visible",i.style.opacity="1",i.style.position="absolute"}}(t,u,o,r):(o.style.cursor="default",r.style.display="none",r.style.visibility="hidden",r.style.opacity="0"))})(o,h,e,v,t),g=null}))}),t.onBubbleClick){let n=null;e.addEventListener("click",o=>{n||(n=requestAnimationFrame(()=>{!function(t,e,n,o){const{mouseX:r,mouseY:l}=i(t,n),s=a(r,l,e);null!=s&&o.onBubbleClick&&o.onBubbleClick(s,t)}(o,h,e,t),n=null}))})}}const u={defaultBubbleColor:"#3498DB",defaultFontColor:"#ffffff",minRadius:10,maxLines:"auto",textWrap:!0,isResizeCanvasOnWindowSizeChange:!0,fontSize:14,defaultFontFamily:"Arial",showToolTip:!0};function c(t={}){var e,n;if(!t)return void console.error("Configuration is not valid. Chart initialization aborted.");if(!t.data||0===t.data.length)return void console.error("No valid data provided. Chart initialization aborted.");const o=(i=Object.assign({canvasContainerId:null!==(e=t.canvasContainerId)&&void 0!==e?e:"chart-container",data:null!==(n=t.data)&&void 0!==n?n:[]},t),Object.assign(Object.assign({},u),i));var i;return d(o),o}class h{constructor(t){const e=c(t);e&&(this.configuration=e)}render(){this.configuration&&d(this.configuration)}}window.initializeChart=c,module.exports=e})();
|
|
1
|
+
(()=>{"use strict";var t={d:(e,n)=>{for(var i in n)t.o(n,i)&&!t.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:n[i]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};t.r(e),t.d(e,{BubbleChart:()=>m,initializeChart:()=>v});const n={defaultBubbleColor:"#3498DB",defaultFontColor:"#ffffff",minRadius:10,maxLines:"auto",textWrap:!0,isResizeCanvasOnWindowSizeChange:!0,fontSize:14,defaultFontFamily:"Arial",showToolTip:!0},i=JSON.parse('{"FC":0.008,"rX":1000,"d6":0.65,"WH":0.02,"ND":0.12,"$l":0.8,"cg":0.3,"e0":35}');function o(t,e){t.forEach((n,i)=>{t.forEach((t,o)=>{if(i>=o)return;if(0===i||0===o){const e=0===i?n:t,o=0===i?t:n,a=o.x-e.x,r=o.y-e.y,l=Math.hypot(a,r),s=e.radius+o.radius+2;if(l<s){const t=s-l,e=Math.atan2(r,a);o.x+=Math.cos(e)*t*.7,o.y+=Math.sin(e)*t*.7}return}const a=n.x-t.x,r=n.y-t.y,l=Math.hypot(a,r),s=n.radius+t.radius-5;if(l<s){const i=(s-l)*(.3+5*e.forceStrength),o=Math.atan2(r,a),d=n.radius+t.radius,c=d>0?t.radius/d:.5;n.fixed||(n.x+=Math.cos(o)*i*c,n.y+=Math.sin(o)*i*c),t.fixed||(t.x-=Math.cos(o)*i*(1-c),t.y-=Math.sin(o)*i*(1-c))}})})}function a(t,e=14,n=400,i=6){const o=n>=700?1.25:n>=500?1.1:1,a=Math.min(t/i,t/1.2);let r=Math.min(e*o,a,.8*t);return r=Math.max(r,Math.max(8,t/6)),Math.round(r)}class r{constructor(t){this.canvas=t;const e=t.getContext("2d");if(!e)throw new Error("Failed to get 2D rendering context from canvas");this.ctx=e}getContext(){return this.ctx}getCanvas(){return this.canvas}setup(){const t=window.devicePixelRatio||1,e=this.canvas.getBoundingClientRect();return this.canvas.width=e.width*t,this.canvas.height=e.height*t,this.canvas.style.width=`${e.width}px`,this.canvas.style.height=`${e.height}px`,this.ctx.setTransform(1,0,0,1,0,0),this.ctx.scale(t,t),{width:e.width,height:e.height}}getSize(){const t=this.canvas.getBoundingClientRect();return{width:t.width,height:t.height}}clear(){this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height)}drawCircle(t,e,n,i,o,a,r){this.ctx.beginPath(),this.ctx.arc(t,e,n,0,2*Math.PI),this.ctx.fillStyle=i,this.ctx.fill(),a>0&&(this.ctx.strokeStyle=o,this.ctx.lineWidth=a,this.ctx.stroke())}drawText(t,e,n,i){const o=`${i.fontStyle} ${i.fontWeight} ${i.fontSize}px ${i.fontFamily}`;this.ctx.fillStyle=i.fontColor,this.ctx.font=o,this.ctx.imageSmoothingEnabled=!0,this.ctx.imageSmoothingQuality="high",this.ctx.textAlign=i.textAlign,this.ctx.textBaseline=i.textBaseline,this.ctx.fillText(t,Math.round(e),Math.round(n))}destroy(){const t=this.canvas.parentElement;t&&t.removeChild(this.canvas)}}class l{constructor(t){this.ctx=t}measureWidth(t,e,n,i,o){return this.ctx.font=`${i} ${n} ${e}px ${o}`,this.ctx.imageSmoothingEnabled=!0,this.ctx.imageSmoothingQuality="high",this.ctx.measureText(t).width}}function s(t,e){const n=`bubbleChartTooltip-${e}`;return document.body.querySelector(`#${n}`)||(t.id=n,document.body.appendChild(t),t)}function d(t,e){const n=e.getBoundingClientRect(),i=window.devicePixelRatio||1;return{mouseX:(t.clientX-n.left)*i,mouseY:(t.clientY-n.top)*i}}function c(t,e,n){return n.find(n=>Math.hypot(t-n.x,e-n.y)<n.radius)||null}function u(t){let e=null;return{handle:n=>{e||(e=requestAnimationFrame(()=>{t(n),e=null}))},cancel:()=>{e&&(cancelAnimationFrame(e),e=null)}}}class h{}function f(t){if(!function(t){return t?!(!Array.isArray(t.data)||0===t.data.length)||(console.error("Invalid or empty data array"),!1):(console.error("Invalid config object"),!1)}(t))return;const e=function(t){var e,n;const i=document.getElementById(t.canvasContainerId);if(!i)return console.error(`Canvas container with ID '${t.canvasContainerId}' not found.`),null;if(i.querySelector("canvas"))return console.error("A canvas already exists inside the container."),null;const o=document.createElement("canvas");return Object.assign(o.style,{border:(null===(e=t.canvasBorderColor)||void 0===e?void 0:e.trim())?`1px solid #${t.canvasBorderColor}`:h.TRANSPARENT,background:(null===(n=t.canvasBackgroundColor)||void 0===n?void 0:n.trim())?`#${t.canvasBackgroundColor}`:h.TRANSPARENT,width:"100%",height:"100%",display:"block",imageRendering:"crisp-edges",aspectRatio:"1 / 1"}),o.style.setProperty("image-rendering","-moz-crisp-edges"),o.style.setProperty("image-rendering","-webkit-optimize-contrast"),o.style.setProperty("-ms-interpolation-mode","nearest-neighbor"),i.appendChild(o),o}(t);if(!e)return;const n=new r(e),m=new l(n.getContext()),{width:v,height:y}=n.setup();let x=function(t,e,n,a){const r=Object.assign({forceStrength:i.FC,iterations:i.rX,damping:i.d6,boundaryForce:i.WH,centerForce:i.ND,centerAttraction:i.$l,centerDamping:i.cg,centerRadiusBuffer:i.e0},a),l=Math.min((e-10)/2,(n-10)/2),s=e/2,d=n/2,c=[...t].sort((t,e)=>e.value-t.value).map(t=>Object.assign(Object.assign({},t),{radius:0,x:0,y:0,fixed:!1}));if(0===c.length)return c;const u=c[0].value,h=Math.min(.5*l,.2*Math.min(e,n)),f=Math.max(.3*h,.05*Math.min(e,n));return c.forEach(t=>{const i=u>0?t.value/u:1;t.radius=f+i*(h-f),t.radius=Math.max(0,Math.min(t.radius,(e-10)/2,(n-10)/2))}),c.forEach((t,i)=>{if(0===i)t.x=s,t.y=d,t.fixed=!0;else{const o=c[0].radius+t.radius+3,a=Math.PI*(3-Math.sqrt(5)),r=e-5-t.radius,l=n-5-t.radius;t.x=Math.min(r,Math.max(5+t.radius,s+Math.cos(a*i)*o)),t.y=Math.min(l,Math.max(5+t.radius,d+Math.sin(a*i)*o)),t.fixed=!1}}),function(t,e,n,i,a,r,l){for(let i=0;i<e.iterations;i++)t.forEach((i,o)=>{if(0===o){const t=a-i.x,n=r-i.y;return void(Math.hypot(t,n)>2&&(i.x+=t*e.centerDamping,i.y+=n*e.centerDamping))}let s=0,d=0;const c=i.radius+5;i.x<c?s+=(c-i.x)*e.boundaryForce:i.x>n-c&&(s+=(n-c-i.x)*e.boundaryForce),t.forEach(t=>{if(i===t)return;const n=i.x-t.x,o=i.y-t.y,c=Math.hypot(n,o),u=i.radius+t.radius;if(c<1.5*u){const t=e.forceStrength*(u/Math.max(c,.1));s+=n/c*t,d+=o/c*t}const h=a-i.x,f=r-i.y,m=Math.hypot(h,f),v=i.value/l*.02;i.x+=h/m*v,i.y+=f/m*v});const u=a-i.x,h=r-i.y,f=Math.hypot(u,h),m=t[0].radius+i.radius+e.centerRadiusBuffer,v=e.centerAttraction*(1-i.value/l)*(1-Math.min(1,f/m));i.x+=u*v,i.y+=h*v,i.x+=s*(1-e.damping),i.y+=d*(1-e.damping)}),o(t,e)}(c,r,e,0,s,d,u),function(t,e,n){t.forEach(t=>{const i=Math.max(5+t.radius,Math.min(e-5-t.radius,t.x)),o=Math.max(5+t.radius,Math.min(n-5-t.radius,t.y));(!t.fixed||Math.hypot(t.x-i,t.y-o)>2)&&(t.x=i,t.y=o)})}(c,e,n),c}(t.data,v,y);function g(){n.setup(),n.clear(),x.forEach(e=>{const i=function(t,e,n){var i,o,r,l,s,d,c,u,h,f,m;let v=null!==(i=n.defaultBubbleColor)&&void 0!==i?i:"#3498db";if(t.bubbleColor)v=t.bubbleColor;else if(n.colorPalette&&n.colorPalette.length>0){const i=e.findIndex(e=>e.label===t.label&&e.value===t.value),o=i>=0?i:0;v=n.colorPalette[o%n.colorPalette.length]}const y=Math.max(t.radius||0,n.minRadius||10);return{bubbleColor:v,borderColor:null!==(o=t.borderColor)&&void 0!==o?o:"black",borderThickness:Math.max(null!==(r=t.borderThickness)&&void 0!==r?r:.25,0),opacity:void 0!==t.opacity?Math.max(0,Math.min(1,t.opacity)):1,fontStyle:t.fontStyle||"normal",fontWeight:"number"==typeof t.fontWeight&&t.fontWeight>=100&&t.fontWeight<=900?t.fontWeight:400,textAlign:null!==(l=t.textAlign)&&void 0!==l?l:"center",textTransform:null!==(s=t.textTransform)&&void 0!==s?s:"none",fontColor:null!==(c=null!==(d=t.fontColor)&&void 0!==d?d:n.defaultFontColor)&&void 0!==c?c:"#000",textBaseline:null!==(u=t.textBaseline)&&void 0!==u?u:"middle",fontSize:Math.max(a(y,null!==(h=n.fontSize)&&void 0!==h?h:14,null!==(f=t.fontWeight)&&void 0!==f?f:400),8),fontFamily:t.fontFamily&&"string"==typeof t.fontFamily&&"Arial"!==t.fontFamily?`${t.fontFamily}, Arial, sans-serif`:`${null!==(m=n.defaultFontFamily)&&void 0!==m?m:"Arial"}, sans-serif`}}(e,x,t);n.drawCircle(e.x,e.y,Math.max(e.radius||0,t.minRadius||10),i.bubbleColor,i.borderColor,i.borderThickness,i.opacity);let o=e.label||"";"uppercase"===i.textTransform?o=o.toUpperCase():"lowercase"===i.textTransform?o=o.toLowerCase():"capitalize"===i.textTransform&&(o=o.replace(/\b\w/g,t=>t.toUpperCase()));const r=Math.max(e.radius||0,t.minRadius||10),l={fontSize:i.fontSize,fontFamily:i.fontFamily,fontWeight:i.fontWeight,fontStyle:i.fontStyle,fontColor:i.fontColor,textAlign:i.textAlign,textBaseline:i.textBaseline};if(t.textWrap){const o=1.5*r-10,a=1.4*i.fontSize,s=function(t,e,n,i,o,a=14,r=400,l="normal",s="Arial",d=0,c=5,u=1.2){const h=1.5*(o-c),f=a*u,m=Math.max(1,Math.floor(h/f)),v="auto"===i||void 0===i?m:Math.min(i,m);n=Math.max(0,n-2*d);const y=e.split(" ");let x="";const g=[];let p=!1,b=!1;const C=e=>t.measureWidth(e,a,r,l,s);for(const t of y){const e=x?`${x} ${t}`:t;if(C(e)<=n)x=e;else if(x.trim()&&g.push(x),x=t,C(x)>n){let t=x;for(;C(t+"...")>n&&t.length>0;)t=t.slice(0,-1);g.push(t+"..."),b=!0;break}if(g.length>=v){p=!0;break}}if(x&&g.length<v&&!b&&g.push(x),p&&g.length>0){let t=g[g.length-1];for(;C(t+"...")>n&&t.length>0;)t=t.slice(0,-1);g[g.length-1]=t+"..."}return g}(m,e.label,o,t.maxLines,r,i.fontSize,i.fontWeight,i.fontStyle,i.fontFamily),d=e.y-(s.length-1)*a/2;s.forEach((t,i)=>{n.drawText(t,e.x,d+i*a,l)})}else n.drawText(o,e.x,e.y,l)})}let p=null;if(t.isResizeCanvasOnWindowSizeChange){const e=document.getElementById(t.canvasContainerId);e&&(p=function(t,e){let n=null,i=null;const o=()=>{i||(i=requestAnimationFrame(()=>{e(),i=null}))};return"undefined"!=typeof ResizeObserver?(n=new ResizeObserver(o),n.observe(t)):(o(),window.addEventListener("resize",o)),{destroy:()=>{n&&(n.disconnect(),n=null),window.removeEventListener("resize",o),i&&(cancelAnimationFrame(i),i=null)}}}(e,()=>{const t=n.getCanvas();e&&t&&(t.width=e.offsetWidth,t.height=e.offsetHeight,g())}))}g();let b=null;t.showToolTip&&(b=function(t){var e,n,i,o,a,r,l,d,c,u,h,f,m,v,y,x,g,p,b;const C=null===(i=null===(n=null===(e=t.data[0])||void 0===e?void 0:e.toolTipConfig)||void 0===n?void 0:n.tooltipFormattedData)||void 0===i?void 0:i.trim();if(C){const e=document.createElement("div");e.innerHTML=C.trim();const n=e.firstElementChild;return n.style.display="none",n.style.visibility="hidden",n.style.opacity="0",n.style.position="absolute",s(n,t.canvasContainerId)}const M=document.createElement("div");M.style.display="none";const w=null!==(o=null==t?void 0:t.tooltipOptions)&&void 0!==o?o:{},S=(t,e)=>"number"==typeof t?`${t}px`:null!=t?t:e;return Object.assign(M.style,{position:"absolute",padding:S(w.padding,"8px"),margin:S(w.margin,"0"),background:null!==(a=w.backgroundColor)&&void 0!==a?a:"rgba(0, 0, 0, 0.85)",color:null!==(r=w.fontColor)&&void 0!==r?r:"white",borderRadius:"4px",pointerEvents:null!==(l=w.pointerEvents)&&void 0!==l?l:"none",fontFamily:null!==(d=w.fontFamily)&&void 0!==d?d:"Arial, sans-serif",fontSize:S(w.fontSize,"14px"),fontWeight:String(null!==(c=w.fontWeight)&&void 0!==c?c:"400"),fontStyle:null!==(u=w.fontStyle)&&void 0!==u?u:"normal",textAlign:null!==(h=w.textAlign)&&void 0!==h?h:"left",textDecoration:null!==(f=w.textDecoration)&&void 0!==f?f:"none",textTransform:null!==(m=w.textTransform)&&void 0!==m?m:"none",letterSpacing:S(w.letterSpacing,"normal"),border:(()=>{var t;if(!w.borderStyle)return"none";const e=S(w.borderWidth,"1px"),n=null!==(t=w.borderColor)&&void 0!==t?t:"transparent";return`${e} ${w.borderStyle} ${n}`})(),boxShadow:null!==(v=w.boxShadow)&&void 0!==v?v:"none",maxWidth:S(w.maxWidth,"200px"),minWidth:S(w.minWidth,"auto"),maxHeight:S(w.maxHeight,"none"),minHeight:S(w.minHeight,"auto"),zIndex:String(null!==(y=w.zIndex)&&void 0!==y?y:1e3),transition:null!==(x=w.transition)&&void 0!==x?x:"opacity 0.2s",transform:null!==(g=w.transform)&&void 0!==g?g:"none",backdropFilter:null!==(p=w.backdropFilter)&&void 0!==p?p:"none",opacity:String(null!==(b=w.opacity)&&void 0!==b?b:1),display:"none",visibility:"hidden"}),s(M,t.canvasContainerId),M}(t));const C=n.getCanvas(),M=u(e=>{const{mouseX:n,mouseY:i}=d(e,C),o=c(n,i,x);if(o){const n=(null==t?void 0:t.cursorType)||"pointer";if(C.style.cursor=n,b){const n=function(t,e){var n,i,o;if(!t)return"";if(e.tooltipOptions&&"function"==typeof e.tooltipOptions.formatter)return e.tooltipOptions.formatter(t);const a=null===(i=null===(n=t.toolTipConfig)||void 0===n?void 0:n.tooltipText)||void 0===i?void 0:i.trim();if(a)return`<div>${a}</div>`;const r=null===(o=t.label)||void 0===o?void 0:o.trim();return r?`<div>${r}<br>Value: ${t.value}</div>`:`<div>${t.value}</div>`}(o,t);!function(t,e,n,i){e&&n&&(e.style.display="block",e.innerHTML=i,e.style.left=`${t.pageX+15}px`,e.style.top=`${t.pageY+15}px`,e.style.zIndex="999999",e.style.visibility="visible",e.style.opacity="1",e.style.position="absolute")}(e,b,C,n)}}else C.style.cursor="default",function(t){t&&(t.style.display="none",t.style.visibility="hidden",t.style.opacity="0")}(b)});C.addEventListener("mousemove",M.handle);const w=u(e=>{const{mouseX:n,mouseY:i}=d(e,C),o=c(n,i,x);o&&t.onBubbleClick&&t.onBubbleClick(o,e)});t.onBubbleClick&&C.addEventListener("click",w.handle);const S=()=>{null==p||p.destroy(),M.cancel(),w.cancel(),C.removeEventListener("mousemove",M.handle),C.removeEventListener("click",w.handle),n.destroy(),(null==b?void 0:b.parentElement)&&b.parentElement.removeChild(b),b=null};return{destroy:S,update:e=>(S(),t.data=e,f(t))}}h.TRANSPARENT="transparent";class m{constructor(t){const e=function(t={}){var e,i;if(!t)return void console.error("Configuration is not valid. Chart initialization aborted.");if(!t.data||0===t.data.length)return void console.error("No valid data provided. Chart initialization aborted.");const o=(a=Object.assign({canvasContainerId:null!==(e=t.canvasContainerId)&&void 0!==e?e:"chart-container",data:null!==(i=t.data)&&void 0!==i?i:[]},t),Object.assign(Object.assign({},n),a));var a;const r=f(o);return r?{config:o,instance:r}:void 0}(t);e&&(this.configuration=e.config,this.instance=e.instance)}destroy(){this.instance&&this.instance.destroy()}update(t){this.instance&&(this.instance=this.instance.update(t))}}function v(t){return new m(t)}"undefined"!=typeof window&&(window.initializeChart=v,window.BubbleChart=m),module.exports=e})();
|
package/dist/bubbleChart.esm.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
let t="default";function n(t,n){if(!n)return console.error("Invalid containerId."),null;const e=document.getElementById(n);if(!e)return console.error("Container not found."),null;const o=e.parentElement;return o?o.querySelector("#bubbleChartTooltip")||(o.prepend(t),t):(console.error("Parent container not found."),null)}function e(t,n){const e=n.getBoundingClientRect();return{mouseX:t.clientX-e.left,mouseY:t.clientY-e.top}}function o(t,n,e){return e.find(e=>Math.hypot(t-e.x,n-e.y)<e.radius)||null}class i{}i.TRANSPARENT="transparent";function a(t,n=14,e=400,o=6){const i=e>=700?1.25:e>=500?1.1:1,a=Math.min(t/o,t/1.2);let r=Math.min(n*i,a,.8*t);return r=Math.max(r,Math.max(8,t/6)),Math.round(r)}function r(r){if(!function(t){return t?!(!Array.isArray(t.data)||0===t.data.length)||(console.error("Invalid or empty data array"),!1):(console.error("Invalid config object"),!1)}(r))return;let l=function(t){var n,e;const o=document.getElementById(t.canvasContainerId);if(!o)return console.error(`Canvas container with ID '${t.canvasContainerId}' not found.`),null;if(o.querySelector("canvas"))return console.error("A canvas already exists inside the container."),null;const a=document.createElement("canvas");return Object.assign(a.style,{border:(null===(n=t.canvasBorderColor)||void 0===n?void 0:n.trim())?`1px solid #${t.canvasBorderColor}`:i.TRANSPARENT,background:(null===(e=t.canvasBackgroundColor)||void 0===e?void 0:e.trim())?`#${t.canvasBackgroundColor}`:i.TRANSPARENT,width:"100%",height:"100%",display:"block",imageRendering:"crisp-edges",aspectRatio:"1 / 1"}),a.style.setProperty("image-rendering","-moz-crisp-edges"),a.style.setProperty("image-rendering","-webkit-optimize-contrast"),a.style.setProperty("-ms-interpolation-mode","nearest-neighbor"),o.appendChild(a),a}(r);if(!l)return;const s=l.getContext("2d");if(!s)return void console.error("Invalid context");const{width:d,height:u}=f(l,s),c=function(t,n,e){const o=Math.min((n-10)/2,(e-10)/2),i=n/2,a=e/2,r=[...t.data].sort((t,n)=>n.value-t.value).map(t=>Object.assign(Object.assign({},t),{radius:0,x:0,y:0,fixed:!1})),l=r[0].value,s=Math.min(.5*o,.2*Math.min(n,e)),d=Math.max(.3*s,.05*Math.min(n,e));r.forEach(t=>{const o=t.value/l;t.radius=d+o*(s-d),t.radius=Math.min(t.radius,(n-10)/2,(e-10)/2)}),r.forEach((t,o)=>{if(0===o)t.x=i,t.y=a,t.fixed=!0;else{const l=r[0].radius+t.radius+3,s=Math.PI*(3-Math.sqrt(5)),d=n-5-t.radius,u=e-5-t.radius;t.x=Math.min(d,Math.max(5+t.radius,i+Math.cos(s*o)*l)),t.y=Math.min(u,Math.max(5+t.radius,a+Math.sin(s*o)*l)),t.fixed=!1}});for(let t=0;t<1e3;t++)r.forEach((t,e)=>{if(0===e){const n=i-t.x,e=a-t.y;return void(Math.hypot(n,e)>2&&(t.x+=.3*n,t.y+=.3*e))}let o=0,s=0;const d=t.radius+5;t.x<d?o+=.02*(d-t.x):t.x>n-d&&(o+=.02*(n-d-t.x)),r.forEach(n=>{if(t===n)return;const e=t.x-n.x,r=t.y-n.y,d=Math.hypot(e,r),u=t.radius+n.radius;if(d<1.5*u){const t=u/Math.max(d,.1)*.008;o+=e/d*t,s+=r/d*t}const c=i-t.x,h=a-t.y,f=Math.hypot(c,h),m=t.value/l*.02;t.x+=c/f*m,t.y+=h/f*m});const u=i-t.x,c=a-t.y,h=Math.hypot(u,c),f=r[0].radius+t.radius+35,m=(Math.pow(t.value/l,.3),.8*(1-t.value/l)*(1-Math.min(1,h/f)));t.x+=u*m,t.y+=c*m,t.x+=.35*o,t.y+=.35*s}),r.forEach((t,n)=>{r.forEach((e,o)=>{if(n>=o)return;if(0===n||0===o){const o=0===n?t:e,i=0===n?e:t,a=i.x-o.x,r=i.y-o.y,l=Math.hypot(a,r),s=o.radius+i.radius+2;if(l<s){const t=s-l,n=Math.atan2(r,a);i.x+=Math.cos(n)*t*.7,i.y+=Math.sin(n)*t*.7}return}const i=t.x-e.x,a=t.y-e.y,r=Math.hypot(i,a),l=t.radius+e.radius-5;if(r<l){const n=(l-r)*(.3+.04),o=Math.atan2(a,i),s=e.radius/(t.radius+e.radius);t.fixed||(t.x+=Math.cos(o)*n*s,t.y+=Math.sin(o)*n*s),e.fixed||(e.x-=Math.cos(o)*n*(1-s),e.y-=Math.sin(o)*n*(1-s))}})});return r.forEach(t=>{const o=Math.max(5+t.radius,Math.min(n-5-t.radius,t.x)),i=Math.max(5+t.radius,Math.min(e-5-t.radius,t.y));(!t.fixed||Math.hypot(t.x-o,t.y-i)>2)&&(t.x=o,t.y=i)}),r}(r,d,u);function h(){l&&s?(f(l,s),s.clearRect(0,0,l.width,l.height),c.forEach(t=>{const{x:n,y:e,radius:o,bubbleColor:i,borderColor:l,borderThickness:d,opacity:u,fontColor:c,fontFamily:h,fontSize:f,fontStyle:m,fontWeight:y,textAlign:v,textTransform:x,textBaseline:g}=function(t,n){var e,o,i,r,l,s,d,u,c,h,f,m;return{x:t.x,y:t.y,radius:Math.max(t.radius||0,n.minRadius||10),bubbleColor:null!==(o=null!==(e=t.bubbleColor)&&void 0!==e?e:n.defaultBubbleColor)&&void 0!==o?o:"#3498db",borderColor:null!==(i=t.borderColor)&&void 0!==i?i:"black",borderThickness:Math.max(null!==(r=t.borderThickness)&&void 0!==r?r:.25,0),opacity:void 0!==t.opacity?Math.max(0,Math.min(1,t.opacity)):1,fontStyle:t.fontStyle||"normal",fontWeight:"number"==typeof t.fontWeight&&t.fontWeight>=100&&t.fontWeight<=900?t.fontWeight:400,textAlign:null!==(l=t.textAlign)&&void 0!==l?l:"center",textTransform:null!==(s=t.textTransform)&&void 0!==s?s:"none",fontColor:null!==(u=null!==(d=t.fontColor)&&void 0!==d?d:n.defaultFontColor)&&void 0!==u?u:"#000",textBaseline:null!==(c=t.textBaseline)&&void 0!==c?c:"middle",fontSize:Math.max(a(t.radius||n.minRadius||10,null!==(h=n.fontSize)&&void 0!==h?h:14,null!==(f=t.fontWeight)&&void 0!==f?f:400),8),fontFamily:t.fontFamily&&"string"==typeof t.fontFamily&&"Arial"!==t.fontFamily?`${t.fontFamily}, Arial, sans-serif`:`${null!==(m=n.defaultFontFamily)&&void 0!==m?m:"Arial"}, sans-serif`}}(t,r);s.beginPath(),s.arc(n,e,o,0,2*Math.PI),s.fillStyle=i,s.fill(),s.strokeStyle=l,s.lineWidth=d,s.stroke();const p=`${m} ${y} ${f}px ${h}`;s.fillStyle=c,s.font=p,s.imageSmoothingEnabled=!0,s.imageSmoothingQuality="high",s.textAlign=v,s.textBaseline=g;let b=t.label||"";if("uppercase"===x?b=b.toUpperCase():"lowercase"===x?b=b.toLowerCase():"capitalize"===x&&(b=b.replace(/\b\w/g,t=>t.toUpperCase())),r.textWrap){const i=1.5*o-10,a=1.4*f,l=function(t,n,e,o,i,a=14,r=400,l="normal",s="Arial",d=0,u=5,c=1.2){const h=1.5*(i-u),f=a*c,m=Math.max(1,Math.floor(h/f)),y="auto"===o||void 0===o?m:Math.min(o,m);e=Math.max(0,e-2*d);const v=n.split(" ");let x="";const g=[];let p=!1,b=!1;t.font=`${r||""} ${l||""} ${a}px ${s}`,t.imageSmoothingEnabled=!0,t.imageSmoothingQuality="high";for(const n of v){const o=x?`${x} ${n}`:n;if(t.measureText(o).width<=e)x=o;else if(x.trim()&&g.push(x),x=n,t.measureText(x).width>e){let n=x;for(;t.measureText(n+"...").width>e&&n.length>0;)n=n.slice(0,-1);g.push(n+"..."),b=!0;break}if(g.length>=y){p=!0;break}}if(x&&g.length<y&&!b&&g.push(x),p&&g.length>0){let n=g[g.length-1];for(;t.measureText(n+"...").width>e&&n.length>0;)n=n.slice(0,-1);g[g.length-1]=n+"..."}return g}(s,t.label,i,r.maxLines,o,f,y,m,h),d=e-(l.length-1)*a/2;l.forEach((t,e)=>{const o=Math.round(n),i=Math.round(d+e*a);s.fillText(t,o,i)})}else s.fillText(t.label,Math.round(n),Math.round(e))})):console.warn("canvas or ctx is not valid")}function f(t,n){const e=window.devicePixelRatio||1,o=t.getBoundingClientRect();return t.width=o.width*e,t.height=o.height*e,t.style.width=`${o.width}px`,t.style.height=`${o.height}px`,n.setTransform(1,0,0,1,0,0),n.scale(e,e),{width:o.width,height:o.height,dpr:e}}function m(){const t=document.getElementById(r.canvasContainerId);t&&l&&(l.width=t.offsetWidth,l.height=t.offsetHeight,l.getContext("2d"),h())}let y;r.isResizeCanvasOnWindowSizeChange&&(m(),window.addEventListener("resize",m)),h(),r.showToolTip&&(y=function(t){var e,o,i,a,r,l,s,d,u,c,h,f,m,y,v,x,g,p;const b=null===(o=null===(e=t.data[0].toolTipConfig)||void 0===e?void 0:e.tooltipFormattedData)||void 0===o?void 0:o.trim();if(b){const e=document.createElement("div");e.innerHTML=b.trim();const o=e.firstElementChild;return o.style.display="none",o.style.visibility="hidden",o.style.opacity="0",o.style.position="absolute",n(o,t.canvasContainerId)}const M=document.createElement("div");M.id="bubbleChartTooltip",M.style.display="none";const C=null!==(i=null==t?void 0:t.tooltipOptions)&&void 0!==i?i:{},w=(t,n)=>"number"==typeof t?`${t}px`:null!=t?t:n;return Object.assign(M.style,{position:"absolute",padding:w(C.padding,"8px"),margin:w(C.margin,"0"),background:null!==(a=C.backgroundColor)&&void 0!==a?a:"rgba(0, 0, 0, 0.85)",color:null!==(r=C.fontColor)&&void 0!==r?r:"white",borderRadius:"4px",pointerEvents:null!==(l=C.pointerEvents)&&void 0!==l?l:"none",fontFamily:null!==(s=C.fontFamily)&&void 0!==s?s:"Arial, sans-serif",fontSize:w(C.fontSize,"14px"),fontWeight:String(null!==(d=C.fontWeight)&&void 0!==d?d:"400"),fontStyle:null!==(u=C.fontStyle)&&void 0!==u?u:"normal",textAlign:null!==(c=C.textAlign)&&void 0!==c?c:"left",textDecoration:null!==(h=C.textDecoration)&&void 0!==h?h:"none",textTransform:null!==(f=C.textTransform)&&void 0!==f?f:"none",letterSpacing:w(C.letterSpacing,"normal"),border:(()=>{var t;if(!C.borderStyle)return"none";const n=w(C.borderWidth,"1px"),e=null!==(t=C.borderColor)&&void 0!==t?t:"transparent";return`${n} ${C.borderStyle} ${e}`})(),boxShadow:null!==(m=C.boxShadow)&&void 0!==m?m:"none",maxWidth:w(C.maxWidth,"200px"),minWidth:w(C.minWidth,"auto"),maxHeight:w(C.maxHeight,"none"),minHeight:w(C.minHeight,"auto"),zIndex:String(null!==(y=C.zIndex)&&void 0!==y?y:1e3),transition:null!==(v=C.transition)&&void 0!==v?v:"opacity 0.2s",transform:null!==(x=C.transform)&&void 0!==x?x:"none",backdropFilter:null!==(g=C.backdropFilter)&&void 0!==g?g:"none",opacity:String(null!==(p=C.opacity)&&void 0!==p?p:1),display:"none",visibility:"hidden"}),n(M,t.canvasContainerId),M}(r));let v=null;if(l.addEventListener("mousemove",n=>{v||(v=requestAnimationFrame(()=>{(function(n,i,a,r,l){const{mouseX:s,mouseY:d}=e(n,a),u=o(s,d,i);t=(null==l?void 0:l.cursorType)||"pointer",a.style.cursor="default",r&&(u?function(n,e,o,i){if(e&&e.value&&o&&i){o.style.cursor=t,i.style.display="block",i.innerHTML=function(t){var n,e,o;if(!t)return"";const i=null===(e=null===(n=t.toolTipConfig)||void 0===n?void 0:n.tooltipText)||void 0===e?void 0:e.trim();if(i)return`<div>${i}</div>`;const a=null===(o=t.label)||void 0===o?void 0:o.trim();return a?`<div>${a}<br>Value: ${t.value}</div>`:`<div>${t.value}</div>`}(e);const a=o.getBoundingClientRect();i.style.left=n.clientX-a.left+15+"px",i.style.top=n.clientY-a.top+15+"px",i.style.zIndex="999999",i.style.visibility="visible",i.style.opacity="1",i.style.position="absolute"}}(n,u,a,r):(a.style.cursor="default",r.style.display="none",r.style.visibility="hidden",r.style.opacity="0"))})(n,c,l,y,r),v=null}))}),r.onBubbleClick){let t=null;l.addEventListener("click",n=>{t||(t=requestAnimationFrame(()=>{!function(t,n,i,a){const{mouseX:r,mouseY:l}=e(t,i),s=o(r,l,n);null!=s&&a.onBubbleClick&&a.onBubbleClick(s,t)}(n,c,l,r),t=null}))})}}const l={defaultBubbleColor:"#3498DB",defaultFontColor:"#ffffff",minRadius:10,maxLines:"auto",textWrap:!0,isResizeCanvasOnWindowSizeChange:!0,fontSize:14,defaultFontFamily:"Arial",showToolTip:!0};function s(t={}){var n,e;if(!t)return void console.error("Configuration is not valid. Chart initialization aborted.");if(!t.data||0===t.data.length)return void console.error("No valid data provided. Chart initialization aborted.");const o=(i=Object.assign({canvasContainerId:null!==(n=t.canvasContainerId)&&void 0!==n?n:"chart-container",data:null!==(e=t.data)&&void 0!==e?e:[]},t),Object.assign(Object.assign({},l),i));var i;return r(o),o}class d{constructor(t){const n=s(t);n&&(this.configuration=n)}render(){this.configuration&&r(this.configuration)}}window.initializeChart=s;export{d as BubbleChart,s as initializeChart};
|
|
1
|
+
const t={defaultBubbleColor:"#3498DB",defaultFontColor:"#ffffff",minRadius:10,maxLines:"auto",textWrap:!0,isResizeCanvasOnWindowSizeChange:!0,fontSize:14,defaultFontFamily:"Arial",showToolTip:!0},e=JSON.parse('{"FC":0.008,"rX":1000,"d6":0.65,"WH":0.02,"ND":0.12,"$l":0.8,"cg":0.3,"e0":35}');function n(t,e){t.forEach((n,i)=>{t.forEach((t,o)=>{if(i>=o)return;if(0===i||0===o){const e=0===i?n:t,o=0===i?t:n,a=o.x-e.x,r=o.y-e.y,l=Math.hypot(a,r),s=e.radius+o.radius+2;if(l<s){const t=s-l,e=Math.atan2(r,a);o.x+=Math.cos(e)*t*.7,o.y+=Math.sin(e)*t*.7}return}const a=n.x-t.x,r=n.y-t.y,l=Math.hypot(a,r),s=n.radius+t.radius-5;if(l<s){const i=(s-l)*(.3+5*e.forceStrength),o=Math.atan2(r,a),d=n.radius+t.radius,c=d>0?t.radius/d:.5;n.fixed||(n.x+=Math.cos(o)*i*c,n.y+=Math.sin(o)*i*c),t.fixed||(t.x-=Math.cos(o)*i*(1-c),t.y-=Math.sin(o)*i*(1-c))}})})}function i(t,e=14,n=400,i=6){const o=n>=700?1.25:n>=500?1.1:1,a=Math.min(t/i,t/1.2);let r=Math.min(e*o,a,.8*t);return r=Math.max(r,Math.max(8,t/6)),Math.round(r)}class o{constructor(t){this.canvas=t;const e=t.getContext("2d");if(!e)throw new Error("Failed to get 2D rendering context from canvas");this.ctx=e}getContext(){return this.ctx}getCanvas(){return this.canvas}setup(){const t=window.devicePixelRatio||1,e=this.canvas.getBoundingClientRect();return this.canvas.width=e.width*t,this.canvas.height=e.height*t,this.canvas.style.width=`${e.width}px`,this.canvas.style.height=`${e.height}px`,this.ctx.setTransform(1,0,0,1,0,0),this.ctx.scale(t,t),{width:e.width,height:e.height}}getSize(){const t=this.canvas.getBoundingClientRect();return{width:t.width,height:t.height}}clear(){this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height)}drawCircle(t,e,n,i,o,a,r){this.ctx.beginPath(),this.ctx.arc(t,e,n,0,2*Math.PI),this.ctx.fillStyle=i,this.ctx.fill(),a>0&&(this.ctx.strokeStyle=o,this.ctx.lineWidth=a,this.ctx.stroke())}drawText(t,e,n,i){const o=`${i.fontStyle} ${i.fontWeight} ${i.fontSize}px ${i.fontFamily}`;this.ctx.fillStyle=i.fontColor,this.ctx.font=o,this.ctx.imageSmoothingEnabled=!0,this.ctx.imageSmoothingQuality="high",this.ctx.textAlign=i.textAlign,this.ctx.textBaseline=i.textBaseline,this.ctx.fillText(t,Math.round(e),Math.round(n))}destroy(){const t=this.canvas.parentElement;t&&t.removeChild(this.canvas)}}class a{constructor(t){this.ctx=t}measureWidth(t,e,n,i,o){return this.ctx.font=`${i} ${n} ${e}px ${o}`,this.ctx.imageSmoothingEnabled=!0,this.ctx.imageSmoothingQuality="high",this.ctx.measureText(t).width}}function r(t,e){const n=`bubbleChartTooltip-${e}`;return document.body.querySelector(`#${n}`)||(t.id=n,document.body.appendChild(t),t)}function l(t,e){const n=e.getBoundingClientRect(),i=window.devicePixelRatio||1;return{mouseX:(t.clientX-n.left)*i,mouseY:(t.clientY-n.top)*i}}function s(t,e,n){return n.find(n=>Math.hypot(t-n.x,e-n.y)<n.radius)||null}function d(t){let e=null;return{handle:n=>{e||(e=requestAnimationFrame(()=>{t(n),e=null}))},cancel:()=>{e&&(cancelAnimationFrame(e),e=null)}}}class c{}function u(t){if(!function(t){return t?!(!Array.isArray(t.data)||0===t.data.length)||(console.error("Invalid or empty data array"),!1):(console.error("Invalid config object"),!1)}(t))return;const h=function(t){var e,n;const i=document.getElementById(t.canvasContainerId);if(!i)return console.error(`Canvas container with ID '${t.canvasContainerId}' not found.`),null;if(i.querySelector("canvas"))return console.error("A canvas already exists inside the container."),null;const o=document.createElement("canvas");return Object.assign(o.style,{border:(null===(e=t.canvasBorderColor)||void 0===e?void 0:e.trim())?`1px solid #${t.canvasBorderColor}`:c.TRANSPARENT,background:(null===(n=t.canvasBackgroundColor)||void 0===n?void 0:n.trim())?`#${t.canvasBackgroundColor}`:c.TRANSPARENT,width:"100%",height:"100%",display:"block",imageRendering:"crisp-edges",aspectRatio:"1 / 1"}),o.style.setProperty("image-rendering","-moz-crisp-edges"),o.style.setProperty("image-rendering","-webkit-optimize-contrast"),o.style.setProperty("-ms-interpolation-mode","nearest-neighbor"),i.appendChild(o),o}(t);if(!h)return;const f=new o(h),m=new a(f.getContext()),{width:v,height:x}=f.setup();let y=function(t,i,o,a){const r=Object.assign({forceStrength:e.FC,iterations:e.rX,damping:e.d6,boundaryForce:e.WH,centerForce:e.ND,centerAttraction:e.$l,centerDamping:e.cg,centerRadiusBuffer:e.e0},a),l=Math.min((i-10)/2,(o-10)/2),s=i/2,d=o/2,c=[...t].sort((t,e)=>e.value-t.value).map(t=>Object.assign(Object.assign({},t),{radius:0,x:0,y:0,fixed:!1}));if(0===c.length)return c;const u=c[0].value,h=Math.min(.5*l,.2*Math.min(i,o)),f=Math.max(.3*h,.05*Math.min(i,o));return c.forEach(t=>{const e=u>0?t.value/u:1;t.radius=f+e*(h-f),t.radius=Math.max(0,Math.min(t.radius,(i-10)/2,(o-10)/2))}),c.forEach((t,e)=>{if(0===e)t.x=s,t.y=d,t.fixed=!0;else{const n=c[0].radius+t.radius+3,a=Math.PI*(3-Math.sqrt(5)),r=i-5-t.radius,l=o-5-t.radius;t.x=Math.min(r,Math.max(5+t.radius,s+Math.cos(a*e)*n)),t.y=Math.min(l,Math.max(5+t.radius,d+Math.sin(a*e)*n)),t.fixed=!1}}),function(t,e,i,o,a,r,l){for(let o=0;o<e.iterations;o++)t.forEach((n,o)=>{if(0===o){const t=a-n.x,i=r-n.y;return void(Math.hypot(t,i)>2&&(n.x+=t*e.centerDamping,n.y+=i*e.centerDamping))}let s=0,d=0;const c=n.radius+5;n.x<c?s+=(c-n.x)*e.boundaryForce:n.x>i-c&&(s+=(i-c-n.x)*e.boundaryForce),t.forEach(t=>{if(n===t)return;const i=n.x-t.x,o=n.y-t.y,c=Math.hypot(i,o),u=n.radius+t.radius;if(c<1.5*u){const t=e.forceStrength*(u/Math.max(c,.1));s+=i/c*t,d+=o/c*t}const h=a-n.x,f=r-n.y,m=Math.hypot(h,f),v=n.value/l*.02;n.x+=h/m*v,n.y+=f/m*v});const u=a-n.x,h=r-n.y,f=Math.hypot(u,h),m=t[0].radius+n.radius+e.centerRadiusBuffer,v=e.centerAttraction*(1-n.value/l)*(1-Math.min(1,f/m));n.x+=u*v,n.y+=h*v,n.x+=s*(1-e.damping),n.y+=d*(1-e.damping)}),n(t,e)}(c,r,i,0,s,d,u),function(t,e,n){t.forEach(t=>{const i=Math.max(5+t.radius,Math.min(e-5-t.radius,t.x)),o=Math.max(5+t.radius,Math.min(n-5-t.radius,t.y));(!t.fixed||Math.hypot(t.x-i,t.y-o)>2)&&(t.x=i,t.y=o)})}(c,i,o),c}(t.data,v,x);function g(){f.setup(),f.clear(),y.forEach(e=>{const n=function(t,e,n){var o,a,r,l,s,d,c,u,h,f,m;let v=null!==(o=n.defaultBubbleColor)&&void 0!==o?o:"#3498db";if(t.bubbleColor)v=t.bubbleColor;else if(n.colorPalette&&n.colorPalette.length>0){const i=e.findIndex(e=>e.label===t.label&&e.value===t.value),o=i>=0?i:0;v=n.colorPalette[o%n.colorPalette.length]}const x=Math.max(t.radius||0,n.minRadius||10);return{bubbleColor:v,borderColor:null!==(a=t.borderColor)&&void 0!==a?a:"black",borderThickness:Math.max(null!==(r=t.borderThickness)&&void 0!==r?r:.25,0),opacity:void 0!==t.opacity?Math.max(0,Math.min(1,t.opacity)):1,fontStyle:t.fontStyle||"normal",fontWeight:"number"==typeof t.fontWeight&&t.fontWeight>=100&&t.fontWeight<=900?t.fontWeight:400,textAlign:null!==(l=t.textAlign)&&void 0!==l?l:"center",textTransform:null!==(s=t.textTransform)&&void 0!==s?s:"none",fontColor:null!==(c=null!==(d=t.fontColor)&&void 0!==d?d:n.defaultFontColor)&&void 0!==c?c:"#000",textBaseline:null!==(u=t.textBaseline)&&void 0!==u?u:"middle",fontSize:Math.max(i(x,null!==(h=n.fontSize)&&void 0!==h?h:14,null!==(f=t.fontWeight)&&void 0!==f?f:400),8),fontFamily:t.fontFamily&&"string"==typeof t.fontFamily&&"Arial"!==t.fontFamily?`${t.fontFamily}, Arial, sans-serif`:`${null!==(m=n.defaultFontFamily)&&void 0!==m?m:"Arial"}, sans-serif`}}(e,y,t);f.drawCircle(e.x,e.y,Math.max(e.radius||0,t.minRadius||10),n.bubbleColor,n.borderColor,n.borderThickness,n.opacity);let o=e.label||"";"uppercase"===n.textTransform?o=o.toUpperCase():"lowercase"===n.textTransform?o=o.toLowerCase():"capitalize"===n.textTransform&&(o=o.replace(/\b\w/g,t=>t.toUpperCase()));const a=Math.max(e.radius||0,t.minRadius||10),r={fontSize:n.fontSize,fontFamily:n.fontFamily,fontWeight:n.fontWeight,fontStyle:n.fontStyle,fontColor:n.fontColor,textAlign:n.textAlign,textBaseline:n.textBaseline};if(t.textWrap){const i=1.5*a-10,o=1.4*n.fontSize,l=function(t,e,n,i,o,a=14,r=400,l="normal",s="Arial",d=0,c=5,u=1.2){const h=1.5*(o-c),f=a*u,m=Math.max(1,Math.floor(h/f)),v="auto"===i||void 0===i?m:Math.min(i,m);n=Math.max(0,n-2*d);const x=e.split(" ");let y="";const g=[];let p=!1,b=!1;const C=e=>t.measureWidth(e,a,r,l,s);for(const t of x){const e=y?`${y} ${t}`:t;if(C(e)<=n)y=e;else if(y.trim()&&g.push(y),y=t,C(y)>n){let t=y;for(;C(t+"...")>n&&t.length>0;)t=t.slice(0,-1);g.push(t+"..."),b=!0;break}if(g.length>=v){p=!0;break}}if(y&&g.length<v&&!b&&g.push(y),p&&g.length>0){let t=g[g.length-1];for(;C(t+"...")>n&&t.length>0;)t=t.slice(0,-1);g[g.length-1]=t+"..."}return g}(m,e.label,i,t.maxLines,a,n.fontSize,n.fontWeight,n.fontStyle,n.fontFamily),s=e.y-(l.length-1)*o/2;l.forEach((t,n)=>{f.drawText(t,e.x,s+n*o,r)})}else f.drawText(o,e.x,e.y,r)})}let p=null;if(t.isResizeCanvasOnWindowSizeChange){const e=document.getElementById(t.canvasContainerId);e&&(p=function(t,e){let n=null,i=null;const o=()=>{i||(i=requestAnimationFrame(()=>{e(),i=null}))};return"undefined"!=typeof ResizeObserver?(n=new ResizeObserver(o),n.observe(t)):(o(),window.addEventListener("resize",o)),{destroy:()=>{n&&(n.disconnect(),n=null),window.removeEventListener("resize",o),i&&(cancelAnimationFrame(i),i=null)}}}(e,()=>{const t=f.getCanvas();e&&t&&(t.width=e.offsetWidth,t.height=e.offsetHeight,g())}))}g();let b=null;t.showToolTip&&(b=function(t){var e,n,i,o,a,l,s,d,c,u,h,f,m,v,x,y,g,p,b;const C=null===(i=null===(n=null===(e=t.data[0])||void 0===e?void 0:e.toolTipConfig)||void 0===n?void 0:n.tooltipFormattedData)||void 0===i?void 0:i.trim();if(C){const e=document.createElement("div");e.innerHTML=C.trim();const n=e.firstElementChild;return n.style.display="none",n.style.visibility="hidden",n.style.opacity="0",n.style.position="absolute",r(n,t.canvasContainerId)}const M=document.createElement("div");M.style.display="none";const w=null!==(o=null==t?void 0:t.tooltipOptions)&&void 0!==o?o:{},S=(t,e)=>"number"==typeof t?`${t}px`:null!=t?t:e;return Object.assign(M.style,{position:"absolute",padding:S(w.padding,"8px"),margin:S(w.margin,"0"),background:null!==(a=w.backgroundColor)&&void 0!==a?a:"rgba(0, 0, 0, 0.85)",color:null!==(l=w.fontColor)&&void 0!==l?l:"white",borderRadius:"4px",pointerEvents:null!==(s=w.pointerEvents)&&void 0!==s?s:"none",fontFamily:null!==(d=w.fontFamily)&&void 0!==d?d:"Arial, sans-serif",fontSize:S(w.fontSize,"14px"),fontWeight:String(null!==(c=w.fontWeight)&&void 0!==c?c:"400"),fontStyle:null!==(u=w.fontStyle)&&void 0!==u?u:"normal",textAlign:null!==(h=w.textAlign)&&void 0!==h?h:"left",textDecoration:null!==(f=w.textDecoration)&&void 0!==f?f:"none",textTransform:null!==(m=w.textTransform)&&void 0!==m?m:"none",letterSpacing:S(w.letterSpacing,"normal"),border:(()=>{var t;if(!w.borderStyle)return"none";const e=S(w.borderWidth,"1px"),n=null!==(t=w.borderColor)&&void 0!==t?t:"transparent";return`${e} ${w.borderStyle} ${n}`})(),boxShadow:null!==(v=w.boxShadow)&&void 0!==v?v:"none",maxWidth:S(w.maxWidth,"200px"),minWidth:S(w.minWidth,"auto"),maxHeight:S(w.maxHeight,"none"),minHeight:S(w.minHeight,"auto"),zIndex:String(null!==(x=w.zIndex)&&void 0!==x?x:1e3),transition:null!==(y=w.transition)&&void 0!==y?y:"opacity 0.2s",transform:null!==(g=w.transform)&&void 0!==g?g:"none",backdropFilter:null!==(p=w.backdropFilter)&&void 0!==p?p:"none",opacity:String(null!==(b=w.opacity)&&void 0!==b?b:1),display:"none",visibility:"hidden"}),r(M,t.canvasContainerId),M}(t));const C=f.getCanvas(),M=d(e=>{const{mouseX:n,mouseY:i}=l(e,C),o=s(n,i,y);if(o){const n=(null==t?void 0:t.cursorType)||"pointer";if(C.style.cursor=n,b){const n=function(t,e){var n,i,o;if(!t)return"";if(e.tooltipOptions&&"function"==typeof e.tooltipOptions.formatter)return e.tooltipOptions.formatter(t);const a=null===(i=null===(n=t.toolTipConfig)||void 0===n?void 0:n.tooltipText)||void 0===i?void 0:i.trim();if(a)return`<div>${a}</div>`;const r=null===(o=t.label)||void 0===o?void 0:o.trim();return r?`<div>${r}<br>Value: ${t.value}</div>`:`<div>${t.value}</div>`}(o,t);!function(t,e,n,i){e&&n&&(e.style.display="block",e.innerHTML=i,e.style.left=`${t.pageX+15}px`,e.style.top=`${t.pageY+15}px`,e.style.zIndex="999999",e.style.visibility="visible",e.style.opacity="1",e.style.position="absolute")}(e,b,C,n)}}else C.style.cursor="default",function(t){t&&(t.style.display="none",t.style.visibility="hidden",t.style.opacity="0")}(b)});C.addEventListener("mousemove",M.handle);const w=d(e=>{const{mouseX:n,mouseY:i}=l(e,C),o=s(n,i,y);o&&t.onBubbleClick&&t.onBubbleClick(o,e)});t.onBubbleClick&&C.addEventListener("click",w.handle);const S=()=>{null==p||p.destroy(),M.cancel(),w.cancel(),C.removeEventListener("mousemove",M.handle),C.removeEventListener("click",w.handle),f.destroy(),(null==b?void 0:b.parentElement)&&b.parentElement.removeChild(b),b=null};return{destroy:S,update:e=>(S(),t.data=e,u(t))}}c.TRANSPARENT="transparent";class h{constructor(e){const n=function(e={}){var n,i;if(!e)return void console.error("Configuration is not valid. Chart initialization aborted.");if(!e.data||0===e.data.length)return void console.error("No valid data provided. Chart initialization aborted.");const o=(a=Object.assign({canvasContainerId:null!==(n=e.canvasContainerId)&&void 0!==n?n:"chart-container",data:null!==(i=e.data)&&void 0!==i?i:[]},e),Object.assign(Object.assign({},t),a));var a;const r=u(o);return r?{config:o,instance:r}:void 0}(e);n&&(this.configuration=n.config,this.instance=n.instance)}destroy(){this.instance&&this.instance.destroy()}update(t){this.instance&&(this.instance=this.instance.update(t))}}function f(t){return new h(t)}"undefined"!=typeof window&&(window.initializeChart=f,window.BubbleChart=h);export{h as BubbleChart,f as initializeChart};
|
package/dist/bubbleChart.umd.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define("BubbleChart",[],e):"object"==typeof exports?exports.BubbleChart=e():t.BubbleChart=e()}(this,()=>(()=>{"use strict";var t={d:(e,n)=>{for(var o in n)t.o(n,o)&&!t.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:n[o]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};t.r(e),t.d(e,{BubbleChart:()=>h,initializeChart:()=>c});let n="default";function o(t,e){if(!e)return console.error("Invalid containerId."),null;const n=document.getElementById(e);if(!n)return console.error("Container not found."),null;const o=n.parentElement;return o?o.querySelector("#bubbleChartTooltip")||(o.prepend(t),t):(console.error("Parent container not found."),null)}function i(t,e){const n=e.getBoundingClientRect();return{mouseX:t.clientX-n.left,mouseY:t.clientY-n.top}}function r(t,e,n){return n.find(n=>Math.hypot(t-n.x,e-n.y)<n.radius)||null}class a{}a.TRANSPARENT="transparent";const l={forceStrength:.008,iterations:1e3,damping:.65,boundaryForce:.02,centerForce:.12,centerAttraction:.8,centerDamping:.3,centerRadiusBuffer:35};function s(t,e=14,n=400,o=6){const i=n>=700?1.25:n>=500?1.1:1,r=Math.min(t/o,t/1.2);let a=Math.min(e*i,r,.8*t);return a=Math.max(a,Math.max(8,t/6)),Math.round(a)}function d(t){if(!function(t){return t?!(!Array.isArray(t.data)||0===t.data.length)||(console.error("Invalid or empty data array"),!1):(console.error("Invalid config object"),!1)}(t))return;let e=function(t){var e,n;const o=document.getElementById(t.canvasContainerId);if(!o)return console.error(`Canvas container with ID '${t.canvasContainerId}' not found.`),null;if(o.querySelector("canvas"))return console.error("A canvas already exists inside the container."),null;const i=document.createElement("canvas");return Object.assign(i.style,{border:(null===(e=t.canvasBorderColor)||void 0===e?void 0:e.trim())?`1px solid #${t.canvasBorderColor}`:a.TRANSPARENT,background:(null===(n=t.canvasBackgroundColor)||void 0===n?void 0:n.trim())?`#${t.canvasBackgroundColor}`:a.TRANSPARENT,width:"100%",height:"100%",display:"block",imageRendering:"crisp-edges",aspectRatio:"1 / 1"}),i.style.setProperty("image-rendering","-moz-crisp-edges"),i.style.setProperty("image-rendering","-webkit-optimize-contrast"),i.style.setProperty("-ms-interpolation-mode","nearest-neighbor"),o.appendChild(i),i}(t);if(!e)return;const d=e.getContext("2d");if(!d)return void console.error("Invalid context");const{width:u,height:c}=m(e,d),h=function(t,e,n){const o=Math.min((e-10)/2,(n-10)/2),i=e/2,r=n/2,a=[...t.data].sort((t,e)=>e.value-t.value).map(t=>Object.assign(Object.assign({},t),{radius:0,x:0,y:0,fixed:!1})),s=a[0].value,d=Math.min(.5*o,.2*Math.min(e,n)),u=Math.max(.3*d,.05*Math.min(e,n));a.forEach(t=>{const o=t.value/s;t.radius=u+o*(d-u),t.radius=Math.min(t.radius,(e-10)/2,(n-10)/2)}),a.forEach((t,o)=>{if(0===o)t.x=i,t.y=r,t.fixed=!0;else{const l=a[0].radius+t.radius+3,s=Math.PI*(3-Math.sqrt(5)),d=e-5-t.radius,u=n-5-t.radius;t.x=Math.min(d,Math.max(5+t.radius,i+Math.cos(s*o)*l)),t.y=Math.min(u,Math.max(5+t.radius,r+Math.sin(s*o)*l)),t.fixed=!1}});for(let t=0;t<l.iterations;t++)a.forEach((t,n)=>{if(0===n){const e=i-t.x,n=r-t.y;return void(Math.hypot(e,n)>2&&(t.x+=e*l.centerDamping,t.y+=n*l.centerDamping))}let o=0,d=0;const u=t.radius+5;t.x<u?o+=(u-t.x)*l.boundaryForce:t.x>e-u&&(o+=(e-u-t.x)*l.boundaryForce),a.forEach(e=>{if(t===e)return;const n=t.x-e.x,a=t.y-e.y,u=Math.hypot(n,a),c=t.radius+e.radius;if(u<1.5*c){const t=l.forceStrength*(c/Math.max(u,.1));o+=n/u*t,d+=a/u*t}const h=i-t.x,f=r-t.y,m=Math.hypot(h,f),y=t.value/s*.02;t.x+=h/m*y,t.y+=f/m*y});const c=i-t.x,h=r-t.y,f=Math.hypot(c,h),m=a[0].radius+t.radius+l.centerRadiusBuffer,y=(l.centerForce,Math.pow(t.value/s,.3),l.centerAttraction*(1-t.value/s)*(1-Math.min(1,f/m)));t.x+=c*y,t.y+=h*y,t.x+=o*(1-l.damping),t.y+=d*(1-l.damping)}),a.forEach((t,e)=>{a.forEach((n,o)=>{if(e>=o)return;if(0===e||0===o){const o=0===e?t:n,i=0===e?n:t,r=i.x-o.x,a=i.y-o.y,l=Math.hypot(r,a),s=o.radius+i.radius+2;if(l<s){const t=s-l,e=Math.atan2(a,r);i.x+=Math.cos(e)*t*.7,i.y+=Math.sin(e)*t*.7}return}const i=t.x-n.x,r=t.y-n.y,a=Math.hypot(i,r),s=t.radius+n.radius-5;if(a<s){const e=(s-a)*(.3+5*l.forceStrength),o=Math.atan2(r,i),d=n.radius/(t.radius+n.radius);t.fixed||(t.x+=Math.cos(o)*e*d,t.y+=Math.sin(o)*e*d),n.fixed||(n.x-=Math.cos(o)*e*(1-d),n.y-=Math.sin(o)*e*(1-d))}})});return a.forEach(t=>{const o=Math.max(5+t.radius,Math.min(e-5-t.radius,t.x)),i=Math.max(5+t.radius,Math.min(n-5-t.radius,t.y));(!t.fixed||Math.hypot(t.x-o,t.y-i)>2)&&(t.x=o,t.y=i)}),a}(t,u,c);function f(){e&&d?(m(e,d),d.clearRect(0,0,e.width,e.height),h.forEach(e=>{const{x:n,y:o,radius:i,bubbleColor:r,borderColor:a,borderThickness:l,opacity:u,fontColor:c,fontFamily:h,fontSize:f,fontStyle:m,fontWeight:y,textAlign:p,textTransform:v,textBaseline:g}=function(t,e){var n,o,i,r,a,l,d,u,c,h,f,m;return{x:t.x,y:t.y,radius:Math.max(t.radius||0,e.minRadius||10),bubbleColor:null!==(o=null!==(n=t.bubbleColor)&&void 0!==n?n:e.defaultBubbleColor)&&void 0!==o?o:"#3498db",borderColor:null!==(i=t.borderColor)&&void 0!==i?i:"black",borderThickness:Math.max(null!==(r=t.borderThickness)&&void 0!==r?r:.25,0),opacity:void 0!==t.opacity?Math.max(0,Math.min(1,t.opacity)):1,fontStyle:t.fontStyle||"normal",fontWeight:"number"==typeof t.fontWeight&&t.fontWeight>=100&&t.fontWeight<=900?t.fontWeight:400,textAlign:null!==(a=t.textAlign)&&void 0!==a?a:"center",textTransform:null!==(l=t.textTransform)&&void 0!==l?l:"none",fontColor:null!==(u=null!==(d=t.fontColor)&&void 0!==d?d:e.defaultFontColor)&&void 0!==u?u:"#000",textBaseline:null!==(c=t.textBaseline)&&void 0!==c?c:"middle",fontSize:Math.max(s(t.radius||e.minRadius||10,null!==(h=e.fontSize)&&void 0!==h?h:14,null!==(f=t.fontWeight)&&void 0!==f?f:400),8),fontFamily:t.fontFamily&&"string"==typeof t.fontFamily&&"Arial"!==t.fontFamily?`${t.fontFamily}, Arial, sans-serif`:`${null!==(m=e.defaultFontFamily)&&void 0!==m?m:"Arial"}, sans-serif`}}(e,t);d.beginPath(),d.arc(n,o,i,0,2*Math.PI),d.fillStyle=r,d.fill(),d.strokeStyle=a,d.lineWidth=l,d.stroke();const x=`${m} ${y} ${f}px ${h}`;d.fillStyle=c,d.font=x,d.imageSmoothingEnabled=!0,d.imageSmoothingQuality="high",d.textAlign=p,d.textBaseline=g;let b=e.label||"";if("uppercase"===v?b=b.toUpperCase():"lowercase"===v?b=b.toLowerCase():"capitalize"===v&&(b=b.replace(/\b\w/g,t=>t.toUpperCase())),t.textWrap){const r=1.5*i-10,a=1.4*f,l=function(t,e,n,o,i,r=14,a=400,l="normal",s="Arial",d=0,u=5,c=1.2){const h=1.5*(i-u),f=r*c,m=Math.max(1,Math.floor(h/f)),y="auto"===o||void 0===o?m:Math.min(o,m);n=Math.max(0,n-2*d);const p=e.split(" ");let v="";const g=[];let x=!1,b=!1;t.font=`${a||""} ${l||""} ${r}px ${s}`,t.imageSmoothingEnabled=!0,t.imageSmoothingQuality="high";for(const e of p){const o=v?`${v} ${e}`:e;if(t.measureText(o).width<=n)v=o;else if(v.trim()&&g.push(v),v=e,t.measureText(v).width>n){let e=v;for(;t.measureText(e+"...").width>n&&e.length>0;)e=e.slice(0,-1);g.push(e+"..."),b=!0;break}if(g.length>=y){x=!0;break}}if(v&&g.length<y&&!b&&g.push(v),x&&g.length>0){let e=g[g.length-1];for(;t.measureText(e+"...").width>n&&e.length>0;)e=e.slice(0,-1);g[g.length-1]=e+"..."}return g}(d,e.label,r,t.maxLines,i,f,y,m,h),s=o-(l.length-1)*a/2;l.forEach((t,e)=>{const o=Math.round(n),i=Math.round(s+e*a);d.fillText(t,o,i)})}else d.fillText(e.label,Math.round(n),Math.round(o))})):console.warn("canvas or ctx is not valid")}function m(t,e){const n=window.devicePixelRatio||1,o=t.getBoundingClientRect();return t.width=o.width*n,t.height=o.height*n,t.style.width=`${o.width}px`,t.style.height=`${o.height}px`,e.setTransform(1,0,0,1,0,0),e.scale(n,n),{width:o.width,height:o.height,dpr:n}}function y(){const n=document.getElementById(t.canvasContainerId);n&&e&&(e.width=n.offsetWidth,e.height=n.offsetHeight,e.getContext("2d"),f())}let p;t.isResizeCanvasOnWindowSizeChange&&(y(),window.addEventListener("resize",y)),f(),t.showToolTip&&(p=function(t){var e,n,i,r,a,l,s,d,u,c,h,f,m,y,p,v,g,x;const b=null===(n=null===(e=t.data[0].toolTipConfig)||void 0===e?void 0:e.tooltipFormattedData)||void 0===n?void 0:n.trim();if(b){const e=document.createElement("div");e.innerHTML=b.trim();const n=e.firstElementChild;return n.style.display="none",n.style.visibility="hidden",n.style.opacity="0",n.style.position="absolute",o(n,t.canvasContainerId)}const M=document.createElement("div");M.id="bubbleChartTooltip",M.style.display="none";const C=null!==(i=null==t?void 0:t.tooltipOptions)&&void 0!==i?i:{},S=(t,e)=>"number"==typeof t?`${t}px`:null!=t?t:e;return Object.assign(M.style,{position:"absolute",padding:S(C.padding,"8px"),margin:S(C.margin,"0"),background:null!==(r=C.backgroundColor)&&void 0!==r?r:"rgba(0, 0, 0, 0.85)",color:null!==(a=C.fontColor)&&void 0!==a?a:"white",borderRadius:"4px",pointerEvents:null!==(l=C.pointerEvents)&&void 0!==l?l:"none",fontFamily:null!==(s=C.fontFamily)&&void 0!==s?s:"Arial, sans-serif",fontSize:S(C.fontSize,"14px"),fontWeight:String(null!==(d=C.fontWeight)&&void 0!==d?d:"400"),fontStyle:null!==(u=C.fontStyle)&&void 0!==u?u:"normal",textAlign:null!==(c=C.textAlign)&&void 0!==c?c:"left",textDecoration:null!==(h=C.textDecoration)&&void 0!==h?h:"none",textTransform:null!==(f=C.textTransform)&&void 0!==f?f:"none",letterSpacing:S(C.letterSpacing,"normal"),border:(()=>{var t;if(!C.borderStyle)return"none";const e=S(C.borderWidth,"1px"),n=null!==(t=C.borderColor)&&void 0!==t?t:"transparent";return`${e} ${C.borderStyle} ${n}`})(),boxShadow:null!==(m=C.boxShadow)&&void 0!==m?m:"none",maxWidth:S(C.maxWidth,"200px"),minWidth:S(C.minWidth,"auto"),maxHeight:S(C.maxHeight,"none"),minHeight:S(C.minHeight,"auto"),zIndex:String(null!==(y=C.zIndex)&&void 0!==y?y:1e3),transition:null!==(p=C.transition)&&void 0!==p?p:"opacity 0.2s",transform:null!==(v=C.transform)&&void 0!==v?v:"none",backdropFilter:null!==(g=C.backdropFilter)&&void 0!==g?g:"none",opacity:String(null!==(x=C.opacity)&&void 0!==x?x:1),display:"none",visibility:"hidden"}),o(M,t.canvasContainerId),M}(t));let v=null;if(e.addEventListener("mousemove",o=>{v||(v=requestAnimationFrame(()=>{(function(t,e,o,a,l){const{mouseX:s,mouseY:d}=i(t,o),u=r(s,d,e);n=(null==l?void 0:l.cursorType)||"pointer",o.style.cursor="default",a&&(u?function(t,e,o,i){if(e&&e.value&&o&&i){o.style.cursor=n,i.style.display="block",i.innerHTML=function(t){var e,n,o;if(!t)return"";const i=null===(n=null===(e=t.toolTipConfig)||void 0===e?void 0:e.tooltipText)||void 0===n?void 0:n.trim();if(i)return`<div>${i}</div>`;const r=null===(o=t.label)||void 0===o?void 0:o.trim();return r?`<div>${r}<br>Value: ${t.value}</div>`:`<div>${t.value}</div>`}(e);const r=o.getBoundingClientRect();i.style.left=t.clientX-r.left+15+"px",i.style.top=t.clientY-r.top+15+"px",i.style.zIndex="999999",i.style.visibility="visible",i.style.opacity="1",i.style.position="absolute"}}(t,u,o,a):(o.style.cursor="default",a.style.display="none",a.style.visibility="hidden",a.style.opacity="0"))})(o,h,e,p,t),v=null}))}),t.onBubbleClick){let n=null;e.addEventListener("click",o=>{n||(n=requestAnimationFrame(()=>{!function(t,e,n,o){const{mouseX:a,mouseY:l}=i(t,n),s=r(a,l,e);null!=s&&o.onBubbleClick&&o.onBubbleClick(s,t)}(o,h,e,t),n=null}))})}}const u={defaultBubbleColor:"#3498DB",defaultFontColor:"#ffffff",minRadius:10,maxLines:"auto",textWrap:!0,isResizeCanvasOnWindowSizeChange:!0,fontSize:14,defaultFontFamily:"Arial",showToolTip:!0};function c(t={}){var e,n;if(!t)return void console.error("Configuration is not valid. Chart initialization aborted.");if(!t.data||0===t.data.length)return void console.error("No valid data provided. Chart initialization aborted.");const o=(i=Object.assign({canvasContainerId:null!==(e=t.canvasContainerId)&&void 0!==e?e:"chart-container",data:null!==(n=t.data)&&void 0!==n?n:[]},t),Object.assign(Object.assign({},u),i));var i;return d(o),o}class h{constructor(t){const e=c(t);e&&(this.configuration=e)}render(){this.configuration&&d(this.configuration)}}return window.initializeChart=c,e})());
|
|
1
|
+
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define("BubbleChart",[],e):"object"==typeof exports?exports.BubbleChart=e():t.BubbleChart=e()}(this,()=>(()=>{"use strict";var t={d:(e,n)=>{for(var i in n)t.o(n,i)&&!t.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:n[i]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};t.r(e),t.d(e,{BubbleChart:()=>m,initializeChart:()=>y});const n={defaultBubbleColor:"#3498DB",defaultFontColor:"#ffffff",minRadius:10,maxLines:"auto",textWrap:!0,isResizeCanvasOnWindowSizeChange:!0,fontSize:14,defaultFontFamily:"Arial",showToolTip:!0},i=JSON.parse('{"FC":0.008,"rX":1000,"d6":0.65,"WH":0.02,"ND":0.12,"$l":0.8,"cg":0.3,"e0":35}');function o(t,e){t.forEach((n,i)=>{t.forEach((t,o)=>{if(i>=o)return;if(0===i||0===o){const e=0===i?n:t,o=0===i?t:n,a=o.x-e.x,r=o.y-e.y,l=Math.hypot(a,r),s=e.radius+o.radius+2;if(l<s){const t=s-l,e=Math.atan2(r,a);o.x+=Math.cos(e)*t*.7,o.y+=Math.sin(e)*t*.7}return}const a=n.x-t.x,r=n.y-t.y,l=Math.hypot(a,r),s=n.radius+t.radius-5;if(l<s){const i=(s-l)*(.3+5*e.forceStrength),o=Math.atan2(r,a),d=n.radius+t.radius,c=d>0?t.radius/d:.5;n.fixed||(n.x+=Math.cos(o)*i*c,n.y+=Math.sin(o)*i*c),t.fixed||(t.x-=Math.cos(o)*i*(1-c),t.y-=Math.sin(o)*i*(1-c))}})})}function a(t,e=14,n=400,i=6){const o=n>=700?1.25:n>=500?1.1:1,a=Math.min(t/i,t/1.2);let r=Math.min(e*o,a,.8*t);return r=Math.max(r,Math.max(8,t/6)),Math.round(r)}class r{constructor(t){this.canvas=t;const e=t.getContext("2d");if(!e)throw new Error("Failed to get 2D rendering context from canvas");this.ctx=e}getContext(){return this.ctx}getCanvas(){return this.canvas}setup(){const t=window.devicePixelRatio||1,e=this.canvas.getBoundingClientRect();return this.canvas.width=e.width*t,this.canvas.height=e.height*t,this.canvas.style.width=`${e.width}px`,this.canvas.style.height=`${e.height}px`,this.ctx.setTransform(1,0,0,1,0,0),this.ctx.scale(t,t),{width:e.width,height:e.height}}getSize(){const t=this.canvas.getBoundingClientRect();return{width:t.width,height:t.height}}clear(){this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height)}drawCircle(t,e,n,i,o,a,r){this.ctx.beginPath(),this.ctx.arc(t,e,n,0,2*Math.PI),this.ctx.fillStyle=i,this.ctx.fill(),a>0&&(this.ctx.strokeStyle=o,this.ctx.lineWidth=a,this.ctx.stroke())}drawText(t,e,n,i){const o=`${i.fontStyle} ${i.fontWeight} ${i.fontSize}px ${i.fontFamily}`;this.ctx.fillStyle=i.fontColor,this.ctx.font=o,this.ctx.imageSmoothingEnabled=!0,this.ctx.imageSmoothingQuality="high",this.ctx.textAlign=i.textAlign,this.ctx.textBaseline=i.textBaseline,this.ctx.fillText(t,Math.round(e),Math.round(n))}destroy(){const t=this.canvas.parentElement;t&&t.removeChild(this.canvas)}}class l{constructor(t){this.ctx=t}measureWidth(t,e,n,i,o){return this.ctx.font=`${i} ${n} ${e}px ${o}`,this.ctx.imageSmoothingEnabled=!0,this.ctx.imageSmoothingQuality="high",this.ctx.measureText(t).width}}function s(t,e){const n=`bubbleChartTooltip-${e}`;return document.body.querySelector(`#${n}`)||(t.id=n,document.body.appendChild(t),t)}function d(t,e){const n=e.getBoundingClientRect(),i=window.devicePixelRatio||1;return{mouseX:(t.clientX-n.left)*i,mouseY:(t.clientY-n.top)*i}}function c(t,e,n){return n.find(n=>Math.hypot(t-n.x,e-n.y)<n.radius)||null}function u(t){let e=null;return{handle:n=>{e||(e=requestAnimationFrame(()=>{t(n),e=null}))},cancel:()=>{e&&(cancelAnimationFrame(e),e=null)}}}class h{}function f(t){if(!function(t){return t?!(!Array.isArray(t.data)||0===t.data.length)||(console.error("Invalid or empty data array"),!1):(console.error("Invalid config object"),!1)}(t))return;const e=function(t){var e,n;const i=document.getElementById(t.canvasContainerId);if(!i)return console.error(`Canvas container with ID '${t.canvasContainerId}' not found.`),null;if(i.querySelector("canvas"))return console.error("A canvas already exists inside the container."),null;const o=document.createElement("canvas");return Object.assign(o.style,{border:(null===(e=t.canvasBorderColor)||void 0===e?void 0:e.trim())?`1px solid #${t.canvasBorderColor}`:h.TRANSPARENT,background:(null===(n=t.canvasBackgroundColor)||void 0===n?void 0:n.trim())?`#${t.canvasBackgroundColor}`:h.TRANSPARENT,width:"100%",height:"100%",display:"block",imageRendering:"crisp-edges",aspectRatio:"1 / 1"}),o.style.setProperty("image-rendering","-moz-crisp-edges"),o.style.setProperty("image-rendering","-webkit-optimize-contrast"),o.style.setProperty("-ms-interpolation-mode","nearest-neighbor"),i.appendChild(o),o}(t);if(!e)return;const n=new r(e),m=new l(n.getContext()),{width:y,height:v}=n.setup();let x=function(t,e,n,a){const r=Object.assign({forceStrength:i.FC,iterations:i.rX,damping:i.d6,boundaryForce:i.WH,centerForce:i.ND,centerAttraction:i.$l,centerDamping:i.cg,centerRadiusBuffer:i.e0},a),l=Math.min((e-10)/2,(n-10)/2),s=e/2,d=n/2,c=[...t].sort((t,e)=>e.value-t.value).map(t=>Object.assign(Object.assign({},t),{radius:0,x:0,y:0,fixed:!1}));if(0===c.length)return c;const u=c[0].value,h=Math.min(.5*l,.2*Math.min(e,n)),f=Math.max(.3*h,.05*Math.min(e,n));return c.forEach(t=>{const i=u>0?t.value/u:1;t.radius=f+i*(h-f),t.radius=Math.max(0,Math.min(t.radius,(e-10)/2,(n-10)/2))}),c.forEach((t,i)=>{if(0===i)t.x=s,t.y=d,t.fixed=!0;else{const o=c[0].radius+t.radius+3,a=Math.PI*(3-Math.sqrt(5)),r=e-5-t.radius,l=n-5-t.radius;t.x=Math.min(r,Math.max(5+t.radius,s+Math.cos(a*i)*o)),t.y=Math.min(l,Math.max(5+t.radius,d+Math.sin(a*i)*o)),t.fixed=!1}}),function(t,e,n,i,a,r,l){for(let i=0;i<e.iterations;i++)t.forEach((i,o)=>{if(0===o){const t=a-i.x,n=r-i.y;return void(Math.hypot(t,n)>2&&(i.x+=t*e.centerDamping,i.y+=n*e.centerDamping))}let s=0,d=0;const c=i.radius+5;i.x<c?s+=(c-i.x)*e.boundaryForce:i.x>n-c&&(s+=(n-c-i.x)*e.boundaryForce),t.forEach(t=>{if(i===t)return;const n=i.x-t.x,o=i.y-t.y,c=Math.hypot(n,o),u=i.radius+t.radius;if(c<1.5*u){const t=e.forceStrength*(u/Math.max(c,.1));s+=n/c*t,d+=o/c*t}const h=a-i.x,f=r-i.y,m=Math.hypot(h,f),y=i.value/l*.02;i.x+=h/m*y,i.y+=f/m*y});const u=a-i.x,h=r-i.y,f=Math.hypot(u,h),m=t[0].radius+i.radius+e.centerRadiusBuffer,y=e.centerAttraction*(1-i.value/l)*(1-Math.min(1,f/m));i.x+=u*y,i.y+=h*y,i.x+=s*(1-e.damping),i.y+=d*(1-e.damping)}),o(t,e)}(c,r,e,0,s,d,u),function(t,e,n){t.forEach(t=>{const i=Math.max(5+t.radius,Math.min(e-5-t.radius,t.x)),o=Math.max(5+t.radius,Math.min(n-5-t.radius,t.y));(!t.fixed||Math.hypot(t.x-i,t.y-o)>2)&&(t.x=i,t.y=o)})}(c,e,n),c}(t.data,y,v);function g(){n.setup(),n.clear(),x.forEach(e=>{const i=function(t,e,n){var i,o,r,l,s,d,c,u,h,f,m;let y=null!==(i=n.defaultBubbleColor)&&void 0!==i?i:"#3498db";if(t.bubbleColor)y=t.bubbleColor;else if(n.colorPalette&&n.colorPalette.length>0){const i=e.findIndex(e=>e.label===t.label&&e.value===t.value),o=i>=0?i:0;y=n.colorPalette[o%n.colorPalette.length]}const v=Math.max(t.radius||0,n.minRadius||10);return{bubbleColor:y,borderColor:null!==(o=t.borderColor)&&void 0!==o?o:"black",borderThickness:Math.max(null!==(r=t.borderThickness)&&void 0!==r?r:.25,0),opacity:void 0!==t.opacity?Math.max(0,Math.min(1,t.opacity)):1,fontStyle:t.fontStyle||"normal",fontWeight:"number"==typeof t.fontWeight&&t.fontWeight>=100&&t.fontWeight<=900?t.fontWeight:400,textAlign:null!==(l=t.textAlign)&&void 0!==l?l:"center",textTransform:null!==(s=t.textTransform)&&void 0!==s?s:"none",fontColor:null!==(c=null!==(d=t.fontColor)&&void 0!==d?d:n.defaultFontColor)&&void 0!==c?c:"#000",textBaseline:null!==(u=t.textBaseline)&&void 0!==u?u:"middle",fontSize:Math.max(a(v,null!==(h=n.fontSize)&&void 0!==h?h:14,null!==(f=t.fontWeight)&&void 0!==f?f:400),8),fontFamily:t.fontFamily&&"string"==typeof t.fontFamily&&"Arial"!==t.fontFamily?`${t.fontFamily}, Arial, sans-serif`:`${null!==(m=n.defaultFontFamily)&&void 0!==m?m:"Arial"}, sans-serif`}}(e,x,t);n.drawCircle(e.x,e.y,Math.max(e.radius||0,t.minRadius||10),i.bubbleColor,i.borderColor,i.borderThickness,i.opacity);let o=e.label||"";"uppercase"===i.textTransform?o=o.toUpperCase():"lowercase"===i.textTransform?o=o.toLowerCase():"capitalize"===i.textTransform&&(o=o.replace(/\b\w/g,t=>t.toUpperCase()));const r=Math.max(e.radius||0,t.minRadius||10),l={fontSize:i.fontSize,fontFamily:i.fontFamily,fontWeight:i.fontWeight,fontStyle:i.fontStyle,fontColor:i.fontColor,textAlign:i.textAlign,textBaseline:i.textBaseline};if(t.textWrap){const o=1.5*r-10,a=1.4*i.fontSize,s=function(t,e,n,i,o,a=14,r=400,l="normal",s="Arial",d=0,c=5,u=1.2){const h=1.5*(o-c),f=a*u,m=Math.max(1,Math.floor(h/f)),y="auto"===i||void 0===i?m:Math.min(i,m);n=Math.max(0,n-2*d);const v=e.split(" ");let x="";const g=[];let p=!1,b=!1;const C=e=>t.measureWidth(e,a,r,l,s);for(const t of v){const e=x?`${x} ${t}`:t;if(C(e)<=n)x=e;else if(x.trim()&&g.push(x),x=t,C(x)>n){let t=x;for(;C(t+"...")>n&&t.length>0;)t=t.slice(0,-1);g.push(t+"..."),b=!0;break}if(g.length>=y){p=!0;break}}if(x&&g.length<y&&!b&&g.push(x),p&&g.length>0){let t=g[g.length-1];for(;C(t+"...")>n&&t.length>0;)t=t.slice(0,-1);g[g.length-1]=t+"..."}return g}(m,e.label,o,t.maxLines,r,i.fontSize,i.fontWeight,i.fontStyle,i.fontFamily),d=e.y-(s.length-1)*a/2;s.forEach((t,i)=>{n.drawText(t,e.x,d+i*a,l)})}else n.drawText(o,e.x,e.y,l)})}let p=null;if(t.isResizeCanvasOnWindowSizeChange){const e=document.getElementById(t.canvasContainerId);e&&(p=function(t,e){let n=null,i=null;const o=()=>{i||(i=requestAnimationFrame(()=>{e(),i=null}))};return"undefined"!=typeof ResizeObserver?(n=new ResizeObserver(o),n.observe(t)):(o(),window.addEventListener("resize",o)),{destroy:()=>{n&&(n.disconnect(),n=null),window.removeEventListener("resize",o),i&&(cancelAnimationFrame(i),i=null)}}}(e,()=>{const t=n.getCanvas();e&&t&&(t.width=e.offsetWidth,t.height=e.offsetHeight,g())}))}g();let b=null;t.showToolTip&&(b=function(t){var e,n,i,o,a,r,l,d,c,u,h,f,m,y,v,x,g,p,b;const C=null===(i=null===(n=null===(e=t.data[0])||void 0===e?void 0:e.toolTipConfig)||void 0===n?void 0:n.tooltipFormattedData)||void 0===i?void 0:i.trim();if(C){const e=document.createElement("div");e.innerHTML=C.trim();const n=e.firstElementChild;return n.style.display="none",n.style.visibility="hidden",n.style.opacity="0",n.style.position="absolute",s(n,t.canvasContainerId)}const M=document.createElement("div");M.style.display="none";const w=null!==(o=null==t?void 0:t.tooltipOptions)&&void 0!==o?o:{},S=(t,e)=>"number"==typeof t?`${t}px`:null!=t?t:e;return Object.assign(M.style,{position:"absolute",padding:S(w.padding,"8px"),margin:S(w.margin,"0"),background:null!==(a=w.backgroundColor)&&void 0!==a?a:"rgba(0, 0, 0, 0.85)",color:null!==(r=w.fontColor)&&void 0!==r?r:"white",borderRadius:"4px",pointerEvents:null!==(l=w.pointerEvents)&&void 0!==l?l:"none",fontFamily:null!==(d=w.fontFamily)&&void 0!==d?d:"Arial, sans-serif",fontSize:S(w.fontSize,"14px"),fontWeight:String(null!==(c=w.fontWeight)&&void 0!==c?c:"400"),fontStyle:null!==(u=w.fontStyle)&&void 0!==u?u:"normal",textAlign:null!==(h=w.textAlign)&&void 0!==h?h:"left",textDecoration:null!==(f=w.textDecoration)&&void 0!==f?f:"none",textTransform:null!==(m=w.textTransform)&&void 0!==m?m:"none",letterSpacing:S(w.letterSpacing,"normal"),border:(()=>{var t;if(!w.borderStyle)return"none";const e=S(w.borderWidth,"1px"),n=null!==(t=w.borderColor)&&void 0!==t?t:"transparent";return`${e} ${w.borderStyle} ${n}`})(),boxShadow:null!==(y=w.boxShadow)&&void 0!==y?y:"none",maxWidth:S(w.maxWidth,"200px"),minWidth:S(w.minWidth,"auto"),maxHeight:S(w.maxHeight,"none"),minHeight:S(w.minHeight,"auto"),zIndex:String(null!==(v=w.zIndex)&&void 0!==v?v:1e3),transition:null!==(x=w.transition)&&void 0!==x?x:"opacity 0.2s",transform:null!==(g=w.transform)&&void 0!==g?g:"none",backdropFilter:null!==(p=w.backdropFilter)&&void 0!==p?p:"none",opacity:String(null!==(b=w.opacity)&&void 0!==b?b:1),display:"none",visibility:"hidden"}),s(M,t.canvasContainerId),M}(t));const C=n.getCanvas(),M=u(e=>{const{mouseX:n,mouseY:i}=d(e,C),o=c(n,i,x);if(o){const n=(null==t?void 0:t.cursorType)||"pointer";if(C.style.cursor=n,b){const n=function(t,e){var n,i,o;if(!t)return"";if(e.tooltipOptions&&"function"==typeof e.tooltipOptions.formatter)return e.tooltipOptions.formatter(t);const a=null===(i=null===(n=t.toolTipConfig)||void 0===n?void 0:n.tooltipText)||void 0===i?void 0:i.trim();if(a)return`<div>${a}</div>`;const r=null===(o=t.label)||void 0===o?void 0:o.trim();return r?`<div>${r}<br>Value: ${t.value}</div>`:`<div>${t.value}</div>`}(o,t);!function(t,e,n,i){e&&n&&(e.style.display="block",e.innerHTML=i,e.style.left=`${t.pageX+15}px`,e.style.top=`${t.pageY+15}px`,e.style.zIndex="999999",e.style.visibility="visible",e.style.opacity="1",e.style.position="absolute")}(e,b,C,n)}}else C.style.cursor="default",function(t){t&&(t.style.display="none",t.style.visibility="hidden",t.style.opacity="0")}(b)});C.addEventListener("mousemove",M.handle);const w=u(e=>{const{mouseX:n,mouseY:i}=d(e,C),o=c(n,i,x);o&&t.onBubbleClick&&t.onBubbleClick(o,e)});t.onBubbleClick&&C.addEventListener("click",w.handle);const S=()=>{null==p||p.destroy(),M.cancel(),w.cancel(),C.removeEventListener("mousemove",M.handle),C.removeEventListener("click",w.handle),n.destroy(),(null==b?void 0:b.parentElement)&&b.parentElement.removeChild(b),b=null};return{destroy:S,update:e=>(S(),t.data=e,f(t))}}h.TRANSPARENT="transparent";class m{constructor(t){const e=function(t={}){var e,i;if(!t)return void console.error("Configuration is not valid. Chart initialization aborted.");if(!t.data||0===t.data.length)return void console.error("No valid data provided. Chart initialization aborted.");const o=(a=Object.assign({canvasContainerId:null!==(e=t.canvasContainerId)&&void 0!==e?e:"chart-container",data:null!==(i=t.data)&&void 0!==i?i:[]},t),Object.assign(Object.assign({},n),a));var a;const r=f(o);return r?{config:o,instance:r}:void 0}(t);e&&(this.configuration=e.config,this.instance=e.instance)}destroy(){this.instance&&this.instance.destroy()}update(t){this.instance&&(this.instance=this.instance.update(t))}}function y(t){return new m(t)}return"undefined"!=typeof window&&(window.initializeChart=y,window.BubbleChart=m),e})());
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>BubbleChartJS Test</title>
|
|
7
|
+
<style>
|
|
8
|
+
body {
|
|
9
|
+
font-family: Arial, sans-serif;
|
|
10
|
+
margin: 20px;
|
|
11
|
+
background-color: #f4f4f9;
|
|
12
|
+
}
|
|
13
|
+
.container {
|
|
14
|
+
display: flex;
|
|
15
|
+
flex-direction: column;
|
|
16
|
+
gap: 20px;
|
|
17
|
+
max-width: 800px;
|
|
18
|
+
margin: 0 auto;
|
|
19
|
+
}
|
|
20
|
+
.controls {
|
|
21
|
+
display: flex;
|
|
22
|
+
gap: 10px;
|
|
23
|
+
padding: 15px;
|
|
24
|
+
background: white;
|
|
25
|
+
border-radius: 8px;
|
|
26
|
+
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
27
|
+
}
|
|
28
|
+
button {
|
|
29
|
+
padding: 8px 16px;
|
|
30
|
+
cursor: pointer;
|
|
31
|
+
border: none;
|
|
32
|
+
border-radius: 4px;
|
|
33
|
+
background-color: #007bff;
|
|
34
|
+
color: white;
|
|
35
|
+
font-weight: bold;
|
|
36
|
+
}
|
|
37
|
+
button:hover {
|
|
38
|
+
background-color: #0056b3;
|
|
39
|
+
}
|
|
40
|
+
button.danger {
|
|
41
|
+
background-color: #dc3545;
|
|
42
|
+
}
|
|
43
|
+
button.danger:hover {
|
|
44
|
+
background-color: #a71d2a;
|
|
45
|
+
}
|
|
46
|
+
#chart-container {
|
|
47
|
+
width: 100%;
|
|
48
|
+
height: 400px;
|
|
49
|
+
background: white;
|
|
50
|
+
border-radius: 8px;
|
|
51
|
+
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
52
|
+
position: relative; /* important for tooltip */
|
|
53
|
+
}
|
|
54
|
+
#log {
|
|
55
|
+
padding: 15px;
|
|
56
|
+
background: #333;
|
|
57
|
+
color: #0f0;
|
|
58
|
+
font-family: monospace;
|
|
59
|
+
border-radius: 8px;
|
|
60
|
+
min-height: 100px;
|
|
61
|
+
}
|
|
62
|
+
</style>
|
|
63
|
+
</head>
|
|
64
|
+
<body>
|
|
65
|
+
<div class="container">
|
|
66
|
+
<h2>BubbleChartJS Testing Playground</h2>
|
|
67
|
+
|
|
68
|
+
<div class="controls">
|
|
69
|
+
<button id="btn-update">Update Data (Dynamic Update)</button>
|
|
70
|
+
<button id="btn-destroy" class="danger">Destroy Chart</button>
|
|
71
|
+
<button id="btn-recreate">Recreate Chart</button>
|
|
72
|
+
<button id="btn-resize">Change Container Size (Responsive)</button>
|
|
73
|
+
</div>
|
|
74
|
+
|
|
75
|
+
<div id="chart-container"></div>
|
|
76
|
+
|
|
77
|
+
<div id="log">Logs will appear here...<br></div>
|
|
78
|
+
</div>
|
|
79
|
+
|
|
80
|
+
<!-- Load the UMD bundle -->
|
|
81
|
+
<script src="../dist/bubbleChart.umd.js?v=2"></script>
|
|
82
|
+
|
|
83
|
+
<script>
|
|
84
|
+
const logEl = document.getElementById('log');
|
|
85
|
+
function log(msg) {
|
|
86
|
+
logEl.innerHTML += `> ${msg}<br>`;
|
|
87
|
+
logEl.scrollTop = logEl.scrollHeight;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
let chartInstance = null;
|
|
91
|
+
|
|
92
|
+
const dataset1 = [
|
|
93
|
+
{ label: "Sales", value: 50 },
|
|
94
|
+
{ label: "Marketing", value: 30 },
|
|
95
|
+
{ label: "Engineering", value: 80 },
|
|
96
|
+
{ label: "HR", value: 20 },
|
|
97
|
+
{ label: "Customer Support", value: 45 }
|
|
98
|
+
];
|
|
99
|
+
|
|
100
|
+
const dataset2 = [
|
|
101
|
+
{ label: "Alpha", value: 90 },
|
|
102
|
+
{ label: "Beta", value: 60 },
|
|
103
|
+
{ label: "Gamma", value: 40 }
|
|
104
|
+
];
|
|
105
|
+
|
|
106
|
+
function createChart(data) {
|
|
107
|
+
if (chartInstance) {
|
|
108
|
+
log("Chart already exists. Destroy it first.");
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
log("Initializing chart...");
|
|
113
|
+
chartInstance = window.initializeChart({
|
|
114
|
+
canvasContainerId: "chart-container",
|
|
115
|
+
data: data,
|
|
116
|
+
minRadius: 20,
|
|
117
|
+
maxLines: 3,
|
|
118
|
+
textWrap: true,
|
|
119
|
+
isResizeCanvasOnWindowSizeChange: true, // Responsive Resize
|
|
120
|
+
colorPalette: ["#FF6B6B", "#4ECDC4", "#45B7D1", "#96CEB4", "#FFEEAD"], // Custom Color Palette
|
|
121
|
+
defaultFontColor: "#ffffff",
|
|
122
|
+
fontSize: 14,
|
|
123
|
+
showToolTip: true,
|
|
124
|
+
tooltipOptions: {
|
|
125
|
+
backgroundColor: "rgba(0, 0, 0, 0.9)",
|
|
126
|
+
fontColor: "#fff",
|
|
127
|
+
// GLOBAL TOOLTIP FORMATTER
|
|
128
|
+
formatter: (item) => {
|
|
129
|
+
return `<div style="text-align: center;">
|
|
130
|
+
<strong>🔥 Custom Formatter 🔥</strong><br>
|
|
131
|
+
<i>${item.label}</i><br>
|
|
132
|
+
<span style="color: #4ECDC4; font-size: 1.2em;">${item.value} units</span>
|
|
133
|
+
</div>`;
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
// BUBBLE CLICK EVENT
|
|
137
|
+
onBubbleClick: (bubble, event) => {
|
|
138
|
+
log(`Clicked on bubble: ${bubble.label} (Value: ${bubble.value})`);
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
log("Chart initialized.");
|
|
142
|
+
|
|
143
|
+
// Debugging the instance structure
|
|
144
|
+
log(`Instance Type: ${chartInstance.constructor ? chartInstance.constructor.name : 'Unknown'}`);
|
|
145
|
+
log(`Has update: ${!!chartInstance.update}`);
|
|
146
|
+
log(`Has destroy: ${!!chartInstance.destroy}`);
|
|
147
|
+
let props = [];
|
|
148
|
+
for (let k in chartInstance) { props.push(k); }
|
|
149
|
+
log(`Properties: ${props.join(', ')}`);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// 1. Initial Render
|
|
153
|
+
createChart(dataset1);
|
|
154
|
+
|
|
155
|
+
// 2. Dynamic Update binding
|
|
156
|
+
document.getElementById('btn-update').addEventListener('click', () => {
|
|
157
|
+
if (chartInstance && chartInstance.update) {
|
|
158
|
+
log("Updating chart with new dataset...");
|
|
159
|
+
chartInstance.update(dataset2);
|
|
160
|
+
} else {
|
|
161
|
+
log("Cannot update: Chart instance not found or doesn't support update().");
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
// 3. Destroy Method binding
|
|
166
|
+
document.getElementById('btn-destroy').addEventListener('click', () => {
|
|
167
|
+
if (chartInstance && chartInstance.destroy) {
|
|
168
|
+
log("Destroying chart...");
|
|
169
|
+
chartInstance.destroy();
|
|
170
|
+
chartInstance = null;
|
|
171
|
+
} else {
|
|
172
|
+
log("Cannot destroy: Chart instance not found or doesn't support destroy().");
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
// 4. Recreate binding
|
|
177
|
+
document.getElementById('btn-recreate').addEventListener('click', () => {
|
|
178
|
+
createChart(dataset1);
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
// 5. Responsive Resize binding
|
|
182
|
+
// Test ResizeObserver or Window Resize behavior
|
|
183
|
+
document.getElementById('btn-resize').addEventListener('click', () => {
|
|
184
|
+
const container = document.getElementById('chart-container');
|
|
185
|
+
const newWidth = container.style.width === '50%' ? '100%' : '50%';
|
|
186
|
+
container.style.width = newWidth;
|
|
187
|
+
log(`Resized container to ${newWidth}. Check if chart resizes correctly.`);
|
|
188
|
+
// Simulate window resize to trigger the window scale logic, since ResizeObserver is not implemented yet
|
|
189
|
+
window.dispatchEvent(new Event('resize'));
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
</script>
|
|
193
|
+
</body>
|
|
194
|
+
</html>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bubble-chart-js",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "bubbleChartJs is a lightweight, customizable JavaScript library for creating stacked bubble charts. It arranges bubbles based on their values, with the largest bubble positioned at the top and surrounding bubbles decreasing in size accordingly.",
|
|
5
5
|
"main": "dist/bubbleChart.cjs.js",
|
|
6
6
|
"module": "dist/bubbleChart.esm.js",
|
|
@@ -40,11 +40,14 @@
|
|
|
40
40
|
"author": "Pragadeeshwaran Pasupathi <pragadeeshwaran.pasupathi@gmail.com>",
|
|
41
41
|
"repository": {
|
|
42
42
|
"type": "git",
|
|
43
|
-
"url": "https://github.com/Praga-Dev/bubbleChartJS.git"
|
|
43
|
+
"url": "git+https://github.com/Praga-Dev/bubbleChartJS.git"
|
|
44
44
|
},
|
|
45
45
|
"license": "MIT",
|
|
46
46
|
"keywords": [
|
|
47
|
+
"bubble",
|
|
48
|
+
"chart",
|
|
47
49
|
"bubble chart",
|
|
50
|
+
"bubble chart js",
|
|
48
51
|
"chartjs",
|
|
49
52
|
"chart.js",
|
|
50
53
|
"visualization",
|
|
@@ -58,4 +61,4 @@
|
|
|
58
61
|
"data plotting",
|
|
59
62
|
"bubble chartjs"
|
|
60
63
|
]
|
|
61
|
-
}
|
|
64
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Conformance Test Fixture Generator
|
|
3
|
+
*
|
|
4
|
+
* Run with: npx ts-node --project tsconfig.json scripts/generate-fixtures.ts
|
|
5
|
+
*
|
|
6
|
+
* Reads all input fixtures from spec/fixtures/, runs them through the layout engine,
|
|
7
|
+
* and writes the expected output alongside each input file.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import * as fs from 'fs';
|
|
11
|
+
import * as path from 'path';
|
|
12
|
+
import { computeLayout } from '../src/core/layout-engine';
|
|
13
|
+
|
|
14
|
+
const fixturesDir = path.join(__dirname, '..', 'spec', 'fixtures');
|
|
15
|
+
|
|
16
|
+
const inputFiles = fs
|
|
17
|
+
.readdirSync(fixturesDir)
|
|
18
|
+
.filter((f) => f.endsWith('.input.json'));
|
|
19
|
+
|
|
20
|
+
for (const inputFile of inputFiles) {
|
|
21
|
+
const inputPath = path.join(fixturesDir, inputFile);
|
|
22
|
+
const input = JSON.parse(fs.readFileSync(inputPath, 'utf8'));
|
|
23
|
+
|
|
24
|
+
const result = computeLayout(input.data, input.width, input.height);
|
|
25
|
+
|
|
26
|
+
const expected = {
|
|
27
|
+
specVersion: input.specVersion || '1.0',
|
|
28
|
+
tolerance: 1.0,
|
|
29
|
+
nodes: result.map((node) => ({
|
|
30
|
+
label: node.label,
|
|
31
|
+
x: Math.round(node.x * 100) / 100,
|
|
32
|
+
y: Math.round(node.y * 100) / 100,
|
|
33
|
+
radius: Math.round(node.radius * 100) / 100,
|
|
34
|
+
fixed: node.fixed,
|
|
35
|
+
})),
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const expectedFile = inputFile.replace('.input.json', '.expected.json');
|
|
39
|
+
const expectedPath = path.join(fixturesDir, expectedFile);
|
|
40
|
+
|
|
41
|
+
fs.writeFileSync(expectedPath, JSON.stringify(expected, null, 2) + '\n');
|
|
42
|
+
console.log(`Generated: ${expectedFile} (${expected.nodes.length} nodes)`);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
console.log('Done! All expected fixtures generated.');
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"specVersion": "1.0",
|
|
3
|
+
"defaultBubbleColor": "#3498DB",
|
|
4
|
+
"defaultFontColor": "#ffffff",
|
|
5
|
+
"minRadius": 10,
|
|
6
|
+
"maxLines": "auto",
|
|
7
|
+
"textWrap": true,
|
|
8
|
+
"fontSize": 14,
|
|
9
|
+
"defaultFontFamily": "Arial",
|
|
10
|
+
"showTooltip": true,
|
|
11
|
+
"enableResize": true,
|
|
12
|
+
"borderThickness": 0.25,
|
|
13
|
+
"borderColor": "#000000",
|
|
14
|
+
"opacity": 1.0,
|
|
15
|
+
"canvasPadding": 5
|
|
16
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"specVersion": "1.0",
|
|
3
|
+
"width": 800,
|
|
4
|
+
"height": 600,
|
|
5
|
+
"data": [
|
|
6
|
+
{ "label": "Item 1", "value": 100 },
|
|
7
|
+
{ "label": "Item 2", "value": 90 },
|
|
8
|
+
{ "label": "Item 3", "value": 80 },
|
|
9
|
+
{ "label": "Item 4", "value": 70 },
|
|
10
|
+
{ "label": "Item 5", "value": 60 },
|
|
11
|
+
{ "label": "Item 6", "value": 50 },
|
|
12
|
+
{ "label": "Item 7", "value": 40 },
|
|
13
|
+
{ "label": "Item 8", "value": 30 },
|
|
14
|
+
{ "label": "Item 9", "value": 20 },
|
|
15
|
+
{ "label": "Item 10", "value": 10 }
|
|
16
|
+
]
|
|
17
|
+
}
|
package/dist/canvas.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export declare const PHYSICS: {
|
|
2
|
-
readonly forceStrength: 0.008;
|
|
3
|
-
readonly iterations: 1000;
|
|
4
|
-
readonly damping: 0.65;
|
|
5
|
-
readonly boundaryForce: 0.02;
|
|
6
|
-
readonly centerForce: 0.12;
|
|
7
|
-
readonly centerAttraction: 0.8;
|
|
8
|
-
readonly centerDamping: 0.3;
|
|
9
|
-
readonly centerRadiusBuffer: 35;
|
|
10
|
-
};
|
package/dist/core/renderer.d.ts
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
export declare function getWrappedLines(ctx: CanvasRenderingContext2D, text: string, maxLineWidth: number, maxAllowedLines: number | "auto" | undefined, radius: number, fontSize?: number, // TODO : take all default values from constants
|
|
2
|
-
fontWeight?: number, fontStyle?: "normal" | "italic" | "oblique", fontFamily?: string, horizontalPadding?: number, verticalPadding?: number, lineHeightFactor?: number, maxCharsPerWord?: number | undefined): string[];
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { DataItemInfo } from "../models/internal/data-item-info";
|
|
2
|
-
import { Configuration } from "../models/public/configuration";
|
|
3
|
-
export declare function createTooltipElement(config: Configuration): HTMLDivElement | null;
|
|
4
|
-
export declare function onBubbleClickEventHandler(// TODO : move to interactions.ts
|
|
5
|
-
event: MouseEvent, data: DataItemInfo[], canvas: HTMLCanvasElement, config: Configuration): void;
|
|
6
|
-
export declare function handleMouseMove(event: MouseEvent, data: DataItemInfo[], canvas: HTMLCanvasElement, tooltip: HTMLDivElement, config: Configuration): void;
|
package/dist/index.d.ts
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Defines the appearance properties for a bubble.
|
|
3
|
-
*/
|
|
4
|
-
export interface BubbleAppearance {
|
|
5
|
-
/**
|
|
6
|
-
* Bubble background color
|
|
7
|
-
* @default "#3498DB"
|
|
8
|
-
*/
|
|
9
|
-
bubbleColor?: string;
|
|
10
|
-
/**
|
|
11
|
-
* Border thickness (in pixels)
|
|
12
|
-
* @default 0.25
|
|
13
|
-
*/
|
|
14
|
-
borderThickness?: number;
|
|
15
|
-
/**
|
|
16
|
-
* Border color
|
|
17
|
-
* @default "black"
|
|
18
|
-
*/
|
|
19
|
-
borderColor?: string;
|
|
20
|
-
/**
|
|
21
|
-
* Opacity level (0: transparent, 1: fully visible)
|
|
22
|
-
* @validValues 0 - 1
|
|
23
|
-
* @default 1
|
|
24
|
-
*/
|
|
25
|
-
opacity?: number;
|
|
26
|
-
}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Defines the font-related styling options.
|
|
3
|
-
*/
|
|
4
|
-
export interface FontOptions {
|
|
5
|
-
/**
|
|
6
|
-
* Custom font family
|
|
7
|
-
* @example "Arial", "Verdana"
|
|
8
|
-
* @default "Arial"
|
|
9
|
-
*/
|
|
10
|
-
fontFamily?: string;
|
|
11
|
-
/**
|
|
12
|
-
* Font style
|
|
13
|
-
* @validValues "normal" | "italic" | "oblique"
|
|
14
|
-
* @default "normal"
|
|
15
|
-
*/
|
|
16
|
-
fontStyle?: "normal" | "italic" | "oblique";
|
|
17
|
-
/**
|
|
18
|
-
* Font weight (numeric scale)
|
|
19
|
-
* @validValues 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900
|
|
20
|
-
* @default 400
|
|
21
|
-
*/
|
|
22
|
-
fontWeight?: 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900;
|
|
23
|
-
/**
|
|
24
|
-
* Text alignment
|
|
25
|
-
* @validValues "center" | "end" | "left" | "right" | "start"
|
|
26
|
-
* @default "center"
|
|
27
|
-
*/
|
|
28
|
-
textAlign?: "center" | "end" | "left" | "right" | "start";
|
|
29
|
-
/**
|
|
30
|
-
* Text transformation style
|
|
31
|
-
* @validValues "none" | "uppercase" | "lowercase" | "capitalize"
|
|
32
|
-
* @default "none"
|
|
33
|
-
*/
|
|
34
|
-
textTransform?: "none" | "uppercase" | "lowercase" | "capitalize";
|
|
35
|
-
/**
|
|
36
|
-
* Font color
|
|
37
|
-
* @default "#000000"
|
|
38
|
-
*/
|
|
39
|
-
fontColor?: string;
|
|
40
|
-
/**
|
|
41
|
-
* Text baseline position
|
|
42
|
-
* @validValues "alphabetic" | "bottom" | "hanging" | "ideographic" | "middle" | "top"
|
|
43
|
-
* @default "middle"
|
|
44
|
-
*/
|
|
45
|
-
textBaseline?: "alphabetic" | "bottom" | "hanging" | "ideographic" | "middle" | "top";
|
|
46
|
-
}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
export interface InteractionOptions {
|
|
2
|
-
showToolTip?: boolean;
|
|
3
|
-
isResizeCanvasOnWindowSizeChange?: boolean;
|
|
4
|
-
cursorType?: "default" | "pointer" | "grab" | "crosshair" | "move" | "not-allowed" | "help";
|
|
5
|
-
onBubbleClick?: (bubbleData: any, event: MouseEvent) => void;
|
|
6
|
-
}
|
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
export interface TooltipOptions {
|
|
2
|
-
/**
|
|
3
|
-
* CSS font-family property
|
|
4
|
-
* @default "Arial, sans-serif"
|
|
5
|
-
*/
|
|
6
|
-
fontFamily?: string;
|
|
7
|
-
/**
|
|
8
|
-
* Font style for tooltip text
|
|
9
|
-
* @validValues "normal", "italic", "oblique"
|
|
10
|
-
* @default "normal"
|
|
11
|
-
*/
|
|
12
|
-
fontStyle?: "normal" | "italic" | "oblique";
|
|
13
|
-
/**
|
|
14
|
-
* Font weight (numeric scale)
|
|
15
|
-
* @validValues 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900
|
|
16
|
-
* @default 400
|
|
17
|
-
*/
|
|
18
|
-
fontWeight?: 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900;
|
|
19
|
-
/**
|
|
20
|
-
* Font size in pixels
|
|
21
|
-
* @default 14
|
|
22
|
-
*/
|
|
23
|
-
fontSize?: number;
|
|
24
|
-
/**
|
|
25
|
-
* Text alignment within tooltip
|
|
26
|
-
* @validValues "left", "center", "right"
|
|
27
|
-
* @default "left"
|
|
28
|
-
*/
|
|
29
|
-
textAlign?: "left" | "center" | "right";
|
|
30
|
-
/**
|
|
31
|
-
* Text decoration style
|
|
32
|
-
* @validValues "none", "underline", "line-through", "overline"
|
|
33
|
-
* @default "none"
|
|
34
|
-
*/
|
|
35
|
-
textDecoration?: "none" | "underline" | "line-through" | "overline";
|
|
36
|
-
/**
|
|
37
|
-
* Text transformation style
|
|
38
|
-
* @validValues "none", "uppercase", "lowercase", "capitalize"
|
|
39
|
-
* @default "none"
|
|
40
|
-
*/
|
|
41
|
-
textTransform?: "none" | "uppercase" | "lowercase" | "capitalize";
|
|
42
|
-
/**
|
|
43
|
-
* Letter spacing in pixels (0 = normal)
|
|
44
|
-
* @default undefined (normal spacing)
|
|
45
|
-
*/
|
|
46
|
-
letterSpacing?: number;
|
|
47
|
-
/**
|
|
48
|
-
* Text color in CSS format
|
|
49
|
-
* @default "white"
|
|
50
|
-
*/
|
|
51
|
-
fontColor?: string;
|
|
52
|
-
/**
|
|
53
|
-
* Background color in CSS format
|
|
54
|
-
* @default "rgba(0, 0, 0, 0.85)"
|
|
55
|
-
*/
|
|
56
|
-
backgroundColor?: string;
|
|
57
|
-
/**
|
|
58
|
-
* Border color in CSS format
|
|
59
|
-
* @default "transparent"
|
|
60
|
-
*/
|
|
61
|
-
borderColor?: string;
|
|
62
|
-
/**
|
|
63
|
-
* Border style (requires borderWidth to be set)
|
|
64
|
-
* @validValues "solid", "dashed", "dotted", "double", "none"
|
|
65
|
-
* @default "none"
|
|
66
|
-
*/
|
|
67
|
-
borderStyle?: "solid" | "dashed" | "dotted" | "double" | "none";
|
|
68
|
-
/**
|
|
69
|
-
* Border width (CSS value or number in pixels)
|
|
70
|
-
* @example "2px", "0.5rem", 3
|
|
71
|
-
*/
|
|
72
|
-
borderWidth?: string | number;
|
|
73
|
-
/**
|
|
74
|
-
* CSS padding value
|
|
75
|
-
* @example "10px", "1em 2rem", "5% 10px"
|
|
76
|
-
* @default "8px"
|
|
77
|
-
*/
|
|
78
|
-
padding?: string | number;
|
|
79
|
-
/**
|
|
80
|
-
* CSS margin value
|
|
81
|
-
* @example "10px auto", "2rem 1rem"
|
|
82
|
-
* @default "0"
|
|
83
|
-
*/
|
|
84
|
-
margin?: string | number;
|
|
85
|
-
/**
|
|
86
|
-
* CSS box-shadow property
|
|
87
|
-
* @example "3px 3px 5px rgba(0,0,0,0.3)"
|
|
88
|
-
* @default "none"
|
|
89
|
-
*/
|
|
90
|
-
boxShadow?: string;
|
|
91
|
-
/**
|
|
92
|
-
* Opacity value (0 = fully transparent, 1 = fully opaque)
|
|
93
|
-
* @minimum 0
|
|
94
|
-
* @maximum 1
|
|
95
|
-
* @default 1
|
|
96
|
-
*/
|
|
97
|
-
opacity?: number;
|
|
98
|
-
/**
|
|
99
|
-
* Maximum width in pixels
|
|
100
|
-
* @default 200
|
|
101
|
-
*/
|
|
102
|
-
maxWidth?: number;
|
|
103
|
-
/**
|
|
104
|
-
* Minimum width in pixels
|
|
105
|
-
* @default undefined (auto)
|
|
106
|
-
*/
|
|
107
|
-
minWidth?: number;
|
|
108
|
-
/**
|
|
109
|
-
* Maximum height in pixels
|
|
110
|
-
* @default undefined (none)
|
|
111
|
-
*/
|
|
112
|
-
maxHeight?: number;
|
|
113
|
-
/**
|
|
114
|
-
* Minimum height in pixels
|
|
115
|
-
* @default undefined (auto)
|
|
116
|
-
*/
|
|
117
|
-
minHeight?: number;
|
|
118
|
-
/**
|
|
119
|
-
* Preferred position relative to target element
|
|
120
|
-
* @validValues "top", "bottom", "left", "right"
|
|
121
|
-
*/
|
|
122
|
-
position?: "top" | "bottom" | "left" | "right";
|
|
123
|
-
/**
|
|
124
|
-
* Horizontal offset in pixels
|
|
125
|
-
* @default 0
|
|
126
|
-
*/
|
|
127
|
-
offsetX?: number;
|
|
128
|
-
/**
|
|
129
|
-
* Vertical offset in pixels
|
|
130
|
-
* @default 0
|
|
131
|
-
*/
|
|
132
|
-
offsetY?: number;
|
|
133
|
-
/**
|
|
134
|
-
* CSS z-index property
|
|
135
|
-
* @default 1000
|
|
136
|
-
*/
|
|
137
|
-
zIndex?: number;
|
|
138
|
-
/**
|
|
139
|
-
* CSS pointer-events property
|
|
140
|
-
* @validValues "auto", "none"
|
|
141
|
-
* @default "none"
|
|
142
|
-
*/
|
|
143
|
-
pointerEvents?: "auto" | "none";
|
|
144
|
-
/**
|
|
145
|
-
* Enable/disable animations
|
|
146
|
-
* @default true
|
|
147
|
-
*/
|
|
148
|
-
animation?: boolean;
|
|
149
|
-
/**
|
|
150
|
-
* Animation duration in milliseconds
|
|
151
|
-
* @default 300
|
|
152
|
-
*/
|
|
153
|
-
animationDuration?: number;
|
|
154
|
-
/**
|
|
155
|
-
* CSS backdrop-filter property
|
|
156
|
-
* @example "blur(5px)"
|
|
157
|
-
* @default "none"
|
|
158
|
-
*/
|
|
159
|
-
backdropFilter?: string;
|
|
160
|
-
/**
|
|
161
|
-
* CSS transition property
|
|
162
|
-
* @default "opacity 0.2s"
|
|
163
|
-
*/
|
|
164
|
-
transition?: string;
|
|
165
|
-
/**
|
|
166
|
-
* CSS transform property
|
|
167
|
-
* @default "none"
|
|
168
|
-
*/
|
|
169
|
-
transform?: string;
|
|
170
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { InteractionOptions } from "./config/interaction-options";
|
|
2
|
-
import { TooltipOptions } from "./config/tooltip-options";
|
|
3
|
-
import { DataItem } from "./data-item";
|
|
4
|
-
export interface Configuration extends InteractionOptions {
|
|
5
|
-
data: DataItem[];
|
|
6
|
-
canvasContainerId: string;
|
|
7
|
-
/**
|
|
8
|
-
* Background color of the canvas.
|
|
9
|
-
*
|
|
10
|
-
* @description Supports only HEX values (without `#`).
|
|
11
|
-
* @default "transparent"
|
|
12
|
-
*/
|
|
13
|
-
canvasBackgroundColor?: string;
|
|
14
|
-
/**
|
|
15
|
-
* Border color of the canvas.
|
|
16
|
-
*
|
|
17
|
-
* @description Supports only HEX values (without `#`).
|
|
18
|
-
* @default "transparent"
|
|
19
|
-
*/
|
|
20
|
-
canvasBorderColor?: string;
|
|
21
|
-
minRadius: number;
|
|
22
|
-
maxLines: number | "auto";
|
|
23
|
-
textWrap: boolean;
|
|
24
|
-
defaultBubbleColor: string;
|
|
25
|
-
fontSize: number;
|
|
26
|
-
defaultFontColor: string;
|
|
27
|
-
defaultFontFamily: string;
|
|
28
|
-
isResizeCanvasOnWindowSizeChange: boolean;
|
|
29
|
-
tooltipOptions?: TooltipOptions;
|
|
30
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { BubbleAppearance } from "./config/bubble-appearance";
|
|
2
|
-
import { FontOptions } from "./config/font-options";
|
|
3
|
-
import { ToolTipConfig } from "./config/tooltip-config";
|
|
4
|
-
export interface DataItem extends BubbleAppearance, FontOptions {
|
|
5
|
-
label: string;
|
|
6
|
-
value: number;
|
|
7
|
-
toolTipConfig?: ToolTipConfig;
|
|
8
|
-
}
|
package/dist/utils/config.d.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { Configuration } from "../models/public/configuration";
|
|
2
|
-
/**
|
|
3
|
-
* Default configuration object.
|
|
4
|
-
*/
|
|
5
|
-
export declare const DEFAULT_CONFIG: Omit<Configuration, "canvasContainerId" | "data">;
|
|
6
|
-
/**
|
|
7
|
-
* Merges user config with defaults, ensuring `canvasContainerId` and `data` are required.
|
|
8
|
-
*/
|
|
9
|
-
export declare function mergeConfig(customConfig: {
|
|
10
|
-
canvasContainerId: string;
|
|
11
|
-
data: Configuration["data"];
|
|
12
|
-
} & Partial<Configuration>): Configuration;
|
package/dist/utils/helper.d.ts
DELETED