UNPKG

d3-ternary

Version:
4 lines (3 loc) 6.56 kB
// d3-ternary v3.0.7 Copyright 2025, Jules Blom !function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports,require("d3-scale")):"function"==typeof define&&define.amd?define(["exports","d3-scale"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self).d3=e.d3||{},e.d3)}(this,(function(e,n){"use strict";function t(e){return new Set(e.map((e=>{const n=Math.round(100*(e[0]+Number.EPSILON))/100,t=Math.round(100*(e[1]+Number.EPSILON))/100,l=Math.abs(t-n);return Math.round(100*(l+Number.EPSILON))/100})))}e.barycentric=function(){let e=0,l=e=>e[0],i=e=>e[1],r=e=>e[2];const a=n.scaleLinear().domain([0,1]),o=n.scaleLinear().domain([0,1]),c=n.scaleLinear().domain([0,1]),s=Math.PI/180,[u,f,b]=[-90,150,30].map((e=>[Math.cos(e*s),Math.sin(e*s)]));function d([e,n,t]){return[e*u[0]+n*f[0]+t*b[0],e*u[1]+n*f[1]+t*b[1]]}function k(n,t){const l=e*Math.PI/180,i=Math.cos(l),r=Math.sin(l);return[n*i+t*r,t*i-n*r]}function A([e,n,t]){if(Number.isNaN(e)||Number.isNaN(n)||Number.isNaN(t))throw new Error("Invalid ternary coordinates: values must be numbers");const[l,i,r]=[Number(e),Number(n),Number(t)],a=l+i+r;return 0===a?[0,0,0]:[l/a,i/a,r/a]}const h=function(e){const[n,t,s]=A([l(e),i(e),r(e)]),[u,f]=d([a(n),o(t),c(s)]);return k(u,f)};return h.unscaled=function(e){const[n,t,l]=A(e),[i,r]=d([n,t,l]);return k(i,r)},h.invert=function([n,t]){const l=-e*Math.PI/180,i=Math.cos(l),r=Math.sin(l),s=n*i+t*r,d=t*i-n*r,[k,A]=u,[h,m]=f,[g,p]=b,O=m-p,x=g-h,M=k-g,S=p-A,z=s-g,y=d-p,N=O*M+x*(A-p),w=Math.abs((O*z+x*y)/N),T=Math.abs((S*z+M*y)/N),v=Math.abs(1-w-T);return[a.invert(w),o.invert(T),c.invert(v)]},h.a=function(e){return e?(l=e,h):l},h.b=function(e){return e?(i=e,h):i},h.c=function(e){return e?(r=e,h):r},h.rotation=function(n){return arguments.length?(e=n??0,h):e},h.domains=function(e){if(!e)return[a.domain(),o.domain(),c.domain()];if(1!==t(e).size)throw new Error("All domains must have the same length");return a.domain(e[0]),o.domain(e[1]),c.domain(e[2]),h},h.scales=function(){return[a,o,c]},h},e.domainsFromTransform=function(e){const{k:n,x:t,y:l}=e,i=1/n;if(i>1)throw new Error(`Invalid zoom level: ${n}. Cannot zoom out beyond the original triangle.`);const r=(n-1)/(3*n),a=Math.PI/180,[o,c,s]=[-90,150,30].map((e=>[Math.cos(e*a),Math.sin(e*a)])),u=o[0]*(c[1]-s[1])+c[0]*(s[1]-o[1])+s[0]*(o[1]-c[1]),f=r-(t/n*(c[1]-s[1])+l/n*(s[0]-c[0]))/u,b=r-(t/n*(s[1]-o[1])+l/n*(o[0]-s[0]))/u,d=r-(t/n*(o[1]-c[1])+l/n*(c[0]-o[0]))/u,k=f+i,A=b+i,h=d+i,m=-1e-5,g=1.00001;if(f<m||k>g)throw new Error(`New domain A exceeds bounds ${[f,k]}`);if(b<m||A>g)throw new Error(`New domain B exceeds bounds ${[b,A]}`);if(d<m||h>g)throw new Error(`New domain C exceeds bounds ${[d,h]}`);return[[f,k],[b,A],[d,h]]},e.ternaryPlot=function(e){let n=300,t="%";const l={label:"A",labelAngle:0,labelOffset:45,tickAngle:0,tickSize:6,tickTextAnchor:"start"},i={label:"B",labelAngle:60,labelOffset:45,tickAngle:60,tickSize:6,tickTextAnchor:"end"},r={label:"C",labelAngle:-60,labelOffset:45,tickAngle:-60,tickSize:6,tickTextAnchor:"end"};function a(e,t){return[e*n,t*n]}const o=function(n){const[t,l]=e(n);return a(t,l)};function c(){return[a(...e.unscaled([1,0,0])),a(...e.unscaled([0,1,0])),a(...e.unscaled([0,0,1]))]}return o.triangle=function(){const[e,n,t]=c();return`M${e}L${n}L${t}Z`},o.gridLines=function(n=10){const[t,l,i]=e.scales(),r=Array.isArray(n)?n:[+n,+n,+n];return[t.ticks(r[0]).map((n=>{const l=t(n);return[a(...e.unscaled([l,1-l,0])),a(...e.unscaled([l,0,1-l]))]})),l.ticks(r[1]).map((n=>{const t=l(n);return[a(...e.unscaled([0,t,1-t])),a(...e.unscaled([1-t,t,0]))]})),i.ticks(r[2]).map((n=>{const t=i(n);return[a(...e.unscaled([1-t,0,t])),a(...e.unscaled([0,1-t,t]))]}))]},o.axisLabels=function({center:e=!1}={}){const[t,a,o]=c();if(e){const e=[(t[0]+a[0])/2,(t[1]+a[1])/2],c=[(a[0]+o[0])/2,(a[1]+o[1])/2],s=[(o[0]+t[0])/2,(o[1]+t[1])/2];return[{position:[e[0]/n*(n+l.labelOffset),e[1]/n*(n+l.labelOffset)],label:l.label,angle:l.labelAngle},{position:[c[0]/n*(n+i.labelOffset),c[1]/n*(n+i.labelOffset)],label:i.label,angle:i.labelAngle},{position:[s[0]/n*(n+r.labelOffset),s[1]/n*(n+r.labelOffset)],label:r.label,angle:r.labelAngle}]}return[{position:[t[0]+t[0]*(l.labelOffset/n),t[1]+t[1]*(l.labelOffset/n)],label:l.label,angle:l.labelAngle},{position:[a[0]+a[0]*(i.labelOffset/n),a[1]+a[1]*(i.labelOffset/n)],label:i.label,angle:i.labelAngle},{position:[o[0]+o[0]*(r.labelOffset/n),o[1]+o[1]*(r.labelOffset/n)],label:r.label,angle:r.labelAngle}]},o.ticks=function(n=10){const[o,c,s]=e.scales(),u=Array.isArray(n)?n:[+n,+n,+n],f="function"==typeof t?t:o.tickFormat(u[0],t),b="function"==typeof t?t:c.tickFormat(u[1],t),d="function"==typeof t?t:s.tickFormat(u[2],t);return[o.ticks(u[0]).map((n=>{const t=o(n);return{tick:f(n),angle:l.tickAngle,textAnchor:l.tickTextAnchor,size:l.tickSize,position:a(...e.unscaled([t,0,1-t]))}})),c.ticks(u[1]).map((n=>{const t=c(n);return{tick:b(n),angle:i.tickAngle,textAnchor:i.tickTextAnchor,size:i.tickSize,position:a(...e.unscaled([1-t,t,0]))}})),s.ticks(u[2]).map((n=>{const t=s(n);return{tick:d(n),angle:r.tickAngle,textAnchor:r.tickTextAnchor,size:r.tickSize,position:a(...e.unscaled([0,1-t,t]))}}))]},o.tickFormat=function(e){return arguments.length?(t=e??"%",o):t},o.radius=function(e){return void 0===e?n:(n=+e,o)},o.invert=function(t){return e.invert([t[0]/n,t[1]/n])},o.labels=function(e){return e?(l.label=String(e[0]),i.label=String(e[1]),r.label=String(e[2]),o):[l.label,i.label,r.label]},o.tickAngles=function(e){return e?(l.tickAngle=e[0],i.tickAngle=e[1],r.tickAngle=e[2],o):[l.tickAngle,i.tickAngle,r.tickAngle]},o.labelAngles=function(e){return e?(l.labelAngle=e[0],i.labelAngle=e[1],r.labelAngle=e[2],o):[l.labelAngle,i.labelAngle,r.labelAngle]},o.tickTextAnchors=function(e){return e?(l.tickTextAnchor=e[0],i.tickTextAnchor=e[1],r.tickTextAnchor=e[2],o):[l.tickTextAnchor,i.tickTextAnchor,r.tickTextAnchor]},o.tickSizes=function(e){return e?Array.isArray(e)?(l.tickSize=e[0],i.tickSize=e[1],r.tickSize=e[2],o):(l.tickSize=i.tickSize=r.tickSize=+e,o):[l.tickSize,i.tickSize,r.tickSize]},o.labelOffsets=function(e){return e?Array.isArray(e)?(l.labelOffset=e[0],i.labelOffset=e[1],r.labelOffset=e[2],o):(l.labelOffset=i.labelOffset=r.labelOffset=+e,o):[l.labelOffset,i.labelOffset,r.labelOffset]},o},e.transformFromDomains=function(e){const[n,l,i]=e,r=1/[...t(e)][0],a=(r-1)/(3*r),o=a-n[0],c=a-l[0],s=a-i[0],u=Math.PI/180,[f,b,d]=[-90,150,30].map((e=>[Math.cos(e*u),Math.sin(e*u)]));return{k:r,x:(f[0]*o+b[0]*c+d[0]*s)*r,y:(f[1]*o+b[1]*c+d[1]*s)*r}}})); //# sourceMappingURL=d3-ternary.umd.min.js.map