From da27612572d676447a2e50be9b0ff3612aefe3bc Mon Sep 17 00:00:00 2001 From: Kanit Wongsuphasawat Date: Tue, 21 Jun 2022 13:23:06 -0700 Subject: [PATCH] feat: add `config.numberFormatType` for using custom formatter with `config.numberFormat` (#8228) Co-authored-by: GitHub Actions Bot --- build/vega-lite-schema.json | 6 +- .../compiled/config_numberFormatType_test.png | Bin 0 -> 76940 bytes .../compiled/config_numberFormatType_test.svg | 1 + .../config_numberFormatType_test.vg.json | 293 ++++++++++++++++++ .../config_numberFormatType_test.vl.json | 20 ++ ...g_numberFormatType_test_normalized.vl.json | 23 ++ site/_includes/docs_toc.md | 2 - site/docs/config.md | 2 +- src/compile/axis/encode.ts | 19 +- src/compile/format.ts | 33 +- src/compile/legend/encode.ts | 28 +- src/config.ts | 16 +- test/compile/axis/encode.test.ts | 12 + test/compile/format.test.ts | 71 ++++- test/compile/legend/encode.test.ts | 19 ++ 15 files changed, 525 insertions(+), 20 deletions(-) create mode 100644 examples/compiled/config_numberFormatType_test.png create mode 100644 examples/compiled/config_numberFormatType_test.svg create mode 100644 examples/compiled/config_numberFormatType_test.vg.json create mode 100644 examples/specs/config_numberFormatType_test.vl.json create mode 100644 examples/specs/normalized/config_numberFormatType_test_normalized.vl.json diff --git a/build/vega-lite-schema.json b/build/vega-lite-schema.json index dfe607a6d8..0e99779025 100644 --- a/build/vega-lite-schema.json +++ b/build/vega-lite-schema.json @@ -7644,7 +7644,11 @@ "description": "Mark Config" }, "numberFormat": { - "description": "D3 Number format for guide labels and text marks. For example `\"s\"` for SI units. Use [D3's number format pattern](https://github.com/d3/d3-format#locale_format).", + "description": "If numberFormatType is not specified, D3 Number format for guide labels and text marks. For example `\"s\"` for SI units. Use [D3's number format pattern](https://github.com/d3/d3-format#locale_format).\n\nIf `config.numberFormatType` is specified and `config.customFormatTypes` is `true`, this value will be passed as `format` alongside `datum.value` to the `config.numberFormatType` function.", + "type": "string" + }, + "numberFormatType": { + "description": "[Custom format type](https://vega.github.io/vega-lite/docs/config.html#custom-format-type) for `config.numberFormat`.\n\n__Default value:__ `undefined` -- This is equilvalent to call D3-format, which is exposed as [`format` in Vega-Expression](https://vega.github.io/vega/docs/expressions/#format). __Note:__ You must also set `customFormatTypes` to `true` to use this feature.", "type": "string" }, "padding": { diff --git a/examples/compiled/config_numberFormatType_test.png b/examples/compiled/config_numberFormatType_test.png new file mode 100644 index 0000000000000000000000000000000000000000..60036d911a90b96606e08010ed3a39b4793a1160 GIT binary patch literal 76940 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

O_LnIHLZIjL-6^xo& zHfkx0kfW>2PvI1eIhT!C8*4_IqNrBPKYI^Qn0;H|{k zhZTeMTz3#oOuL+_PdTM$PCuO6_<(Rb*pvRgY0iq- zSwQb-gx0f=@XUJ9?ke)q*9Vumb9PugYPV=vch-*Lh3ez^aJ}}x>+kQs(?ksci$b{h zdR|O(^&ac>w>i9dJ##jr=nWtV93S4a;|K~0nmM@BijVx=E(yE+S&Jpvppugcp;^nuI9%<1=AfLI5c5sV z%r!Qz!e&keaix#PtMk3$tUZF=n_Ob&_!^~^=GhyiL2DVF1j>lfalepcOPLuF1xQKe zR?_r#T$@kfwbw>|YcmsM1s%mi6n_Nk#FzN%VnPs8BynyEv*_de)Z1nT-5j!#ir+iK z)|JR6xynZc6B>3CqfBB+2SbT67yw@jvkroon%ULX+Q zOc}i1KK0f%W(`r&wR|3et!Zf_-Vf=UvcM7h>(T$MwMMhJ zAFYu*&Z6L?lv!|m)xm=>jgmpP5)Rd&+wt_%K%vlZtczW4z*-(}} z*~mxqM8GMI)?Mho0qgLIxe*Olhgc(*4}-tS8&(jQrz8&7kBsK?iw6Qad-D0Pyz&ZcPkDJE(MA;xE6=^?*Ey0h8Y+>B=;nH zUAuesoU@9&TGIRP{ikawPJ6#*jVA01G^h>Vyla{$ALun$Yftmrs?4?1Z6Kfjd)=y! zInDe4@SXi=MS3Ez{NovxO@BcDh0Vr7o~yRHioU&e4lN3TgEutGk<{neIN6u&rxIKTM)=Z$Wo? zHPzHX^>-dgFqAfQr9pn<^88(})8leVEC~`$hr5o#wEKd@8zZ-T-Han)ZcVx(X5f?0 zIO0>}ePo$qm#_0?nb3Zgzx2#CoVH$Cd{HDeO`AByNx!A=0Ule-Bk;T@Pg5 zqG6^+t5n?fR+;NFvLnj|%ky2WXjzq--~OUwS+Xt~2N_pr(x_ou>7{~^nGW+Ti6E`L z)qcDswC~ej$i6TU1)Qu9C9rF8qNjR0w%-2{;{SQu0dKT{5q}&CBW&+bR#i9%1Spn- z7_hdHlCs!&*2E&EwDgY9Jp{|0B9RlH8u^7w;Ays2`!P`9Go@v1%onz{%+u>n;qu+$ zqnI=~jf{<}G#mxy9Vz&ckl=oh^W=Yv*)v}jUBW0;!_ThK3WJ>dez!?9R<58c8hHS{i47Ue@65Stn_pv_^$~%fY<1b3rWd_H?s?i{zq$aJ z*l|aq7tyM97NZHMqUQx7{>zOvn1xTf^eZh+B#MfPmW}%M%}Z5O%?9x`HEQC3$}CSj_WoU{BFjymF2U?9p64-m6;BaoT?*Kg4B|gY@2n6w&#te83~-7 zQNDBhlT@+0Uy*mKlQ|>NPlvUo?XILfI1yrxG3c7riUtNR(yv~enngb=vb9IZDy1*a zW$udXY#iiCJ$da))Xtf&47tBg*du;gfHpd0*3Prg$QSD|nfyGv(AZ?pRMF9Emc(gBN#5ewOIOZ0VD;cKR zc7)(-&PE;bup&Zje^&c51P`i7fDK*FXV{4tAaQh&8+4ERHb^1g+E@rxDt-hHjz!xE zUMuRNWnfC`=cjiJD-7>$$3#ntzv_F=-lSukRoi=SU{hwCxqfts8ih3|D~3Db00G~ssj=xJq`u{cM9ss`tc z5b#L4v-^uR|E@^3Ea>Y}(DM?&L`nyARh2AkY+S;^lP*sqE`~Z+)mR}iC7-e24E<03 zr`G(Zv&KV#&zYioetv#)ywRE2?SEU~w#go_jVd;*8B$+gAN$LC!rJG&%gFoU>h%6D`m68>irkLRHYieyED}pcL=d-kk_{&56hXvx2Q#V(_|h{nP?L5%_&<;T4&p}i-wFr0BI{qQEN1>DDzU^owHU7=B^unjLG(Y$(mz^>HEAgi z?61+{f4UXiqq|zYv}}szQ4^>8+(yuNJD*tlSw}F^_m8F1c^IcWw%+EuJ*G!UI-4ac zMNW3>-f(3lG^o|zyLI&bya#veSF=87ebT^{?dArUqxTf+)ij-2i+=yp!&Ok=}w&Ln%e|#wF zEWJvqye$j9GS-&-f5@M)!iszGmsC{+V^}82U3Nq>Z@$L&Br{)#+EVNcpb3bQ&FFH3 z4fUNza6_JJ#bgFAT}$zQRv>kHId-%7WA=@9IEg-EMrN_CNNHskIp%?sO6>^SkgRob zmuqBosRl%DuZ^DGZo;{2dh6vD(gRH=zVx<7;Uj6`dwGN_J+@MgwU231077|cpS&6&cVR5!7bGb*Y;IUaAP%qO zKy#Sx^b?L~i1=*&Jf~4%8C|R}uRa_lgmH*xk9DGs=qLs#;nIPe>8@>pc;7H%@8)^Z z!AG!Ph!N2ajbSMn-+FvI!TRbam5w}MDD!f^XC>+j&Bk>ti$T~F$+KB-Jr^kq4kr=? zDT|Rb99hJEsWE_~s-g_KwJnetv}uz4h_!A05Wj1`ZMEi)>+rWJKA&^MAD2|WrqQr* zNh+wu`RYz8*?fTtcd5-`28&sl1RB|Si*|KW2G*-4ezGix$;E< zh52>qbQ{O`$wnHYn|p#4he5)`8M1@d(J-c9tZFz)WPOa>a4Td>>0)O;!j?!Fyx5h@ z5npds+Tn*pvb>$$fasjem(I18u?FrB#)@;{f2f36_HPv?VA+Y~P!&;GfC z9dB$Q^ZI#d;R6(`vpuvN^c(ZUvZv zL|<2~wh=?XM~!;*YL>|S-|ivO&YlLMepCBm6KCJ}bUn&)m?eHg`H8xwXEnNhgX5PpIH zlCo3)OAaE7i%V(WO&vup728{kFj-LBjXb72i6yFT--&9kwI9!8B1appNKpP!vik#x zp;3gZerwo3g?;z7hD5E^C}Vt)T_MIPw>67GSZr$Z`42;l_x|mKV%b%|)mZA&;)d>3 z4+-D9^KBB@Pdz?iXT4ov6iBDt&QX>QHVw`l0k?hc63NGkn7Al9%$DB@#^a6xnR_^2`HhO?=9hx%4}iGMM z&CNe}wdYDW-%h+`61Y+DgP-syhC2<&W}KgzSEW+)*5Ey!z70ddVGp)rNGUATzHiqM ze(JUKD~(A)wJfzqK=1dNKNwTCIca_vywJB3csiE~j$%rk$0trm+`yp|k3miunOq;Rxml#UOQ z2HS^cKPFJjy1pabl+7rjEO7V^;2tp&=nT7cF)ya`LqTQc0HL(t zQ^yd{Uf<& ztZc4@jQdPPc_r&%Slak6J0d%AH(`lp?V?a9^mw@i{@d6BUC`Z3B!D`;T#hk{UKOzF z4y|qeuP&>ZOu2Sap@dUa&G2!CNUgX6D9Ae3;_#G3{t-?)Z&rf)Q3hK<0mCJ~s!E~T zM)jADUro)31C!6J8_0Ah%3rzEg?BnGe(iojG~3`vu`YGqxeG~;h_&(^Dn{W{-s{+I zygF&*jKBCbtNQ$>f}6x^)ISw8vbh?uIHwc`{4mzee|QpKxD?Fc>S(5P9cQZh|UTF&6-3bkUEQ3JypW$u9&r#kkKQ5yTp~#rKNU zeVc0{Je}e)K}M9WMy$vhw}*m%Hr>^#&X}(8joA{0d)J^CsA?SK1mgj%WWb~AY21+) zX6aIu2w=+K9%$b(5z#|~gv@w8mQHflqbdkVQV26SQ@ZX-AJG5K zXv@iJcP&!3IVzP<7jtAK;6U-vMr|srKPt|G2FRjvVAya;G3DhcL(H+f#yOasD}kG` zV+V71*}#+zrz2(uv5L#_p<#rflO%HwI++hqTY{L{G5 z$fG-PZ}{VL7&w@OC+~s!K0TFR$LEnKS65{W=4-*(V98akS1A>_(-x>?}|_o2dRLyan{ z#&8U|XZv~Ilkt#IOrRr%ch5On3X0MKR1BKa)kS5gbeQttHJvB;`1k7cvVW^5_w%}N zI9RcY*HTe?VC`2Ir@zcXfWJ$KjWrX?f}`PUGy6-&o*5x|2TgJuWC%nw(S(GDzI2n# zo&^^Z29dja+4FUwkw?k>28SeO>fw@NDJ3JZ1uq&MH39@|Y9&Gwaq8Mj0iR2RO#++w zCsF={+rp1`fN_GqjPKuN97K8@pVPa`oGBYkmlUx!8=(XOweq#esVTSTg)c#e_Wt#- z^K}rBaxzT$k3+XB!NA44hg5Yfed||H_F4<5_GF}%#A$BRn(VF=_c<0n^%+V_1(^h_ z{>H(laH*BbJqkd4nnW|=j}v!m*zrbHme+Zc)Bt-R zEp$4T+```_<;3N)wSTUnMUnaCkQDMJ!H{Qqkye;Nw~BIkR>F)b9m;xrX>1WF4WvY? z>z&2+#it+kdnjIL;Jf+!-0Ylev!C+r9kVoGrnE^{*_|6r0d#iLP0Qqpl;{%#DW2^3Y=*Pd zRplXwe|rp;y+0^~@+ zJBUEQ7f{UB1#)!^)NXPN@m3#*@bV6Wl`Xou)b>n_r{|hPQaHnFCh#aEP{ewlDF3UZ zj@W)6tl5M-Aex51>t!x&G-ynsMehHyv;*BgD6BAS`{KFdleMqQZDbuw=Ls#P1~&jc z99+fjJ3eAS1Y{YC3c(rZS|K!YRyF(uAM+v}K;R@?pWx# z?6z^wT)|Hqy8Cfw==V}>tU#F*CgZKb%Lt#}g?PPIU9 zFB-QJkC@L0Nb0S(u8)6>)2@7?#;X;MG^UE@>WI8`+U+DWl#Vlh&jlH3%%n01@p#>N~vclj}kB96f$2-J% zj(qAev}h)JX!7oHmMyELmRJD+UG3}roO~G8w#qlSz%h?rn|B`tavWTFbjz&6g`|ZZ zQw>FC-A2UAY|0e7ICS5?l{YGt%)F4Y)sH?T=A9^k`5YHkHhcsSUu7G19d!EZZdtAD zWs($27Jl(18gX+?-4u%nPjV6ct+m=+0K3tev=+d%V!$nPT%6S=TDyvdaH%S1`24v; zL0=p6djAfaZu$S=CdG|Sv6`xP*p_~OU| zj}@3m*`+d%cE4xfxN>aKG(!Rj79}>^J86t4d!~B@!ULi?OBH-auWOS4|Yy3ujCBq&6N;0EiY;_JgHR`?DvSeO2Uvec5=uf3b4LE7{ec3R|oiR{q z``Wiukc+tW5U=kQ|6KrxBCVeKm*OBJis~tLW&-Whl9CeO?x|jR_v?p|_eS$6z2~Q@ zMW>$g=TtpsJv*NDZ=sD=39LHzn?Y7Wfd^RU9+k>q;UK5I9>aRQ8iPNX$yR}!FLtlO zi4;Lj|1G)?|8|&}YBa3BTV^Gh?g(4}-R~EXsyHyuU6?i4a_I8i|2Pfy@Vj1X%4Q%$ z`p7|67}|(mAfPYaG}PdCCy+zswh@6QfuvH)_pggp<%$CtR_PIX^;ymZEKKz)Y=F%> z%3~%?nFd;xPR?x=2p0&WILeIRirUhXr*ok_E*+D}dk?EKR#2-=P<8_hpc1_m4uC{q zg}fvnNr-P;AR)mwS+vu5rdw)#G-Q0*PEaa@qE8}`IayP0N2;<~`V^)=5-EkhU2m+el( z%zG0TF>ZAlD#fZr79Q>2JtCp&qQ3@JRjMvuMcq+mKubNsn`p6CsiTRtSn5_^52mN$ zFhQh5&TeQ^7?`jn{^)4U9d|>mqhMeA=fqrmWAvED)9=IUI>TSUN%i0ak3e zB`)y*K^i*Z#LcIChlW!2;9`ZWni)*hs))hzfX_0T%iSN9>A;$tq{ao6=67$uQr>M} z;QvJ{{iE^+c=CcAHYolQp@Q_Elc>55dunsDhFRdPRj@d6Fl-!I7FhB0_cPG-KR`ZA z@Ww{$q(+s;Sr(&}mH>Fra3;;~90{q6C?+Pk^MQc$&{$p#b^Jk&3py|`7Ne0jD@>rk zu!t?sbOsP$T-hbdpUC;{(BfrR242$Q9HlM9CLGDnNDXAzJkr~c7Y|h;m#e?DSRt_D zu_62AI+KblM|Yi-^?XxJ-6xw>fewqN)ZT|}bt;*@>ZQ1I=1xS0B_~M4ppR;Zf6d8` zKl{N-km|)Lcv2%yS&f(vrT3Y&*zvluSTvnD{P_Xa6`S@#f@89%s^Fwh^ z2UgDod6!vMLb(E0@p&?dtdCvGz`XrV)f&H3qLQH`)RJ6Cd#hfDNtqA3|LXnWer~Ov za&_2fx1Az^ZmWiy7e=Y?!J;#{SkJ(&!Vb$^q090c0PIy%(u{)O_(uw5vk>kc{>>FF zMw93N&fi(2!VEn5#MZ z`Fs_pl&Fk``~Zfs2vGF|7XG#qPZ0`(%A7(M!KcDavEVaAnqp$ge6t1L^nfGJ&T4*n zrPOS;-0##VJAv{*2|l*q*nun9C{4XCLWxI}-8SN4EEWZZOitZjW1?N8XMU(KApbgH z(5UChK(yT(Mvf6H)L~fS*kQS2R;&uW01lXOUak9yDHEw0{X0B;8C|%}$e&U?M1vg5 z%lUhKN<`Yp=Tds%Vhx6)7jQXf(reTZW<2yv^U4?kIWuw}6RqJ3cvaQRm85viFI@Fq zZVtsZntH71haKM33*0g$41r=m55k74#ql7Oe$-WtM)o+;)<~9P? zQV)pe-ZT_lP0>#op^Rz0`#3g_o=b0>vlotg&n;Dh6=Dqq+qM76kzl&XIdN@vzA7nU zCN(bqStpD(_}>|RtWgQkug=EIY1Hebyx4?tnZdsm+2mtU3PFP7L3inH1%*s*wl(AS z8{mkkjBTDyS?GFO1#UBb^cQD*N{zXjAh9OqXQ#!`*qE22+TMcAmy=D=gFUg@>#`Cw z?~!OJJO$;E!fik6 zm{3W>*|zO-*14vmAd3#GIb>2zHVtMN3?>PC36Q6&88hUc4K8My)Mbf@P}F6PnY(<) zq)ecS6!M={H>XGrI5sfhC7Ti}Ef+&oIo-#v<7ssdKoBVmBztJ|4LVtHmt4EQxsd69 zPN6{?q}3VUflrEtXelR(BiUyRx=%@H4=j)Gw9B+9z7ok4t!ufmmmz_rT^HHfBcWT$m7Hm zv6~G0!-o%Z8b)0WTGS@3_v5Ij>)xIeonH~&W0u9x8Fd@6>{gN%R03S6jTJ(5qd_lW z9cF|AdaMSOAk~=YfKUfnE+CpNTOY063>KcVYPN*9JSQwRE8Zbmj|T*tA$Xw~KX?$1 zjR56Z-XuTaWY`B&<>Yox2Y$eO5o5;NJ_Z>5HJqGR}O_o*D{}o_MT#$zJ5gx(FuhxZOfbC8))Kb*#Nx-+w2fS(BY0Th@*@r3JLPtk z^E;4^ue9};f=MxkRu}zV0gQv9kj?x)qz;Ev#*mMUqI0i1$g%jxegWKjGQp;ZzHH-f zI|!zJan>bBB;(-7?K@jYoOsg*s9DKTyNhl8y!X)4 zk^44M$l`coajHiX{-sxze!A^+L&%S4vg;oIL5**OY|Y>2X^1K4^R|q}VESi`{{*NwerbIJa*Ud5RQ7k813{dg{ zk@MR%aG{_-sxln;-^y#wQ=_SXP&*BqUcz95f(C^BjnbnSxV};Xf@=uXwhu7xzKhJv zxI5Kk+%0DKO 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

~zlgbng2ugIu0GERjB@a4 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±4EdLkzD}LY+j$)!S3Q?< zl=6p4@}2Q7xvhg&+3jzD__ z|Er232A#j#*>G;Y)%zkIvH$hc0*b9hn&7|=K~^muMXgUuXD_9jkJRsWQ{h^L5pX12 zF+pRLVc++6te&_(Af00KFKq6J6WtCYLRVCMDUYkjkyzQCND=kgOyZNpU{`_eWIBhG zz^d!fZ`+vi+nDi>yPgh$BSMoBs9`Utj)Log1ubSMVRsp}d{-*_{l7O^IB$aagQB_dw3OJ%IwF(AloSuB zqG4iY7Sh$7b7)>;l=l<3y-qFZJECRv`)T zQ}RY=uFpjhSuHWp)hNOk7mUR_V{`jC2I6PY^df&VTVjSz)_xbf^vq592lvB5LC|+{ zFVu;Tf!|odUaKkjp$1v4j7RPd2EQQ zS$U)$i{jhUfc|3d*yxtYUK}=#U)@%6p?*^y+q1Vb>5~cQOL;k7R^Pz6#v;AOl@k6o zzPskeRBfqKs;7cT@q)Z$J*}|*(Cd4aPv06+Es`dcc(BAMaJDu4h0liCf_k3_7(ZuEF0`EWEo}OY&si@<85OxQjhHbyfVv6QY*a>m=&+Wn* zyWRS{iU&;!)mmo?E{U4sVmIZbA16%&<@uG_$K|0DI^knC2W$>yjM+F-Qdj!b z?4o+q2CBzWg$9|~jk>H>;t0~gUHVped6S9aM~Zeb(A$2j*6l2+?;pO$#tsk zf^8B(Gi%S{pZkAaa+jd_ilXv_P@zw~9=vf!9lHZv812D?r5kBfZ=#z{&DXMv$Bf@P z(FxMu2S;8Ioc>87A>kUbQgK_r6`!>BkG7Bm+{eOf|9#Cem;?co9S;lf9WI zBq4~Jsb#G#@HMKt5l&4K2TFgxK92NGJ8Pu6XGkB{pwwm_Q7bP~2di&@c~C)GuAbiq z2bEWmXZD((Xyj-pPRq#Xs0jJJH^tCS0QiV{y^Yt~-yn3KGWyvQk$dgl6V8!&$>`|A z?Zd#05{WKnrk02L1UOx|Y6q7HjtUAk5Mx=B@w)X)=`VS)^$Qhi{Z-}8t79lRzH4GX zG=x+R%vs$vDZbghO~ET5)b(1?K612B>q=699H-zfy_RaMgauynnBK%EgZ!37oS5WB zs4oL)4-qivjhB8gS@TPtr8<6&yusoAbx)ko0c|^j$Qd`vl4P)^UH)K(^_u!co|mPv zD|kKq$gg%=K=Ylpp-Xy32gl5ZPX#*by&)@af%li z!I13|bOul!+qOk<_rVZL{jt-M@vm`hR4J{)2BG8b8Vo=B%4_k#LVawJf=_EP?5gvA zn_XFFkmSaXbbmX~qV@Uq9NJC$x+QeQNU^e6w~p;Mrg7y#m?H<2U<~|e1duX7PdDAx z__Hel`xlU_8%W52qNL%-HZn4T6cBF_Zu1y>E_uZ3Th6R-!PVjkFA3-3&t#&BD?fW3 zes?$Ar)S@tZJBl*J z!=_apjQrgmq0SKRsZJX04tR)TF*23o@yDbkdLxPTW9^s%qvlJ>#`r1MrMPPjj@|u| z>J>kTz9U^KF|X&{owlU&)zPyRe0o>sxrJlh(xIe9#$$bjNdAzwA0j_5;dtj=bI*9> z&nwXSs?8uJW#-S?`_$p-xH!(IwHpf$ll5J1-ZUG>uPF1PGy8rptQe5{?UYjB-ZI3T6c9th8(n?7Icc z5sUYc9b_2-mIo>g2Y#ASz>U5U$;)w2GX$fEod&7*@ zAWOQH{m)BW+OGJO`&LJ{yYNt3$SJ*Wp5xr4#m`{Bsu+DwanUfoywxle&^YW?IZU`MS{${rf43#ckm~y|K6hFLujpFG5T8>6HKUAQV=T!y|8YOvGPy34V7cql*;uoN{ALW_WEVU)|02{*~b~hK!mm zIk#ZnuRONTUG;13i&8JGX0CbcFSvdbbs+fG&gT23ZuVh@mqOG93;}K1)K;&gEYO=Z z0UjZ$uX=}ff4qH4mtoPc`C{~Y!7mnYm3m{_~VqmztqSlA1{TCDAA5;IJDSq#})|7<-?LlfYUoz=b4Sdd76 zE7^TXEI5jRzd?C4bh6A39jlTN!ec$D^3B!8oF^NHeqVqJsxVmnaE7hc1;Re1d*#zY zx@^l-dLfdo_he}U*@n;^s^1up)DzNf5GuPSAh&W4jPe#!B|*owki1p&!tki&)I*dZ zW;@Mq($2*n<;)z9*v9iZD%MR!TPDdq>xhxUrg6JAeH%AR9~Fmn`-?XB z$0afJVvJ$(iqf&z+=zGkwt^yqUR|Fq;;BwIhJyzNQSxzXpRaJ-)cm^ zr@13ez4~EE1!t%=8(?Pg* z`gFgo%0Im_9YkfKI#5UCFPE8S@_VAATs}CGUqzyx75xQHXO|4lWH3n<@thx7UI|4t z0~(znQL6b)B&K@?X&br{0SyN&hkDuiX9oAc%%#T82&r{}Qqhn5d)CoR8R3P_bWU^y z=@dL&Y6rFv(5`KTz#9EUzre!ZgcH4NeF(K#kD^j8R1kFWg=uvn^<-0iV!EfbIB}m# z#GH#8Y)29n#1t~T$|pG8aT!V#ue0I^-wAvCMB6aPRg<{)a&Pw(c~AR~eIY?$DVWen zhT3To=>tRkzAnVqwq!`EQLz5%)@(LgXrvO4M0+USuVDyKIG#q+~i zJ1l+8yHX~u94DFt_K*;mi{IdI?TD;@T->l*b-e`l%IiY?n{=i>z8u;3=BD#WiCLGt z$|l>pXX}*Nnm8pi%!n_bK=W&ZqFrd1{C77Wu~N!Qqshx&Pit@ZbcG5g;y|2yrtLz; z%hQ;?iyp(U@Q3Gxg&q9u>sp<%*??RO=1{@k-75L>{Ywvf=^OKOhc!Dl?6lW#qF&(4 z8^Poi95#lU9g15oRO`pur?^gFkwAmp*U2r}>c8VwGx5&&SOKQQar?2btly9Gn9T2$sgiIs<@o$!X=sTkEf8HoBQ$JKdqjY*$RP(EjPC`s#&uU3Z1kq{0MLCGGRq`ZW9iIoF%Enx07p^ChDA zbdnU={aQra+yESdHo6tu)!`zBOfGii`qkEYKjjTiUW8R%z(C*Oq&Q|v>G*+ z9=bM`=9HBo$*|8q`h!s{;iiBQVOoho)W`F?;x!jp4cd{))AckN$9KJ0$Q{7wzIXx6 z#Y@kJFD(@Z5GGjplY0?e&!SIW&=(IZw1j^7Vq!7@D`3h(g>WRDG37*$YsP03CCDod zvJD6|;~CL0L%ER-7hShr6**-A}^|6-Gyov8jWYZ5|wt^TxMD%fz znQcf+w9%Jtt9P0;ro|1Dp_BuzAKmM|MN4%ugQa||1Qsxcz% zeZ(@HuDOX*k;Hje`v*yd!~5Jy_9LQ!gw4)=$JK}8K}DH#fnk@+sGFl!In44xY%r|^ zjnU*DDMBEo?D^LB+oR&?Tl|nYZ9c4mTH5IXNj-KWf~bSx;v#@Jtoh_#=${$^(lzUWqW+CVpFHLZ(VKnj77RHmG08A{=#C`c0CJbEx; zLDIv#!q0fWl@V(Gv(QIefBC(Ok%F#i`g-rZ{1zVb%54Y@lFKQm#Tj+%QyPjD6?A^qJ>%Os+l@Td_bPaXB5bY z@rnF52HPRkQs%;++%gKsno~CNufYjG)_%MSJ3E0#H7OVW zQiNS|9PK&>=ldSACQpOxKFHqqL_Ol;c&VjhkG7<9p@58T*QakGDmCGQxBaVrmI>K+ z`}2CP0bUk9m^)Nar}gZtk5oDv54i~4TI$-_dTr*E`$7`B*J;^M%g9ehW`o{Fzr3G& zDxRCNwjQ@k^4@0l^T)(pB&fg95zTc1o>>#}q+(_KV_YZh7Y+)XRXLW-%ela}LRV6xv$Jyuqi+K0Fg zhL{zGzqpf4E_n$Jep|d0JikQf@2gYEfPW~N1vUK)?A+g;l53ho(uGm7Akq8|fCMoA)!4_YCEye1-)c-aMH5YR$pjL%bmA{{FS2JlZl3yG_YdvdK*<8^)7TD$Zglv8V#d8_4L;;C>t-K^8vOH zJ+H;=_Sr(*DQ(W(L(`WS)#^&RS|v;r4-0fkbQ>wP&!F`$ZYDtWka$|(}m6#txL^cWWp7O zKU8dRkBxEtPMp%x<30$M{&92M&5KV9Q{E~rI6F6wqDhb9Tct@LHCE^V#{xF(cS~Of z=8tGTeQJinT6V7@-_&^#8D72_F>#)rWv_)6KEQcB__j=`KA&d_5W*f+otVQ%`>Q zk!{Y8(gNjdRbxge858PStI$OqP)H+Xb1~M^VReA%qK{-BAxY$cB$H8Y1&_?g4L$Kl z{1W!tWn{osFErPA$Jt;i_V*9{PLjA`t638~)rGEZ*sAz+Ncnx)qlvWBTbhZ=!4iMe zM)GSwwo66d@d~IXJe2>%`7t_;+)KW4@`N}77fCyKx=s8vKOEcevx#n(hWdTM($g_0ARm-6h8Z_zRMDJar|p&p2p}yy%5WrD8-XE#S^z>2wppoh84AZOJpVs+od-}8+y2L~TtK8sQ$!R{kRnBj zG(iF=MLJ68&4eyeB1JGDRq9oG9z~QQil72sngUWHy+lQ&Nf$vNf`rchx8QsC&VSz9 z8D<&S$!>Pf**#~^_wzZ-dQCE)csoDe4ybth-p9XvQ6b*S!$y?*_3B9&E0#I;b-JGJ zXn=XV>ofISHhrcmPAj~tx&G)xnVsq?T1veM$R#ZTrWYMY7`e}o0Wh?whGaaFj`!=j zHRSzi`F{pL<=!NP2oZ@)Y!0VV?Z1pNh|pP9)x`L$38FMe61$~rkP_U126`}eOf-ND{*sArrE8kqP)0% zr?2YNo5=#tw4~m6KXE?EuwYyDHomzs)A=epsVw(QYkXJMfyna?zbfQY@_VwhBt9%G z6o{V`n{Dx&ez_M~2*8K;d@N53%@e35x~$~zVUAe(Td!Z9?q+Y27Ktt$4wAve9lW); z;q~CH-{4qJknz%FA`CVerG%&ql5C6S&KkHJ64vNFTk*VL;xR_I>1{3~;HnlkHtN_M za0!CzI?z+;*f@4fw}Ht&;IVe)w8IfDPM;}93oj(N9QB7SJWnGb&YFQ+b3C}_xD&ws zRqVT`8^}X}L_0sfGys~%)&d(67B8E51uwo=?(dO?~l# zJ}%78_K2sJnr@%g(XZ6eCybQN89DZ824TgxNc!wPnPtz2w+zMeDfA|mJfCE!gU7;h zbsVI!t-cUOO;i5jkup#u1oncvr@pEj z%ySQoNiBQne&YJgWm1r_&lD?+{3OURU33vsOBT>>+B_}0Jg&bozmouSOp#B7(bh>I zyB&aGjC5D&2|jM?;u38+*Yq=fH#R%QxTX_-DQ|?7sqfV=6Ocf=l8}GOnY@O1wlP0< zAa}

