From 8dc7f1dbb48b21b10e1c2883cd72ea2f7f183971 Mon Sep 17 00:00:00 2001 From: MiniPear Date: Sat, 6 May 2023 18:03:51 +0800 Subject: [PATCH] feat(interaction): support focus context (#4946) * feat(interaction): focus and context * docs: add example * fix: ci * chore: lock gui to 0.5.0-alpha.17 --- .../api-chart-on-brush-filter.spec.ts | 56 ++++++++++++ .../api-chart-on-focus-context.spec.ts | 82 +++++++++++++++++ ...c.ts => api-chart-on-item-element.spec.ts} | 0 ...ts => api-chart-on-series-element.spec.ts} | 0 .../chart-on-focus-context/step0-context.png | Bin 0 -> 5989 bytes .../chart-on-focus-context/step0-focus.png | Bin 0 -> 8004 bytes .../chart-on-focus-context/step1-context.png | Bin 0 -> 5960 bytes .../chart-on-focus-context/step1-focus.png | Bin 0 -> 5518 bytes .../chart-on-focus-context/step2-context.png | Bin 0 -> 5875 bytes .../chart-on-focus-context/step2-focus.png | Bin 0 -> 4598 bytes .../chart-on-focus-context/step3-context.png | Bin 0 -> 4768 bytes .../chart-on-focus-context/step3-focus.png | Bin 0 -> 13626 bytes .../chart-on-focus-context/step4-context.png | Bin 0 -> 5975 bytes .../chart-on-focus-context/step4-focus.png | Bin 0 -> 7022 bytes .../chart-on-focus-context/step5-context.png | Bin 0 -> 6016 bytes .../chart-on-focus-context/step5-focus.png | Bin 0 -> 7516 bytes .../chart-on-focus-context/step6-context.png | Bin 0 -> 4768 bytes .../chart-on-focus-context/step6-focus.png | Bin 0 -> 13626 bytes __tests__/plots/api/chart-on-focus-context.ts | 80 +++++++++++++++++ __tests__/plots/api/index.ts | 1 + package.json | 2 +- .../interaction/demo/focus-context.ts | 84 ++++++++++++++++++ .../interaction/interaction/demo/meta.json | 8 ++ src/interaction/brushFilter.ts | 45 ++++++---- src/interaction/brushHighlight.ts | 59 ++++++++++-- src/utils/scale.ts | 23 +++++ 26 files changed, 418 insertions(+), 22 deletions(-) create mode 100644 __tests__/integration/api-chart-on-brush-filter.spec.ts create mode 100644 __tests__/integration/api-chart-on-focus-context.spec.ts rename __tests__/integration/{chart-on-item-element.spec.ts => api-chart-on-item-element.spec.ts} (100%) rename __tests__/integration/{chart-on-series-element.spec.ts => api-chart-on-series-element.spec.ts} (100%) create mode 100644 __tests__/integration/snapshots/api/chart-on-focus-context/step0-context.png create mode 100644 __tests__/integration/snapshots/api/chart-on-focus-context/step0-focus.png create mode 100644 __tests__/integration/snapshots/api/chart-on-focus-context/step1-context.png create mode 100644 __tests__/integration/snapshots/api/chart-on-focus-context/step1-focus.png create mode 100644 __tests__/integration/snapshots/api/chart-on-focus-context/step2-context.png create mode 100644 __tests__/integration/snapshots/api/chart-on-focus-context/step2-focus.png create mode 100644 __tests__/integration/snapshots/api/chart-on-focus-context/step3-context.png create mode 100644 __tests__/integration/snapshots/api/chart-on-focus-context/step3-focus.png create mode 100644 __tests__/integration/snapshots/api/chart-on-focus-context/step4-context.png create mode 100644 __tests__/integration/snapshots/api/chart-on-focus-context/step4-focus.png create mode 100644 __tests__/integration/snapshots/api/chart-on-focus-context/step5-context.png create mode 100644 __tests__/integration/snapshots/api/chart-on-focus-context/step5-focus.png create mode 100644 __tests__/integration/snapshots/api/chart-on-focus-context/step6-context.png create mode 100644 __tests__/integration/snapshots/api/chart-on-focus-context/step6-focus.png create mode 100644 __tests__/plots/api/chart-on-focus-context.ts create mode 100644 site/examples/interaction/interaction/demo/focus-context.ts diff --git a/__tests__/integration/api-chart-on-brush-filter.spec.ts b/__tests__/integration/api-chart-on-brush-filter.spec.ts new file mode 100644 index 0000000000..c8ec0ed30a --- /dev/null +++ b/__tests__/integration/api-chart-on-brush-filter.spec.ts @@ -0,0 +1,56 @@ +import { chartOnBrushFilter as render } from '../plots/api/chart-on-brush-filter'; +import { PLOT_CLASS_NAME } from '../../src'; +import { dblclick, brush } from '../plots/interaction/penguins-point-brush'; +import { createDOMGCanvas } from './utils/createDOMGCanvas'; +import { createPromise, receiveExpectData } from './utils/event'; +import { sleep } from './utils/sleep'; +import './utils/useCustomFetch'; + +describe('chart.on', () => { + const canvas = createDOMGCanvas(640, 480); + const { finished, chart } = render({ canvas }); + + chart.off(); + + it('chart.on("brush:filter", callback) should provide selection when filtering', async () => { + await finished; + const { document } = canvas; + const plot = document.getElementsByClassName(PLOT_CLASS_NAME)[0]; + + // Brush plot. + const [filtered, resolve] = createPromise(); + chart.on( + 'brush:filter', + receiveExpectData(resolve, { + selection: [ + [34.99184225303586, 44.72635552737214], + [15.877014192597635, 20.13017874955966], + ], + }), + ); + brush(plot, 100, 100, 300, 300); + await filtered; + await sleep(20); + + // Reset plot. + const [rested, resolve1] = createPromise(); + chart.off(); + chart.on( + 'brush:filter', + receiveExpectData(resolve1, { + selection: [ + [32.1, 59.6], + [13.1, 21.5], + ], + }), + ); + setTimeout(() => dblclick(plot), 1000); + await rested; + // Wait for rerender over to close test. + await sleep(20); + }); + + afterAll(() => { + canvas?.destroy(); + }); +}); diff --git a/__tests__/integration/api-chart-on-focus-context.spec.ts b/__tests__/integration/api-chart-on-focus-context.spec.ts new file mode 100644 index 0000000000..2727726ff9 --- /dev/null +++ b/__tests__/integration/api-chart-on-focus-context.spec.ts @@ -0,0 +1,82 @@ +import { chartOnFocusContext as render } from '../plots/api/chart-on-focus-context'; +import { + dblclick, + brush, + dragMask, +} from '../plots/interaction/penguins-point-brush'; +import { PLOT_CLASS_NAME } from '../../src'; +import { createNodeGCanvas } from './utils/createNodeGCanvas'; +import { kebabCase } from './utils/kebabCase'; +import { sleep } from './utils/sleep'; +import './utils/useSnapshotMatchers'; +import './utils/useCustomFetch'; +import { createPromise } from './utils/event'; + +function plotOf(canvas) { + const { document } = canvas; + const plot = document.getElementsByClassName(PLOT_CLASS_NAME)[0]; + return plot; +} + +describe('chart.on', () => { + const dir = `${__dirname}/snapshots/api/${kebabCase(render.name)}`; + const canvas1 = createNodeGCanvas(640, 360); + const canvas2 = createNodeGCanvas(640, 80); + const assetSnapshots = async (step) => { + await sleep(500); + await expect(canvas1).toMatchCanvasSnapshot(dir, step + '-focus', { + maxError: 300, + }); + await expect(canvas2).toMatchCanvasSnapshot(dir, step + '-context', { + maxError: 300, + }); + }; + + it('chart.on({...}) should enables different charts to communicate.', async () => { + const { focused, contexted, focusView } = render({ + canvas1, + canvas2, + container: document.createElement('div'), + }); + await focused; + await contexted; + + const focusPlot = plotOf(canvas1); + const contextPlot = plotOf(canvas2); + + // Brush context view. + const [p1, r1] = createPromise(); + brush(focusPlot, 100, 100, 300, 300); + await assetSnapshots('step0'); + + // Brush context view again. + const [p2, r2] = createPromise(); + brush(focusPlot, 200, 200, 400, 400); + await assetSnapshots('step1'); + + // Drag focus view. + dragMask(contextPlot, 50, 50, 100, 100); + await assetSnapshots('step2'); + + // Reset focus view. + dblclick(contextPlot); + await assetSnapshots('step3'); + + // Brush focus view. + brush(focusPlot, 30, 30, 180, 180); + await assetSnapshots('step4'); + + // Drag focus view. + dragMask(contextPlot, 50, 50, 100, 100); + await assetSnapshots('step5'); + + // Reset focus view. + dblclick(contextPlot); + await assetSnapshots('step6'); + }); + + afterAll(() => { + canvas1?.destroy(); + canvas2?.destroy(); + }); +}); diff --git a/__tests__/integration/chart-on-item-element.spec.ts b/__tests__/integration/api-chart-on-item-element.spec.ts similarity index 100% rename from __tests__/integration/chart-on-item-element.spec.ts rename to __tests__/integration/api-chart-on-item-element.spec.ts diff --git a/__tests__/integration/chart-on-series-element.spec.ts b/__tests__/integration/api-chart-on-series-element.spec.ts similarity index 100% rename from __tests__/integration/chart-on-series-element.spec.ts rename to __tests__/integration/api-chart-on-series-element.spec.ts diff --git a/__tests__/integration/snapshots/api/chart-on-focus-context/step0-context.png b/__tests__/integration/snapshots/api/chart-on-focus-context/step0-context.png new file mode 100644 index 0000000000000000000000000000000000000000..28b943f26c7d75043d86718c5e4335c82551794a GIT binary patch literal 5989 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
uEDvcf3sKdo^ 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 Tx|n{@-$xKV6J3P1^Q->{kAyT_ literal 0 HcmV?d00001 diff --git a/__tests__/integration/snapshots/api/chart-on-focus-context/step1-context.png b/__tests__/integration/snapshots/api/chart-on-focus-context/step1-context.png new file mode 100644 index 0000000000000000000000000000000000000000..dd3e824cec71bbfd681c2c23016fc2a4b0bded82 GIT binary patch literal 5960 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 literal 0 HcmV?d00001 diff --git a/__tests__/integration/snapshots/api/chart-on-focus-context/step1-focus.png b/__tests__/integration/snapshots/api/chart-on-focus-context/step1-focus.png new file mode 100644 index 0000000000000000000000000000000000000000..1cd365675c377873126ae8e703754846af8c7589 GIT binary patch literal 5518 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 L;8z%*-u&jD;_WCN literal 0 HcmV?d00001 diff --git a/__tests__/integration/snapshots/api/chart-on-focus-context/step3-context.png b/__tests__/integration/snapshots/api/chart-on-focus-context/step3-context.png new file mode 100644 index 0000000000000000000000000000000000000000..0f732ba900551959d2a1af8193b4935fc2c509be GIT binary patch literal 4768 zcmcgwi9eL<`+l{Y3MnU!owB5%AqR!Aoa|#xmLVF9DUz5NOZK%>mSoA;%9#j{B>%5yk(~{ zE>2c3G;NG(64zqCHWov;WgK;S2yM)!5g{QkJRj~g2zEnBxuOa`Y}V^AQo#Ig9A4VJUs+s*4u zSa4=Xsy=W60EW?<>4T<;x~p7i4>}3otcSJz_LptJJ@}11>}-EVmZSozS6OBGlZ|E^ za2f#0YdP2V;Rl1I3O);eLS>P@g^AW*rN>ShX$Amt<9Uva8tf2I>mSL%+Xa6NQ1h8{ zWUkHa67D19;=BVPt*0*nz$b^IojPTBR;4VRJ6fCQU+p%EjQb7${a*8N>R%>Zg?~se zc8cd79u&IEhteY`hoP^|M6lPY@!mw`Xrp^*^T-uV2My{ZuKb|SZ>YL9;3PL28JABG zy0D;Rtma_zYQa|Sm~F4N7f5hwNxa8=q5tVUJniA7Bb;$BEuGR) zJ8J#woPzADKnlflIni=z`$=2jBh(Nr$WY|SM4anp`Z-Zz>Fxb5g8xdS*n2i|X#l6$ zpKR@{hvePK^qYK}kZTObQ}?;Zqja7h`M<^zR|-z)Xk@MK(F!_vF(Aln z3{-}(cOkWMBKzeA?KXpiSz%pRvYuT}x=R!yMyv!UBy-nDWH8B=zioe!Tx_f1&OYmEnL))vKsrQ)+`+Q?*^K92F_aBaU1J3DT1JmH!^xmKJ4!K zT4Y`{(|KF$@+)Tmron=#WN=+=_DKoL`EtyQ?fgeR+gf^s*G1NcuqGJI3;s9Z$(4TR5w}se^vV~9#CZ$MmyhGd3j=ehx46Q5dnFE6%3>kI+mP@eHj)c(}S~XWH zE8OWeUKgm8B`n@ABEFjbflE95?p?^|uPVHK3RZw3k||PoP0sf{&tZPNnd65y7;fY@ zFYRB{We3;K^8=LC=^vKDxiukAaF!zCj8%e6@(t@^G*>De6$DSye%~tub>O!Uw68BZ z7#<8R)+)P|dim@Q__>(E<09*!zsRQ)AgXvbk->3|#ksyBA{w#k18)-U&J}bJtZ?FG zyv8NVfM&O2w^CML7`}U7@gF;cKHV&8Xi0`W)k}v)PR8`FAn=~!TsHIo!>STTi%b+o z6;k?gbIsOkdN5d*k$yV7TV0#li!p4kk<8C1h&7ozS4L3ES+&(rvuxd()Rp_TZf;#- zTUEEU(0pW zGK;z(!8N5hPbTB8j6YbUyxUy9XLFRGqE_rGoFTzO%>-vx&i%Yx;B8a4E{o-?DKr+Y zeb-nUMaa&w<2QLavZsvE7U+TO%kvndbR-sApyXXUx<7Ka)=D>%rq-^=8!fb*O;WRLU7&qJgZ-jm>Yxb>F;K?!*-}l%yZsYz{pzcviSNn5PLQCHgeNa0 zL{*7~<#=mX8x{1_+v0 z(Q9-(j2O7TyS2fRcqlXzCVY4V~skgrB~&h zk1@`1=vBTXkp=D$=9f)?)w1~AOpb$q`^kMI#2uJryl!63Sh;H@4t&pWyh-SG9ii@G1=n6k;*0!!4e2sN53`G!Kmq$wR+2sk|Jo}HA&oy6;`qy zmz9E|Ic_hp!q`T~|H{u2A-OUtjxiKdCq zJJQ!afE5S*$CmLoq!Uz;(xD-VlFxB2t;mq&N4cTTV1=ddYV9W zD#Ttc?R*<;GGlvQ!KO5}|(uh%VLh}QToSom!@(d|6*Eb7WTzQu1ZWew%U>()huud>ke7MlMe5fEO%coRug4ME_qL}u!XLT>jQ(x2_;+O4WZ#V&dJdS@ts4?H zut5oR6(hJM86_YYR^e^2SE1e+Z3^AKVqjqdS`JQfY=$q&7XQ`uUTo+m)NO!JWb6yo zN!C(_=_sf%mk2Ti(e!=2ces!8n)NFEuVhHOo`>ZHZjI<;5n2X-=GQJ_;~~@~mv^ut zHejfRH%iR7W5}6AvgC89uyw&m{7E+nxM$?PDfOFJ_QwZ3GKk~J;~y0h%qvy>iK?P* zCKFdkyrUjw6)^$!Bdjd0MTv<+ll3H7Q=2WM5bmg+W=(h2Ozgd%*R5e@NivI)P7#M| z?{Bm*t>t${ex;m>x2)1u=JZOcDuh&9SgZ3{X4{=JG#P?Sr<7Mo+F}p;b|SHY&yRZ= zO9A4Jr45aKhMfdsQ(0KhP}&}(@ta7#nj2q-a5?$xJEa@twn)2$-A^RN?@2xA%Viqw zPIDu^$s(xKgU?LLkOvp@A99I#h}lj>n&}vBOczb^Pa|&OmmTk>$bYq4Xc()aln^2C z@p6}N9l&$ADewMT6xEy8dx zoqO!T=q!zV z`!SE|;AF{;6FPvPArQjlv$mvDY;`3yvzr=4=9WK{1NFR|J{F1U98omPe{woi8g*}Z zmf{YPyl#7#3thKQQ%v11?F&isJKb6DR)`amd zlYgo`Hlpw7>NnYkTSP?q*CQ8RYr64QCWj3Zt+Ba(Y#E6S{R+*ib+L_ke`=l9k zT8cO}->qjedv3apyi*oKRm5eBN6yQG3dlD+Xd$Iq1GLv}wVefL^hmc}4OiqHPAk_d z?bRvDlUpk@58OHa*^jFS)Cz0;Y?Zb=>}m6~kT!Yqsli0zG@%vOek zjDd>>{t&HPn^T%1S;?8ryB>k7)HS=jS49VZED0_K2h30O=^zcnE}SewRXuEh?ZcgX zBW2V75E;@ZzXRDS;+j5eQX$PX?2aj6a2+JDbVI$>pwh*}%~+{j+Yj*c6!hUJM0km@0g9`PO7y+s_88tKkl@GbOu_ZvxL|tU9wf zoz)N1xfU@n*Ppylc&MY1vKv2$aDIxzMQ46I;BFT#*`ai&t_thM8jPhsD1Mo*c_62g zAZ|gu;HN1F_YSCYXAhDjuar^#QnRGj{EohqfEd-3wG8LiGtMQ+{voSb*@#WS~r)MK25x!us3rwE9^bm|xOt;mUeKgwaq(Z7=j zIdY*H!!*ff!YAeou(^2qe>34X1bFz(9W5J*FOj**1OXzI_oh|OBITNBUzr6xO0cHsBA%j?dgEa~hogE5j; zh>AwBbP2``7w4<%JOBX}V;UA??i{-!nQ-_X+#0``=-Qhxb?Z;Zpat)VYK#jsDOxC2 z`mfbs1Kh}sMLI(il>aJi3C5z1m=1sKhY`yepljs=w&$+_a@xMQl1fclIPbj6^?)B` zeyO$)?-nI{Vg!m@!L4IiALKytOHZ7D+eENXx*H*6JsHh-qK>qZGT+ks*7E&uzvt+I zJCKZPZPt*(iPK=3T00EbysA}AI(;o)RkRjAU3jSv(MJur-E;a&nm^;~h=pTd_0Oe9 zb-{Zn^{RWjea13Me{Y((q;*>4 zy&a-xws6;aCx3#D)29)AleX-9tJ2i7ipCGiMAb!o{-ufgL&b;9kUI1z<}<4DCnhjwhnef& zui*WAaqIAi%CL=nT6ePE&C5$kVuc8XP4yF=5d(E~6H*=QCscGeQ3=mR;M-XHzt5Hq z1m_O)6IAY&VLZSx1C=QO?Ss|8ISm{9Iiz9qwmxvR$>Z4O$pnmyoQvY7S*e+<)xmFh z$O;5y<)vJau{u^Mdgg>Q+c}w)VF3u5DN{#gusZGa-wj4qXrWZ;$5}X*EIR%>S*^n@ zz59~OOWzf9ud6ixtXxy$Gqq776|&P4NPOw#6XP{I-!yDh@3>^#!uyv@cqtBvDKb6T zpTupp)L(aacDSNme*#R=Va>&rdI19PjA>G3x(Rrk$Ep&eW#elNgHJB6R7y~nM$Ak40gJLES~i4L?w z2i2XVrVcI#b?wX{@g>72OEG{XiM8hp#R0tePY%?F|57c*nyu7ph0TIac5joo&AHnL|iS3CjtgtKiBl0d)&2vON0YiBzu2Zi=G&koaQ5 z1v;AL+@5|=3pLgHOH;%R*b?;bmSXs3=a44F2`6OiSdisiR#AD!mM5#ZHXn^fniLKE zy;t@vk!Gbmn)ee=zKH&Hk#YaY&p|M> zzo3~?&zeq(*U0X^v&mOUm(;66{lMFeSEb24rE9N&S&0@pHsudNCB zHOqkc+f~x`^q_H6YAy9E690thgjLZ*hYWGaQca1*=)p|x*DabQNTMXQPn6&U?h^d_ z&3`jZ9{KT^nVkP~={+_PSiRp(HcIjxs751O{+=Ns8`jb+Z>}y~U?kqJHqR{NgvsTL zweGDl&Vl`iqrGEc4R5g5(DP=|ZEPMlO)H<=<@dV~kJv(wlT~^*$e2AdZM~!H+}}su z`)QNtTIky}lx@_FqD$`)v?UV2aaQb*jj3nIaU!mwjT@O}r_1MlTJU6ZTxP{TGWe|{ zv#KWx&^Nq)HXEKW2+3#Y>!W{wzk?CqmN33blZ)y7)ZoPGi|GNb^S<+ZWy&m_P)m&~ zRn9r-#Yr?#G@u}A6s)VusLCPh#7%KGCY#~~aJz+Rn`6E-ZBIq^%gaf*B}1g{W`S1d z4Uo07uu4vk5tRCFFq~#`=y$|CgQhaNCmAbz@eeM(E+zfy7wqz%fR)3y(^L#^R|&<1 z2GzOc8_|f}WoTAi727(pDP+6+s z1^-&gr#m9jMJ(Cl_HFBGx6TUtbyEUO^JrVO(Xtezr-;rTS>)H7qn_6)#49VU2W?W@ zSW#eM6A^hx-*?ecj|5*hq8_FY2*qm{S9vRU`*ktF+%GiMUfN|F5}`@w!|Vcd;tv=> zQXSPyj2^GI+Q80R9qfE9o_Fn9<)rQvZsWCa?w3gBkT#c>75o{WRmo}HrF{L$kdpFG zRvqP$G!Y2od>tIi9Ni+XcK$~!_+kya*Hc64DxQzOM?S}hv#c^0O1)?)=PMTQt54g{ z+sUe1=L$Nw^85*Z@P&FAh+X{b!g9g5O1iWv3GJ0$;MG{EBRR_VA*ziJ1=Bz-izq1t z_5ZF^uGse_-Wp*yL!LVkW|xn6NMJmXKDDx7(|0=!oI{XK_v0*gn~D7uMtOPRjb8oj6mB*&P4ay~DxxCnEgMN4p@9pQr|LL_On4KnY(;PY={hVY!O4 z-rVs@=e_RcQzrpe&}AIopR4R!caaLo$VRMbK_W$ly0Z%&snVRqOr{ym03|{$^2HDp zq=yFX6Sh+Yq4=#7?6}g-@KlHl^q%`QY2FdV)y)sw4If#$kbO5^pb}WalWN| z?%eX<7)sqL^k`I+;&$nO(nZL`78q^^P-Pdwucm{~?g(HI&}iZJ40(%3DDi+%k$S(TJ2 zbwfDOC0FhinHgipWQMEL^0_{ay*R<_wC_|6={xs&YVOVStTHqn9S zmi%(6RaU4zd;bC@M-_Q*?N<{Xft!YuSR7xuP$9Q)<+Lqco4@4y@j+!@2t;1RG`J;l z=i};+lb~gjkT{_@xUOldoAIrNn2}}7YbGwof*f0@<(8L;icq{2*hSaF%ruzk8j+Sr z;JY`5I7xnN5{Rws1)AQSV>0DI*#Y+9p7zB@p7lxLIG5xZiTtnUJA(_Y0u8S88ptjg z4yBw1i=E^m5VdNzSCYibMXF=;eRB>%&WV}evJkt{xx>2Dths;*MCs8^v~(2c`$;Nu z)7hzl!F5q|l6L?tpuLh2r}V<^Wr(Ny=*kpY-zPutVLV&nZws1}HGRl;iL3CD^JA-O zk5>gx7F=MrAX3i?oI}(s9mX9ZV~1ucU0ZVxZ=D6%@b4i5i91OAUF&l2NJ#Hy-P(jz zZrR`+d=~wa`wGD#mjUgEsrM1cLrL4?zh;zziLgt6bN7?5U;4C}S)rwGKcfE92+Zy` zQ8Yf3a?W+NK%eF;*#4bwmBCdRAEl@wbQCcV{QO2G7C9ir5obK%vrLr1Jp}7oY^g4x zdd1b;SewK7#TlXh0nV*~_sw_}A8IwBc69;D&Hhex^h#tGU%CdC9G%0+e~YWT>w0~-sWf=&Bu*^KkC`+mHL9X;PYG$`t z2$FLQxLbv1LDVm9I!TYK<3;p*MoTnn+L zkTISGc_ZpB;K(Rji5{Xrks@ZlO_J0aiFywg~ceuHWuB7fa%t#aO%sMqv*${JDv zj{=*GN?%xUn z?$Z-K?sz9Nw;V)cLh8c-##G@DJ(-59wK4eT&aS! zgIzk&%Q0RrDBRTLN|M7C*Mm#COw>I z4Ch_SN0AUM!@Z2+W{IW<0qreKyUDU9IkC7*Y~7D`jj=c1?RLj^=Bm>w_iZO(0@lIB zo2J#Ypl0!q&8xo!&p4@aKz#A!`K3z7s{MR_&pjV18Y}*tk5^fCssoFyYulBUu#~q{ zh+Amr5##onQmT8?`}$j|J-hX=881lsHcja4%yBgy zS?br{M&}@z)Q-N*-rlNu_B{;JSo3Ajl-ZfO!n__fyC5g!U%sr+oKkOF6&NA-)mZe^bVb6?1jCQ!k?A_l1LN$Xu*Y=UD_<~_xC9Q%Sg7mLd(OY8R@e%^`= zov~a0z1A!1^+NlcEDp zU4f#%a6>tsxtV&ZLB?4j8=J;ND~ML6QVH42v)Xi!mdQWR$6Cnu64)z*rX3R7>jn8K zE(|qbN7p?2*E8oJ`oF&P7g)aeO)J?YGrx!jsG-G`{(z}y*Fj<4&&@;OQyIOK{MTzT z#x47R>~mD{`NbX#o3y+lUk*rX57|{%=Cc(hM_^UTP%RZPeoF3~WCFIlM&@mnYy5s% z&43j0_~dET*AsYHl5KlI{rbV43RmF4uj}*Osp7|bfFxx2gFUB%HLN#w%aK>xt6m>7$-0Ub?coj!qmkp2H6yo33aA12D1AzzuI66y z`4yKxtWSoir%^Ovv8jL&92FaQv8?RJ4+`Bkl|2s50%W{!?B6qoReEMt9GK^NlVq%Vj!Q+D%KgOKeZtN?0x*_* zJQd78P$GUO_)V!Xv`_zr=Ks+7#q)KLz7T&tlj4a>(d3ROO zbf2FL|D{l^v){mrmd(;P4sps!r=yvUtN!A62*lg4FeK}691Wbf{hAvW$>_}UmON&} z_DdJzPeLaubGsrCJM_bhuGrx_^_CU#grGKd4hbG z;b_=zD~S&b&#Q)gbOF~pPVGBH4GrN`T9Dm1wJSc$wTr

3kGkmldjL6-tfT{8 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 DFi{%o literal 0 HcmV?d00001 diff --git a/__tests__/integration/snapshots/api/chart-on-focus-context/step5-context.png b/__tests__/integration/snapshots/api/chart-on-focus-context/step5-context.png new file mode 100644 index 0000000000000000000000000000000000000000..521ddc71be8b6d185a635207b2d37b932dd08928 GIT binary patch literal 6016 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 literal 0 HcmV?d00001 diff --git a/__tests__/integration/snapshots/api/chart-on-focus-context/step5-focus.png b/__tests__/integration/snapshots/api/chart-on-focus-context/step5-focus.png new file mode 100644 index 0000000000000000000000000000000000000000..2b4c127471d1d6d0c4e7523b287b902c81ef0b2d GIT binary patch literal 7516 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 literal 0 HcmV?d00001 diff --git a/__tests__/integration/snapshots/api/chart-on-focus-context/step6-context.png b/__tests__/integration/snapshots/api/chart-on-focus-context/step6-context.png new file mode 100644 index 0000000000000000000000000000000000000000..0f732ba900551959d2a1af8193b4935fc2c509be GIT binary patch literal 4768 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

3kGkmldjL6-tfT{8 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 { + const { nativeEvent } = e; + if (!nativeEvent) return; + const { selection } = e.data; + const { x: scaleX } = focusView.getScale(); + const [[x1, x2]] = selection; + const domainX = scaleX.getOptions().domain; + if (x1 === domainX[0] && x2 === domainX[1]) { + contextView.emit('brush:remove'); + } else { + contextView.emit('brush:highlight', { data: { selection } }); + } + }); + + contextView.on('brush:highlight', (e) => { + const { nativeEvent, data } = e; + if (!nativeEvent) return; + const { selection } = data; + focusView.emit('brush:filter', { data: { selection } }); + }); + + contextView.on('brush:end', () => { + const { x: scaleX, y: scaleY } = contextView.getScale(); + const selection = [scaleX.getOptions().domain, scaleY.getOptions().domain]; + focusView.emit('brush:filter', { data: { selection } }); + }); + + return { focusView, focused, contexted, contextView }; +} diff --git a/__tests__/plots/api/index.ts b/__tests__/plots/api/index.ts index 894be15c98..b8bd16a0d2 100644 --- a/__tests__/plots/api/index.ts +++ b/__tests__/plots/api/index.ts @@ -16,3 +16,4 @@ export { chartChangeDataFacet } from './chart-change-data-facet'; export { chartRenderClearAnimation } from './chart-render-clear-animation'; export { chartOnBrushFilter } from './chart-on-brush-filter'; export { chartOptionsChangeData } from './chart-options-change-data'; +export { chartOnFocusContext } from './chart-on-focus-context'; diff --git a/package.json b/package.json index b73216a1ce..3fe59ac88b 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "@antv/g": "^5.7.4", "@antv/g-canvas": "^1.7.4", "@antv/g-plugin-dragndrop": "^1.6.1", - "@antv/gui": "^0.5.0-alpha.15", + "@antv/gui": "0.5.0-alpha.17", "@antv/path-util": "^3.0.1", "@antv/scale": "^0.4.7", "@antv/util": "^3.3.2", diff --git a/site/examples/interaction/interaction/demo/focus-context.ts b/site/examples/interaction/interaction/demo/focus-context.ts new file mode 100644 index 0000000000..1c68454443 --- /dev/null +++ b/site/examples/interaction/interaction/demo/focus-context.ts @@ -0,0 +1,84 @@ +import { Chart } from '@antv/g2'; + +document.getElementById('container').innerHTML = ` +

+
+`; + +// Render focus View. +const focus = new Chart({ + container: 'focus', + theme: 'classic', + height: 360, +}); + +focus + .area() + .data({ + type: 'fetch', + value: + 'https://gw.alipayobjects.com/os/bmw-prod/551d80c6-a6be-4f3c-a82a-abd739e12977.csv', + }) + .encode('x', 'date') + .encode('y', 'close') + .animate(false) + .axis('x', { grid: false, title: false, tickCount: 5 }) + .axis('y', { grid: false, tickCount: 5 }) + .interaction('tooltip', false) + .interaction('brushXFilter', true); + +focus.render(); + +// Render context View. +const context = new Chart({ + container: 'context', + theme: 'classic', + paddingLeft: 40, + paddingTop: 0, + paddingBottom: 0, + height: 80, +}); + +context + .area() + .data({ + type: 'fetch', + value: + 'https://gw.alipayobjects.com/os/bmw-prod/551d80c6-a6be-4f3c-a82a-abd739e12977.csv', + }) + .encode('x', 'date') + .encode('y', 'close') + .animate(false) + .axis(false) + .interaction('tooltip', false) + .interaction('brushXHighlight', true); + +context.render(); + +// Add event listeners to communicate. +focus.on('brush:filter', (e) => { + const { nativeEvent } = e; + if (!nativeEvent) return; + const { selection } = e.data; + const { x: scaleX } = focus.getScale(); + const [[x1, x2]] = selection; + const domainX = scaleX.getOptions().domain; + if (x1 === domainX[0] && x2 === domainX[1]) { + context.emit('brush:remove'); + } else { + context.emit('brush:highlight', { data: { selection } }); + } +}); + +context.on('brush:highlight', (e) => { + const { nativeEvent, data } = e; + if (!nativeEvent) return; + const { selection } = data; + focus.emit('brush:filter', { data: { selection } }); +}); + +context.on('brush:end', () => { + const { x: scaleX, y: scaleY } = context.getScale(); + const selection = [scaleX.getOptions().domain, scaleY.getOptions().domain]; + focus.emit('brush:filter', { data: { selection } }); +}); diff --git a/site/examples/interaction/interaction/demo/meta.json b/site/examples/interaction/interaction/demo/meta.json index 8fbe1c4324..62b4c60228 100644 --- a/site/examples/interaction/interaction/demo/meta.json +++ b/site/examples/interaction/interaction/demo/meta.json @@ -99,6 +99,14 @@ "en": "Fisheye" }, "screenshot": "https://gw.alipayobjects.com/zos/raptor/1669041902028/fisheye.gif" + }, + { + "filename": "focus-context.ts", + "title": { + "zh": "图表联动", + "en": "Focus and Context" + }, + "screenshot": "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*zQRoSI_fW4MAAAAAAAAAAAAADmJ7AQ/original" } ] } diff --git a/src/interaction/brushFilter.ts b/src/interaction/brushFilter.ts index 4ff90592fe..d88d96e635 100644 --- a/src/interaction/brushFilter.ts +++ b/src/interaction/brushFilter.ts @@ -1,6 +1,6 @@ import { deepMix } from '@antv/util'; import { subObject } from '../utils/helper'; -import { invert, domainOf } from '../utils/scale'; +import { selectionOf } from '../utils/scale'; import { brush as createBrush } from './brushHighlight'; import { selectPlotArea } from './utils'; @@ -26,6 +26,10 @@ export function brushFilter( brushRegion, extent: optionalExtent, reverse, + emitter, + scale, + coordinate, + selection, series = false, ...rest }, @@ -49,17 +53,29 @@ export function brushFilter( // Filter when brush created. function brushcreated(x, y, x1, y1, event) { - filter(x, y, x1, y1, event); + event.nativeEvent = true; + filter(selection(x, y, x1, y1), event); brush.remove(); } // Reset when dblclick. function click(e) { - if (isDblclick(e)) reset(e); + if (isDblclick(e)) { + e.nativeEvent = true; + reset(e); + } } + const onFilter = ({ nativeEvent, data }) => { + if (nativeEvent) return; + const { selection } = data; + filter(selection, { nativeEvent: false }); + }; + emitter.on('brush:filter', onFilter); + return () => { brush.destroy(); + emitter.off('brush:filter', onFilter); root.removeEventListener('click', click); }; } @@ -80,27 +96,21 @@ export function BrushFilter({ hideX = true, hideY = true, ...rest }) { let filtering = false; let newView = view; + const { scale, coordinate } = view; return brushFilter(plotArea, { brushRegion: (x, y, x1, y1) => [x, y, x1, y1], - filter: async (x, y, x1, y1, event) => { + selection: (x, y, x1, y1) => { + const { scale, coordinate } = newView; + return selectionOf(x, y, x1, y1, scale, coordinate); + }, + filter: async (selection, event) => { // Avoid redundant filter. if (filtering) return; filtering = true; - // Invert visual range to abstract domain. - const { scale, coordinate } = newView; - const { x: scaleX, y: scaleY } = scale; - const abstractDomain = (point, start) => { - const [x, y] = coordinate.invert(point); - return [invert(scaleX, x, start), invert(scaleY, y, start)]; - }; - const p0 = abstractDomain([x, y], true); - const p1 = abstractDomain([x1, y1], false); - // Update the domain of x and y scale to filter data. + const [domainX, domainY] = selection; const { marks } = viewOptions; - const domainX = domainOf(scaleX, [p0[0], p1[0]]); - const domainY = domainOf(scaleY, [p0[1], p1[1]]); const newMarks = marks.map((mark) => deepMix( { @@ -153,6 +163,9 @@ export function BrushFilter({ hideX = true, hideY = true, ...rest }) { update(viewOptions); }, extent: undefined, + emitter, + scale, + coordinate, ...defaultOptions, ...rest, }); diff --git a/src/interaction/brushHighlight.ts b/src/interaction/brushHighlight.ts index 3b0c126596..a09a083f5c 100644 --- a/src/interaction/brushHighlight.ts +++ b/src/interaction/brushHighlight.ts @@ -1,5 +1,6 @@ import { DisplayObject, Rect, Path } from '@antv/g'; import { subObject } from '../utils/helper'; +import { selectionOf, pixelsOf } from '../utils/scale'; import { selectG2Elements, selectPlotArea, @@ -240,11 +241,16 @@ export function brush( return { mask, + move(x, y, x1, y1) { + if (!mask) initMask(x, y); + start = [x, y]; + end = [x1, y1]; + updateMask([x, y], [x1, y1]); + }, remove() { if (mask) removeMask(); }, destroy() { - if (mask) removeMask(); root.removeEventListener('dragstart', dragstart); root.removeEventListener('drag', drag); root.removeEventListener('dragend', dragend); @@ -290,6 +296,8 @@ export function brushHighlight( brushRegion, extent: optionalExtent, reverse, + scale, + coordinate, series = false, key = (d) => d, bboxOf = (root) => { @@ -297,6 +305,7 @@ export function brushHighlight( return { x, y, width, height }; }, state = {}, + emitter, ...rest }, ) { @@ -379,18 +388,51 @@ export function brushHighlight( } }; - return brush(root, { + const brushHandler = brush(root, { ...brushStyle, extent, brushRegion, reverse, - brushended: series ? seriesBrushend : brushended, - brushed: series ? seriesBrushed : brushed, + brushended: () => { + const handler = series ? seriesBrushend : brushended; + emitter.emit('brush:end', { nativeEvent: true }); + handler(); + }, + brushed: (x, y, x1, y1) => { + const selection = selectionOf(x, y, x1, y1, scale, coordinate); + emitter.emit('brush:highlight', { + nativeEvent: true, + data: { selection }, + }); + const handler = series ? seriesBrushed : brushed; + handler(x, y, x1, y1); + }, }); + + // Move brush and highlight data. + const onHighlight = ({ nativeEvent, data }) => { + if (nativeEvent) return; + const { selection } = data; + const [x, y, x1, y1] = pixelsOf(selection, scale, coordinate); + brushHandler.move(x, y, x1, y1); + }; + emitter.on('brush:highlight', onHighlight); + + // Remove brush and reset data. + const onRemove = () => brushHandler.remove(); + emitter.on('brush:remove', onRemove); + + // Remove event handlers. + brushHandler.destroy = () => { + emitter.off('brush:highlight', onHighlight); + emitter.off('brush:remove', onRemove); + }; + + return brushHandler; } export function BrushHighlight({ facet, brushKey, ...rest }) { - return (target, viewInstances) => { + return (target, viewInstances, emitter) => { const { container, view, options } = target; const plotArea = selectPlotArea(container); const defaultOptions = { @@ -400,6 +442,7 @@ export function BrushHighlight({ facet, brushKey, ...rest }) { reverse: false, }; const defaultStates = ['active', ['inactive', { opacity: 0.5 }]]; + const { scale, coordinate } = view; if (facet) { const bbox = plotArea.getBounds(); @@ -418,6 +461,9 @@ export function BrushHighlight({ facet, brushKey, ...rest }) { selectFacetViews(target, viewInstances).map((d) => d.options), defaultStates, ), + emitter, + scale, + coordinate, ...defaultOptions, ...rest, }); @@ -439,6 +485,9 @@ export function BrushHighlight({ facet, brushKey, ...rest }) { [options, ...selectSiblingOptions(target, viewInstances, brushKey)], defaultStates, ), + emitter, + scale, + coordinate, ...defaultOptions, ...rest, }); diff --git a/src/utils/scale.ts b/src/utils/scale.ts index 08d5e5c86b..c9fe400323 100644 --- a/src/utils/scale.ts +++ b/src/utils/scale.ts @@ -29,3 +29,26 @@ export function domainOf(scale, values) { const end = domain.indexOf(v2); return domain.slice(start, end + 1); } + +export function selectionOf(x, y, x1, y1, scale, coordinate) { + const { x: scaleX, y: scaleY } = scale; + const abstractDomain = (point, start) => { + const [x, y] = coordinate.invert(point); + return [invert(scaleX, x, start), invert(scaleY, y, start)]; + }; + const p0 = abstractDomain([x, y], true); + const p1 = abstractDomain([x1, y1], false); + const domainX = domainOf(scaleX, [p0[0], p1[0]]); + const domainY = domainOf(scaleY, [p0[1], p1[1]]); + return [domainX, domainY]; +} + +export function pixelsOf(selection, scale, coordinate) { + const [[minX, maxX], [minY, maxY]] = selection; + const { x: scaleX, y: scaleY } = scale; + const p0 = [scaleX.map(minX), scaleY.map(minY)]; + const p1 = [scaleX.map(maxX), scaleY.map(maxY)]; + const [x, y] = coordinate.map(p0); + const [x1, y1] = coordinate.map(p1); + return [x, y, x1, y1]; +}