z-oWoCw_ZOkidz}y5|fm94V|!;(})4h_g$TbbiM}OBBH-a{_Mf=R{o{DCoExZSRkZ zRB2}Kg05epo^d);gyi*JJZR^d*qoc+5~E?_8Mhc-<3J+E9{BbC)rClvc1RVHqiICg z=wN>4^lXu2x+Z&;G{sC>TbFtnhL<$=-P zqM=(C1%tvl(NPbBPf!V-D83jLQLJ>IE`U6(yI1Rk$6lF*oU>=O!i^jDW6f_*1l!U* zk+2RY8%sC0z22a_Fd(9xu<(WA-s zDUe7(mcBiA!sO`(d0zzyi8>JX5CO66V#2Sexs-DuDSQNQM1q0fgF}o%2|=?C#Me=r zb=_%&ucXWu{h%`r-Q9LV=o~eR{;as9xwmTH;X-Lup&^_W6FlhikB?lU)9KUfr*4Xk zi)cPLhFcThD*AD@B2eQfWJW@~63JC~w0CiQEQ~EeV2y{1YdS1`CS09PI4=0-<)aqt z!yk}nMYMBFE=JPYS15N3Yl@6YGovyX;W4mInV&jnv$7Ylvp{yO2H1^>lCAG0aLjEP zitf@}kRd0h{8jTuFx*u4cybQ^|A=Q>&1mfQ4&UntK!|imF0=1aFS*--6X7ip}n>3ks`?P z`zz7GSK3}++O7lpn-*lkD7WV+h>ZiVlSxEL7UGaPYYAE{!|Ij25T;yvj%T7OjO^?;PD2@O_`Ee~y>y zNkxssoP^~sbW*vqR{F`y{CfL-^22Gk_atU4yhs>(xVQ=$JRdhPSJ{l=fzd-a>!|QB zg=-HDBr3j_Fbium%dX(3%I@70E7&>uQE7tIYa-6-&1#1S&x_6Eq**1iwixHN=I<~| zEV-&{Iftt+V^}Nih=eue#s-y*X<4587b%W2TK`(lI)*8l>%E}{Nt~-?U4vIlNTXaU ztGP{Yv?8mHc27}Dl_GGXd zWiksCY#$ZX!4F#MswSk7C5AS0dAwoDCTY;?nE1nyNYebdZ=Hf@bIl&U3CW!dbfZ$b z%ugkAnM~9E`>5#hLHV1ESDedzW^-HMrEdB?uCCbkRJ0Au4TqsUsxKBY6E4S)4O?;i zmG$Y4nH9;Y3ti?|lEQ@96OrP>3Q_Dh&8Z}zUpGNjiPz-sC1?i>G?$81XQu7t1# zd*+j7#VHJVz4m3;mQm=BP4;CyITJ2rLP?K>=8K1E*oM)K15*n-j!9b2S7y&uw|QeM zj3fV8_7quTFBy&9Ir1>MQqhX=T{$8uij{xYmjIb_`QL$ zw-zzwKU&1nzqN=HzYPw|qoThR4FBsRuMdT80gUGja@wCT@Y_!5-nkyA8i5Yi9eV(X z4q`E81As>bjvTZ}>l)cj#rx?J`W|c}j}^p&0&Myu@~lM^I(COUr`UGCoL@(J-vd0H ze1ufm_uxN_P@vw<@I5N3FTElF z_?19U7Wo&l(%8Tj7Z}j0<&`zBx^H$ArrT_Si**=HRm$3zKy%(6ySTtA=3l;qI z2QvOn*Sq%CVu_gTPp+`9BzhS|7r7NJ`DZGLEFxB%LmEO{-qucmb3 zR;pxYkt7G<-@n28IO)8kfO5gz+7TufGTufz4zv|!in{m$J-(Q|tz@(QrH|?zwiK`ty70X~foyIq{&HIL|TFX;ohf*=6;fupQWgykn4+vTXvP?An( zXt?UmdLM76Qc2;1ZKPHsKfu9>tAGFzrqs2wx3`~EK_Rwb@S&zVOR31nXo#i$Yc)_g z+tJ>BG->VZQVEb(IoVyQMA)3w-l{x>_u{{TNWvM*9m@3m=T4IPar{Xa_60I=}h@aOzPxz1#hs+~6S4 zF;A6@FfP!OR95bsCKdRvEeV;HSYw==oO)*nkMHsftMkEpIS7DK0E{PB8KI;!8U+0a|~#+yJ+fQHWi?c`8ZRV@uYibRuJwgR<(y%^0Y=FK5t;@c0=d39K z8rN2ljqcuM0j)fvvhwmxa#efcmA)?6$JTd3yM%vGgY-@%mEQLA?1k+>hjF@Y)JPr#YW^9K`%K4dIKLE z4m6I8Ags73%E1qE5a@-#s~l~sd`&|k8ot($s0~8IZB78ecl|sU@OTxNj`Uio8Q>k@ z0jlvM-x(UR_NwI0F^F=Kj>ee9#>ab6=B%t=2Wa4MG61iDNrP%`pt7MMk_l{Z0*NgW zkhQe1u(+$pzUl!x@H)X)Yuk7QlocLS#ugT?RNgBKb`G(Ug(j^lfy#)o2Ift$RpLpw ztIjtGDvQa+yR7-e#hpNCbprLiFU?QsdaUH+yLvcAoPA>QIcaA>~5Ns)_B+#Uc0%=d9IjG8>N zA)|WkpGGq%o`iz0JugMw`X|X_L~g~Kv0!Ikv}1eygbn3;C}ClFM{k9EI)-w5JFkaMf^v52+_ z<0|=Ev zXyZiOV1O>QOn8BEx)h*T@G`&+RmkoVA8WzRXZ{SmKF*GmTu*tcA%3J#|6O$T)M}B! n9o6RijdOPshD~G(J~7HMN&at9WptE0Dp<5M^wf({ws-yy^uXaL literal 0 HcmV?d00001 diff --git a/examples/compiled/config_numberFormatType_test.svg b/examples/compiled/config_numberFormatType_test.svg new file mode 100644 index 0000000000..5835ebfce4 --- /dev/null +++ b/examples/compiled/config_numberFormatType_test.svg @@ -0,0 +1 @@ +Weight_in_lbs (binned)01020304050Miles_per_Gallon01020304050Miles_per_Gallon197019721974197619781980Year197019721974197619781980Year197019721974197619781980Year1000 – 20002000 – 30003000 – 40004000 – 50005000 – 6000824.8Acceleration100200300400Displacement (binned) \ No newline at end of file diff --git a/examples/compiled/config_numberFormatType_test.vg.json b/examples/compiled/config_numberFormatType_test.vg.json new file mode 100644 index 0000000000..0d33c1e9b3 --- /dev/null +++ b/examples/compiled/config_numberFormatType_test.vg.json @@ -0,0 +1,293 @@ +{ + "$schema": "https://vega.github.io/schema/vega/v5.json", + "description": "Testing global number formatting config", + "background": "white", + "padding": 5, + "data": [ + { + "name": "source_0", + "url": "data/cars.json", + "format": {"type": "json", "parse": {"Year": "date"}}, + "transform": [ + { + "type": "extent", + "field": "Weight_in_lbs", + "signal": "bin_maxbins_4_Weight_in_lbs_extent" + }, + { + "type": "bin", + "field": "Weight_in_lbs", + "as": [ + "bin_maxbins_4_Weight_in_lbs", + "bin_maxbins_4_Weight_in_lbs_end" + ], + "signal": "bin_maxbins_4_Weight_in_lbs_bins", + "extent": {"signal": "bin_maxbins_4_Weight_in_lbs_extent"}, + "maxbins": 4 + }, + { + "type": "extent", + "field": "Displacement", + "signal": "child_bin_maxbins_6_Displacement_extent" + }, + { + "type": "bin", + "field": "Displacement", + "as": [ + "bin_maxbins_6_Displacement", + "bin_maxbins_6_Displacement_end" + ], + "signal": "child_bin_maxbins_6_Displacement_bins", + "extent": {"signal": "child_bin_maxbins_6_Displacement_extent"}, + "maxbins": 6 + }, + { + "type": "filter", + "expr": "(isDate(datum[\"Year\"]) || (isValid(datum[\"Year\"]) && isFinite(+datum[\"Year\"]))) && isValid(datum[\"Miles_per_Gallon\"]) && isFinite(+datum[\"Miles_per_Gallon\"]) && isValid(datum[\"Acceleration\"]) && isFinite(+datum[\"Acceleration\"]) && isValid(datum[\"bin_maxbins_6_Displacement\"]) && isFinite(+datum[\"bin_maxbins_6_Displacement\"])" + } + ] + }, + { + "name": "facet_domain", + "source": "source_0", + "transform": [ + { + "type": "aggregate", + "groupby": [ + "bin_maxbins_4_Weight_in_lbs", + "bin_maxbins_4_Weight_in_lbs_end" + ] + } + ] + }, + { + "name": "facet_domain_row", + "transform": [ + { + "type": "sequence", + "start": 0, + "stop": {"signal": "ceil(length(data(\"facet_domain\")) / 3)"} + } + ] + }, + { + "name": "facet_domain_column", + "transform": [ + { + "type": "sequence", + "start": 0, + "stop": {"signal": "min(length(data(\"facet_domain\")), 3)"} + } + ] + } + ], + "signals": [ + {"name": "child_width", "value": 150}, + {"name": "child_height", "value": 150} + ], + "layout": {"padding": 20, "bounds": "full", "align": "all", "columns": 3}, + "marks": [ + { + "name": "facet-title", + "type": "group", + "role": "column-title", + "title": { + "text": "Weight_in_lbs (binned)", + "style": "guide-title", + "offset": 10 + } + }, + { + "name": "row_header", + "type": "group", + "role": "row-header", + "from": {"data": "facet_domain_row"}, + "encode": {"update": {"height": {"signal": "child_height"}}}, + "axes": [ + { + "scale": "y", + "orient": "left", + "grid": false, + "title": "Miles_per_Gallon", + "labelOverlap": true, + "tickCount": {"signal": "ceil(child_height/40)"}, + "encode": { + "labels": { + "update": {"text": {"signal": "pow(datum.value, \"1.0\")"}} + } + }, + "zindex": 0 + } + ] + }, + { + "name": "column_footer", + "type": "group", + "role": "column-footer", + "from": {"data": "facet_domain_column"}, + "encode": {"update": {"width": {"signal": "child_width"}}}, + "axes": [ + { + "scale": "x", + "orient": "bottom", + "grid": false, + "title": "Year", + "labelFlush": true, + "labelOverlap": true, + "tickCount": {"signal": "ceil(child_width/40)"}, + "zindex": 0 + } + ] + }, + { + "name": "cell", + "type": "group", + "title": { + "text": { + "signal": "!isValid(parent[\"bin_maxbins_4_Weight_in_lbs\"]) || !isFinite(+parent[\"bin_maxbins_4_Weight_in_lbs\"]) ? \"null\" : pow(parent[\"bin_maxbins_4_Weight_in_lbs\"], \"1.0\") + \" – \" + pow(parent[\"bin_maxbins_4_Weight_in_lbs_end\"], \"1.0\")" + }, + "style": "guide-label", + "frame": "group", + "offset": 10 + }, + "style": "cell", + "from": { + "facet": { + "name": "facet", + "data": "source_0", + "groupby": [ + "bin_maxbins_4_Weight_in_lbs", + "bin_maxbins_4_Weight_in_lbs_end" + ] + } + }, + "sort": { + "field": ["datum[\"bin_maxbins_4_Weight_in_lbs\"]"], + "order": ["ascending"] + }, + "encode": { + "update": { + "width": {"signal": "child_width"}, + "height": {"signal": "child_height"} + } + }, + "marks": [ + { + "name": "child_marks", + "type": "symbol", + "style": ["point"], + "from": {"data": "facet"}, + "encode": { + "update": { + "opacity": {"value": 0.7}, + "tooltip": { + "signal": "{\"Year\": timeFormat(datum[\"Year\"], '%b %d, %Y'), \"Miles_per_Gallon\": pow(datum[\"Miles_per_Gallon\"], \"1.0\"), \"Acceleration\": pow(datum[\"Acceleration\"], \"1.0\"), \"Displacement (binned)\": !isValid(datum[\"bin_maxbins_6_Displacement\"]) || !isFinite(+datum[\"bin_maxbins_6_Displacement\"]) ? \"null\" : pow(datum[\"bin_maxbins_6_Displacement\"], \"1.0\") + \" – \" + pow(datum[\"bin_maxbins_6_Displacement_end\"], \"1.0\")}" + }, + "fill": {"value": "transparent"}, + "stroke": {"scale": "color", "field": "Acceleration"}, + "ariaRoleDescription": {"value": "point"}, + "description": { + "signal": "\"Year: \" + (timeFormat(datum[\"Year\"], '%b %d, %Y')) + \"; Miles_per_Gallon: \" + (pow(datum[\"Miles_per_Gallon\"], \"1.0\")) + \"; Acceleration: \" + (pow(datum[\"Acceleration\"], \"1.0\")) + \"; Displacement (binned): \" + (!isValid(datum[\"bin_maxbins_6_Displacement\"]) || !isFinite(+datum[\"bin_maxbins_6_Displacement\"]) ? \"null\" : pow(datum[\"bin_maxbins_6_Displacement\"], \"1.0\") + \" – \" + pow(datum[\"bin_maxbins_6_Displacement_end\"], \"1.0\"))" + }, + "x": {"scale": "x", "field": "Year"}, + "y": {"scale": "y", "field": "Miles_per_Gallon"}, + "size": { + "signal": "scale(\"size\", 0.5 * datum[\"bin_maxbins_6_Displacement\"] + 0.5 * datum[\"bin_maxbins_6_Displacement_end\"])" + } + } + } + } + ], + "axes": [ + { + "scale": "x", + "orient": "bottom", + "gridScale": "y", + "grid": true, + "tickCount": {"signal": "ceil(child_width/40)"}, + "domain": false, + "labels": false, + "aria": false, + "maxExtent": 0, + "minExtent": 0, + "ticks": false, + "zindex": 0 + }, + { + "scale": "y", + "orient": "left", + "gridScale": "x", + "grid": true, + "tickCount": {"signal": "ceil(child_height/40)"}, + "domain": false, + "labels": false, + "aria": false, + "maxExtent": 0, + "minExtent": 0, + "ticks": false, + "zindex": 0 + } + ] + } + ], + "scales": [ + { + "name": "x", + "type": "time", + "domain": {"data": "source_0", "field": "Year"}, + "range": [0, {"signal": "child_width"}] + }, + { + "name": "y", + "type": "linear", + "domain": {"data": "source_0", "field": "Miles_per_Gallon"}, + "range": [{"signal": "child_height"}, 0], + "nice": true, + "zero": true + }, + { + "name": "color", + "type": "linear", + "domain": {"data": "source_0", "field": "Acceleration"}, + "range": "ramp", + "interpolate": "hcl", + "zero": false + }, + { + "name": "size", + "type": "linear", + "domain": { + "signal": "[child_bin_maxbins_6_Displacement_bins.start, child_bin_maxbins_6_Displacement_bins.stop]" + }, + "range": [0, 361], + "bins": {"signal": "child_bin_maxbins_6_Displacement_bins"}, + "zero": true + } + ], + "legends": [ + { + "stroke": "color", + "gradientLength": {"signal": "clamp(child_height, 64, 200)"}, + "title": "Acceleration", + "encode": { + "labels": {"update": {"text": {"signal": "pow(datum.value, \"1.0\")"}}}, + "gradient": {"update": {"opacity": {"value": 0.7}}} + } + }, + { + "size": "size", + "symbolType": "circle", + "title": "Displacement (binned)", + "encode": { + "labels": {"update": {"text": {"signal": "pow(datum.value, \"1.0\")"}}}, + "symbols": { + "update": { + "fill": {"value": "transparent"}, + "opacity": {"value": 0.7} + } + } + } + } + ], + "config": {"customFormatTypes": true} +} diff --git a/examples/specs/config_numberFormatType_test.vl.json b/examples/specs/config_numberFormatType_test.vl.json new file mode 100644 index 0000000000..420f64f903 --- /dev/null +++ b/examples/specs/config_numberFormatType_test.vl.json @@ -0,0 +1,20 @@ +{ + "$schema": "https://vega.github.io/schema/vega-lite/v5.json", + "description": "Testing global number formatting config", + "width": 150, + "height": 150, + "data": {"url": "data/cars.json"}, + "mark": {"type": "point", "tooltip": true}, + "encoding": { + "x": {"field": "Year", "type": "temporal"}, + "y": {"field": "Miles_per_Gallon", "type": "quantitative"}, + "color": {"field": "Acceleration", "type": "quantitative"}, + "size": {"bin": true, "field": "Displacement", "type": "quantitative"}, + "facet": {"bin": {"maxbins": 4}, "field": "Weight_in_lbs", "columns": 3} + }, + "config": { + "numberFormat": "1.0", + "numberFormatType": "pow", + "customFormatTypes": true + } +} diff --git a/examples/specs/normalized/config_numberFormatType_test_normalized.vl.json b/examples/specs/normalized/config_numberFormatType_test_normalized.vl.json new file mode 100644 index 0000000000..ce96547025 --- /dev/null +++ b/examples/specs/normalized/config_numberFormatType_test_normalized.vl.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://vega.github.io/schema/vega-lite/v5.json", + "description": "Testing global number formatting config", + "data": {"url": "data/cars.json"}, + "config": { + "numberFormat": "1.0", + "numberFormatType": "pow", + "customFormatTypes": true + }, + "columns": 3, + "facet": {"bin": {"maxbins": 4}, "field": "Weight_in_lbs"}, + "spec": { + "width": 150, + "height": 150, + "mark": {"type": "point", "tooltip": true}, + "encoding": { + "x": {"field": "Year", "type": "temporal"}, + "y": {"field": "Miles_per_Gallon", "type": "quantitative"}, + "color": {"field": "Acceleration", "type": "quantitative"}, + "size": {"bin": true, "field": "Displacement", "type": "quantitative"} + } + } +} \ No newline at end of file diff --git a/site/_includes/docs_toc.md b/site/_includes/docs_toc.md index 8902f79e9c..a71657fc06 100644 --- a/site/_includes/docs_toc.md +++ b/site/_includes/docs_toc.md @@ -287,7 +287,6 @@ - [Nominal]({{site.baseurl}}/docs/type.html#nominal) - [GeoJSON]({{site.baseurl}}/docs/type.html#geojson) - [Value]({{site.baseurl}}/docs/value.html) - - [Examples]({{site.baseurl}}/docs/value.html#examples) - [Projection]({{site.baseurl}}/docs/projection.html) - [Documentation Overview]({{site.baseurl}}/docs/projection.html#documentation-overview) - [Projection Properties]({{site.baseurl}}/docs/projection.html#projection-properties) @@ -330,7 +329,6 @@ - [Using Parameters]({{site.baseurl}}/docs/parameter.html#using-parameters) - [Selection Configuration]({{site.baseurl}}/docs/parameter.html#config) - [Value]({{site.baseurl}}/docs/value.html) - - [Examples]({{site.baseurl}}/docs/value.html#examples) - [Expr]({{site.baseurl}}/docs/parameter.html) - [Documentation Overview]({{site.baseurl}}/docs/parameter.html#documentation-overview) - [Defining a Parameter]({{site.baseurl}}/docs/parameter.html#defining-a-parameter) diff --git a/site/docs/config.md b/site/docs/config.md index 2dfca0b672..da5ef00302 100644 --- a/site/docs/config.md +++ b/site/docs/config.md @@ -52,7 +52,7 @@ A Vega-Lite `config` object can have the following top-level properties: These two config properties define the default number and time formats for text marks as well as axes, headers, and legends: -{% include table.html props="numberFormat,timeFormat,customFormatTypes" source="Config" %} +{% include table.html props="numberFormat,numberFormatType,timeFormat,customFormatTypes" source="Config" %} {:#custom-format-type} diff --git a/src/compile/axis/encode.ts b/src/compile/axis/encode.ts index f338752250..02be3f3e97 100644 --- a/src/compile/axis/encode.ts +++ b/src/compile/axis/encode.ts @@ -1,5 +1,5 @@ import {getSecondaryRangeChannel, PositionScaleChannel} from '../../channel'; -import {getFieldOrDatumDef} from '../../channeldef'; +import {channelDefType, getFieldOrDatumDef} from '../../channeldef'; import {formatCustomType, isCustomFormatType} from '../format'; import {UnitModel} from '../unit'; @@ -22,6 +22,23 @@ export function labels(model: UnitModel, channel: PositionScaleChannel, specifie }), ...specifiedLabelsSpec }; + } else if ( + format === undefined && + formatType === undefined && + config.customFormatTypes && + config.numberFormatType && + channelDefType(fieldOrDatumDef) === 'quantitative' + ) { + return { + text: formatCustomType({ + fieldOrDatumDef, + field: 'datum.value', + format: config.numberFormat, + formatType: config.numberFormatType, + config + }), + ...specifiedLabelsSpec + }; } return specifiedLabelsSpec; diff --git a/src/compile/format.ts b/src/compile/format.ts index bbc645a37b..3e00554b1d 100644 --- a/src/compile/format.ts +++ b/src/compile/format.ts @@ -56,6 +56,23 @@ export function formatSignalRef({ } const field = fieldToFormat(fieldOrDatumDef, expr, normalizeStack); + const type = channelDefType(fieldOrDatumDef); + + if ( + type === 'quantitative' && + format === undefined && + formatType === undefined && + config.customFormatTypes && + config.numberFormatType + ) { + return formatCustomType({ + fieldOrDatumDef, + format: config.numberFormat, + formatType: config.numberFormatType, + expr, + config + }); + } if (isFieldOrDatumDefForTimeFormat(fieldOrDatumDef)) { const signal = timeFormatExpression( @@ -68,7 +85,7 @@ export function formatSignalRef({ return signal ? {signal} : undefined; } - format = numberFormat(channelDefType(fieldOrDatumDef), format, config); + format = numberFormat(type, format, config); if (isFieldDef(fieldOrDatumDef) && isBinning(fieldOrDatumDef.bin)) { const endField = vgField(fieldOrDatumDef, {expr, binSuffix: 'end'}); return { @@ -121,7 +138,11 @@ export function formatCustomType({ }) { field ??= fieldToFormat(fieldOrDatumDef, expr, normalizeStack); - if (isFieldDef(fieldOrDatumDef) && isBinning(fieldOrDatumDef.bin)) { + if ( + field !== 'datum.value' && // For axis/legend, we can't correctly know the end of the bin from `datum` + isFieldDef(fieldOrDatumDef) && + isBinning(fieldOrDatumDef.bin) + ) { const endField = vgField(fieldOrDatumDef, {expr, binSuffix: 'end'}); return { signal: binFormatExpression(field, endField, format, formatType, config) @@ -140,6 +161,8 @@ export function guideFormat( ) { if (isCustomFormatType(formatType)) { return undefined; // handled in encode block + } else if (format === undefined && formatType === undefined && config.numberFormatType && config.customFormatTypes) { + return undefined; // handled in encode block } if (isFieldOrDatumDefForTimeFormat(fieldOrDatumDef)) { @@ -216,7 +239,11 @@ export function binFormatExpression( format: string | Dict, formatType: string, config: Config -) { +): string { + if (format === undefined && formatType === undefined && config.customFormatTypes && config.numberFormatType) { + return binFormatExpression(startField, endField, config.numberFormat, config.numberFormatType, config); + } + const start = binNumberFormatExpr(startField, format, formatType, config); const end = binNumberFormatExpr(endField, format, formatType, config); return `${fieldValidPredicate(startField, false)} ? "null" : ${start} + "${BIN_RANGE_DELIMITER}" + ${end}`; diff --git a/src/compile/legend/encode.ts b/src/compile/legend/encode.ts index 180d8758e5..7529e71f32 100644 --- a/src/compile/legend/encode.ts +++ b/src/compile/legend/encode.ts @@ -150,15 +150,25 @@ export function labels(specifiedlabelsSpec: any, {fieldOrDatumDef, model, channe const {format, formatType} = legend; - const text = isCustomFormatType(formatType) - ? formatCustomType({ - fieldOrDatumDef, - field: 'datum.value', - format, - formatType, - config - }) - : undefined; + let text = undefined; + + if (isCustomFormatType(formatType)) { + text = formatCustomType({ + fieldOrDatumDef, + field: 'datum.value', + format, + formatType, + config + }); + } else if (format === undefined && formatType === undefined && config.customFormatTypes && config.numberFormatType) { + text = formatCustomType({ + fieldOrDatumDef, + field: 'datum.value', + format: config.numberFormat, + formatType: config.numberFormatType, + config + }); + } const labelsSpec = { ...(opacity ? {opacity} : {}), diff --git a/src/config.ts b/src/config.ts index 66ab07b2a1..b8d4a2ec18 100644 --- a/src/config.ts +++ b/src/config.ts @@ -145,10 +145,23 @@ export interface VLOnlyConfig { fieldTitle?: 'verbal' | 'functional' | 'plain'; /** - * D3 Number format for guide labels and text marks. For example `"s"` for SI units. Use [D3's number format pattern](https://github.com/d3/d3-format#locale_format). + * If numberFormatType is not specified, + * D3 Number format for guide labels and text marks. For example `"s"` for SI units. + * Use [D3's number format pattern](https://github.com/d3/d3-format#locale_format). + * + * If `config.numberFormatType` is specified and `config.customFormatTypes` is `true`, this value will be passed as `format` alongside `datum.value` to the `config.numberFormatType` function. */ numberFormat?: string; + /** + * [Custom format type](https://vega.github.io/vega-lite/docs/config.html#custom-format-type) + * for `config.numberFormat`. + * + * __Default value:__ `undefined` -- This is equilvalent to call D3-format, which is exposed as [`format` in Vega-Expression](https://vega.github.io/vega/docs/expressions/#format). + * __Note:__ You must also set `customFormatTypes` to `true` to use this feature. + */ + numberFormatType?: string; + /** * Default time format for raw time values (without time units) in text marks, legend labels and header labels. * @@ -579,6 +592,7 @@ const VL_ONLY_CONFIG_PROPERTIES: (keyof Config)[] = [ 'facet', 'concat', 'numberFormat', + 'numberFormatType', 'timeFormat', 'countTitle', 'header', diff --git a/test/compile/axis/encode.test.ts b/test/compile/axis/encode.test.ts index e9aeb52e33..dd4786135d 100644 --- a/test/compile/axis/encode.test.ts +++ b/test/compile/axis/encode.test.ts @@ -49,5 +49,17 @@ describe('compile/axis/encode', () => { const labels = encode.labels(model, 'x', {}); expect(labels.text.signal).toBe('customNumberFormat(datum.value)'); }); + + it('applies custom format type from config', () => { + const model = parseUnitModelWithScale({ + mark: 'point', + encoding: { + x: {field: 'a', type: 'quantitative'} + }, + config: {customFormatTypes: true, numberFormat: 'abc', numberFormatType: 'customNumberFormat'} + }); + const labels = encode.labels(model, 'x', {}); + expect(labels.text.signal).toBe('customNumberFormat(datum.value, "abc")'); + }); }); }); diff --git a/test/compile/format.test.ts b/test/compile/format.test.ts index 8c935585a2..d6810a703b 100644 --- a/test/compile/format.test.ts +++ b/test/compile/format.test.ts @@ -1,5 +1,11 @@ import {vgField} from '../../src/channeldef'; -import {formatSignalRef, guideFormatType, numberFormat, timeFormatExpression} from '../../src/compile/format'; +import { + formatSignalRef, + guideFormat, + guideFormatType, + numberFormat, + timeFormatExpression +} from '../../src/compile/format'; import {defaultConfig} from '../../src/config'; import {NOMINAL, ORDINAL, QUANTITATIVE, TEMPORAL} from '../../src/type'; @@ -116,7 +122,22 @@ describe('Format', () => { }); }); - it('should formats datumDef if format is present', () => { + it('correctly formats binned field defs if custom format config is present', () => { + expect( + formatSignalRef({ + fieldOrDatumDef: {bin: true, field: 'foo', type: 'quantitative'}, + format: undefined, + formatType: undefined, + expr: 'parent', + config: {numberFormat: 'abc', numberFormatType: 'customFormatter'} + }) + ).toEqual({ + signal: + '!isValid(parent["bin_maxbins_10_foo"]) || !isFinite(+parent["bin_maxbins_10_foo"]) ? "null" : format(parent["bin_maxbins_10_foo"], "abc") + " – " + format(parent["bin_maxbins_10_foo_end"], "abc")' + }); + }); + + it('should format datumDef if format is present', () => { expect( formatSignalRef({ fieldOrDatumDef: {datum: 200, type: 'quantitative'}, @@ -129,6 +150,52 @@ describe('Format', () => { signal: 'format(200, ".2f")' }); }); + + it('should use a custom formatter datumDef if formatType is present', () => { + expect( + formatSignalRef({ + fieldOrDatumDef: {datum: 200, type: 'quantitative'}, + format: 'abc', + formatType: 'customFormatter', + expr: 'parent', + config: {} + }) + ).toEqual({ + signal: 'customFormatter(200, "abc")' + }); + }); + + it('should use a custom formatter datumDef if config.numberFormatType is present', () => { + expect( + formatSignalRef({ + fieldOrDatumDef: {datum: 200, type: 'quantitative'}, + format: undefined, + formatType: undefined, + expr: 'parent', + config: {numberFormat: 'abc', numberFormatType: 'customFormatter', customFormatTypes: true} + }) + ).toEqual({ + signal: 'customFormatter(200, "abc")' + }); + }); + }); + + describe('guideFormat', () => { + it('returns undefined for custom formatType', () => { + const format = guideFormat({datum: 200, type: 'quantitative'}, 'quantitative', 'abc', 'custom', {}, false); + expect(format).toBeUndefined(); + }); + it('returns undefined for custom formatType in the config', () => { + const format = guideFormat( + {datum: 200, type: 'quantitative'}, + 'quantitative', + undefined, + undefined, + {numberFormat: 'abc', numberFormatType: 'customFormatter', customFormatTypes: true}, + false + ); + expect(format).toBeUndefined(); + }); }); describe('guideFormatType()', () => { diff --git a/test/compile/legend/encode.test.ts b/test/compile/legend/encode.test.ts index 32856a6bd1..319baee532 100644 --- a/test/compile/legend/encode.test.ts +++ b/test/compile/legend/encode.test.ts @@ -166,4 +166,23 @@ describe('compile/legend', () => { expect(label.text).toEqual({signal: 'customDateFormat(datum.value, "abc")'}); }); }); + + it('returns correct expression for custom format Type from config.numberFormatType', () => { + const fieldDef: Encoding['color'] = { + field: 'a', + type: 'temporal' + }; + + const model = parseUnitModelWithScale({ + mark: 'point', + encoding: {color: fieldDef}, + config: {customFormatTypes: true, numberFormat: 'abc', numberFormatType: 'customDateFormat'} + }); + + const label = encode.labels( + {}, + {fieldOrDatumDef: fieldDef, model, channel: COLOR, legendCmpt: symbolLegend, legendType: 'symbol'} + ); + expect(label.text).toEqual({signal: 'customDateFormat(datum.value, "abc")'}); + }); });