From b392808a4427d2ca00b77a46ac1c03c14f6b76b0 Mon Sep 17 00:00:00 2001 From: Jukka Kurkela Date: Wed, 28 Apr 2021 11:13:23 +0300 Subject: [PATCH 1/2] Update category panning --- docs/guide/options.md | 1 - karma.conf.js | 1 - package-lock.json | 13 ---- package.json | 1 - src/core.js | 8 +-- src/plugin.js | 1 - src/scale.types.js | 38 ++++++---- test/fixtures/pan/category-x-1.js | 68 ++++++++++++++++++ test/fixtures/pan/category-x-1.png | Bin 0 -> 7525 bytes test/fixtures/pan/category-x-10.js | 68 ++++++++++++++++++ test/fixtures/pan/category-x-10.png | Bin 0 -> 17646 bytes test/fixtures/pan/category-x-25.js | 68 ++++++++++++++++++ test/fixtures/pan/category-x-25.png | Bin 0 -> 18967 bytes .../pan/{category-x.js => category-x-5.js} | 33 ++++----- test/fixtures/pan/category-x-5.png | Bin 0 -> 13583 bytes test/fixtures/pan/category-x-50.js | 67 +++++++++++++++++ test/fixtures/pan/category-x-50.png | Bin 0 -> 23174 bytes test/fixtures/pan/category-x.png | Bin 20971 -> 0 bytes test/specs/defaults.spec.js | 1 - types/options.d.ts | 5 -- 20 files changed, 310 insertions(+), 63 deletions(-) create mode 100644 test/fixtures/pan/category-x-1.js create mode 100644 test/fixtures/pan/category-x-1.png create mode 100644 test/fixtures/pan/category-x-10.js create mode 100644 test/fixtures/pan/category-x-10.png create mode 100644 test/fixtures/pan/category-x-25.js create mode 100644 test/fixtures/pan/category-x-25.png rename test/fixtures/pan/{category-x.js => category-x-5.js} (60%) create mode 100644 test/fixtures/pan/category-x-5.png create mode 100644 test/fixtures/pan/category-x-50.js create mode 100644 test/fixtures/pan/category-x-50.png delete mode 100644 test/fixtures/pan/category-x.png diff --git a/docs/guide/options.md b/docs/guide/options.md index 084abeb5..4c740ae0 100644 --- a/docs/guide/options.md +++ b/docs/guide/options.md @@ -36,7 +36,6 @@ const chart = new Chart('id', { | `mode` | `'x'`\|`'y'`\|`'xy'` | `'xy'` | Allowed panning directions | `modifierKey` | `'ctrl'`\|`'alt'`\|`'shift'`\|`'meta'` | `null` | Modifier key required for panning with mouse | `overScaleMode` | `'x'`\|`'y'`\|`'xy'` | `undefined` | Which of the enabled panning directions should only be available when the mouse cursor is over a scale for that axis -| `speed` | `number` | `20` | Factor for pan velocity on **category scale** | `threshold` | `number` | `10` | Mimimal pan distance required before actually applying pan ### Pan Events diff --git a/karma.conf.js b/karma.conf.js index f814d2a0..5a3cf5a9 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -60,7 +60,6 @@ module.exports = function(karma) { {pattern: 'test/fixtures/**/*.json', included: false}, {pattern: 'test/fixtures/**/*.png', included: false}, {pattern: 'node_modules/chart.js/dist/chart.js'}, - {pattern: 'node_modules/hammer-simulator/index.js'}, {pattern: 'node_modules/hammerjs/hammer.js'}, {pattern: 'node_modules/chartjs-adapter-date-fns/dist/chartjs-adapter-date-fns.bundle.js'}, {pattern: 'test/index.js'}, diff --git a/package-lock.json b/package-lock.json index b43d1913..e2d1060a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,7 +26,6 @@ "eslint-plugin-es": "^4.1.0", "eslint-plugin-html": "^6.1.2", "eslint-plugin-markdown": "^2.0.1", - "hammer-simulator": "0.0.1", "jasmine": "^3.7.0", "karma": "^6.3.2", "karma-chrome-launcher": "^3.1.0", @@ -8166,12 +8165,6 @@ "node": ">=6.0" } }, - "node_modules/hammer-simulator": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/hammer-simulator/-/hammer-simulator-0.0.1.tgz", - "integrity": "sha1-7tO85CtDMgF1o/T4NP4gjl+iSho=", - "dev": true - }, "node_modules/hammerjs": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/hammerjs/-/hammerjs-2.0.8.tgz", @@ -24608,12 +24601,6 @@ "strip-bom-string": "^1.0.0" } }, - "hammer-simulator": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/hammer-simulator/-/hammer-simulator-0.0.1.tgz", - "integrity": "sha1-7tO85CtDMgF1o/T4NP4gjl+iSho=", - "dev": true - }, "hammerjs": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/hammerjs/-/hammerjs-2.0.8.tgz", diff --git a/package.json b/package.json index 7a3118da..c31604e0 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,6 @@ "eslint-plugin-es": "^4.1.0", "eslint-plugin-html": "^6.1.2", "eslint-plugin-markdown": "^2.0.1", - "hammer-simulator": "0.0.1", "jasmine": "^3.7.0", "karma": "^6.3.2", "karma-chrome-launcher": "^3.1.0", diff --git a/src/core.js b/src/core.js index d64cbb4c..765e5b1e 100644 --- a/src/core.js +++ b/src/core.js @@ -76,12 +76,12 @@ export function resetZoom(chart) { chart.update(); } -function panScale(scale, delta, panOptions, limits) { +function panScale(scale, delta, limits) { const {panDelta} = getState(scale.chart); // Add possible cumulative delta from previous pan attempts where scale did not change delta += panDelta[scale.id] || 0; const fn = panFunctions[scale.type] || panFunctions.default; - if (call(fn, [scale, delta, panOptions, limits])) { + if (call(fn, [scale, delta, limits])) { // The scale changed, reset cumulative delta panDelta[scale.id] = 0; } else { @@ -102,9 +102,9 @@ export function doPan(chart, pan, enabledScales) { each(enabledScales || chart.scales, function(scale) { if (scale.isHorizontal() && xEnabled) { - panScale(scale, x, panOptions, limits); + panScale(scale, x, limits); } else if (!scale.isHorizontal() && yEnabled) { - panScale(scale, y, panOptions, limits); + panScale(scale, y, limits); } }); diff --git a/src/plugin.js b/src/plugin.js index 669bc391..ec07b8ae 100644 --- a/src/plugin.js +++ b/src/plugin.js @@ -14,7 +14,6 @@ export default { pan: { enabled: false, mode: 'xy', - speed: 20, threshold: 10, modifierKey: null, }, diff --git a/src/scale.types.js b/src/scale.types.js index 329c30ce..b3a48c5e 100644 --- a/src/scale.types.js +++ b/src/scale.types.js @@ -66,23 +66,31 @@ function zoomCategoryScale(scale, zoom, center, limits) { return updateRange(scale, newRange, limits, true); } -const categoryDelta = new WeakMap(); -function panCategoryScale(scale, delta, panOptions, limits) { +function scaleLength(scale) { + return scale.isHorizontal() ? scale.width : scale.height; +} + +function panCategoryScale(scale, delta, limits) { const labels = scale.getLabels(); const lastLabelIndex = labels.length - 1; - const offsetAmt = Math.max(scale.ticks.length, 1); - const panSpeed = panOptions.speed; - const step = Math.round(scale.width / (offsetAmt * panSpeed)); - const cumDelta = (categoryDelta.get(scale) || 0) + delta; - const scaleMin = scale.min; - const minIndex = cumDelta > step ? Math.max(0, scaleMin - 1) - : cumDelta < -step ? Math.min(lastLabelIndex - offsetAmt + 1, scaleMin + 1) - : scaleMin; - const maxIndex = Math.min(lastLabelIndex, minIndex + offsetAmt - 1); - - categoryDelta.set(scale, minIndex !== scaleMin ? 0 : cumDelta); + let {min, max} = scale; + // The visible range. Ticks can be skipped, and thus not reliable. + const range = Math.max(max - min, 1); + // How many pixels of delta is required before making a step. stepSize, but limited to max 1/10 of the scale length. + const stepDelta = Math.round(scaleLength(scale) / Math.max(range, 10)); + const stepSize = Math.ceil(Math.abs(delta / stepDelta)); + let applied; + if (delta < -stepDelta) { + max = Math.min(max + stepSize, lastLabelIndex); + min = range === 1 ? max : max - range; + applied = max === lastLabelIndex; + } else if (delta > stepDelta) { + min = Math.max(0, min - stepSize); + max = range === 1 ? min : min + range; + applied = min === 0; + } - return updateRange(scale, {min: minIndex, max: maxIndex}, limits); + return updateRange(scale, {min, max}, limits) || applied; } const OFFSETS = { @@ -96,7 +104,7 @@ const OFFSETS = { year: 182 * 24 * 60 * 60 * 1000 // 182 d }; -function panNumericalScale(scale, delta, panOptions, limits) { +function panNumericalScale(scale, delta, limits) { const {min: prevStart, max: prevEnd, options} = scale; const round = options.time && options.time.round; const offset = OFFSETS[round] || 0; diff --git a/test/fixtures/pan/category-x-1.js b/test/fixtures/pan/category-x-1.js new file mode 100644 index 00000000..d4df0fd2 --- /dev/null +++ b/test/fixtures/pan/category-x-1.js @@ -0,0 +1,68 @@ +const labels = []; +const data = []; +for (let i = 1; i <= 100; i++) { + labels.push('Label ' + i); + data.push(Math.sin(i / 100 * Math.PI) * 10); +} + +const canvas = document.createElement('canvas'); +canvas.width = 512; +canvas.height = 512; +const ctx = canvas.getContext('2d'); + +module.exports = { + tolerance: 0.02, + config: { + type: 'bar', + data: { + labels, + datasets: [{ + data, + barPercentage: 1, + categoryPercentage: 1, + backgroundColor: c => `rgba(${255 - c.index * 4}, 0, 0, 1)` + }] + }, + options: { + events: [], + scales: { + x: { + display: false, + min: 'Label 1', + max: 'Label 1' + }, + y: {display: false, max: 10} + }, + plugins: { + legend: false, + tooltip: false, + zoom: { + pan: { + enabled: true, + mode: 'x', + } + } + }, + layout: { + padding: 2 + } + } + }, + options: { + spriteText: true, + run(chart) { + const steps = 16; + const n = Math.sqrt(steps); + const side = 512 / n; + for (let i = 0; i < steps; i++) { + const col = i % n; + const row = Math.floor(i / n); + chart.pan({x: -100}); + chart.update(); + ctx.drawImage(chart.canvas, col * side, row * side, side, side); + } + Chart.helpers.clearCanvas(chart.canvas); + chart.ctx.drawImage(canvas, 0, 0); + } + } +}; diff --git a/test/fixtures/pan/category-x-1.png b/test/fixtures/pan/category-x-1.png new file mode 100644 index 0000000000000000000000000000000000000000..25176c5ca035f10a55a4b867fb56d7c2f54ebe68 GIT binary patch literal 7525 zcmeHMe^8U>9sfRW5{NM1MMjxrkoP8P@8Zc_y-ma_xufSHj$+{b`RRmovDprsm z$&2SsRxQwWYljxXHc#rNhTAAug1qm!dV0!@9I)aLNVJ0FEJ+YZ0wKx1Z=&n&wzd1w z?c6PYCHLg}e4p?0eV^y^W+;vysc#g*AFoXuQ0oRzdG>5W&|i@M0| zlGDFB-Ewr3&KcQS-dFYqOMCT^A(w)ZGaOLz+wynztvgU8rCA_S`b(rp8W@+ZkaKPO z)z65dEDP5$RE&R$qL|0VUyt@j)9{3tg5lUE4&+-Zwg<9Exd?x1hE8JO&|tzUF$EA( zBnhStHbgu*!4vXuUm1FheXhTFN8&Fp>lM|}u&`oN1|{E)h;U|U!Avn{O*f-iCWnQS z3*lU+=7<{VHWJeGVKNLZB_tB*pj67fz(dyEib^S+6+^>L&u2_Z&ojsQB71x5Ci`>~ zCQ^Eig^d?dze=TI+JZxv$youTOD*YnxaK+rmyxmG<%jNIMe~8RO7B)IJ&D1s90te1 zZcnaGj0>#YcGhH>!?-F0ud{{FxiHYLS0$HB{qD*7wVc9csP=u~jHM7)RJ1z=;D)yw z>?Vn=K?rZVt4Z7J+v{t0EVdND$rQ6p+~nv|t&DcsLYQ={UEYk6o2SHP=pW2daxRdv)v$co;|^;}gF@2jsU~)tlCy@qHKb7K3;Juu zij8TDhGv_$<={-J@NtNg{kG@89`8rqJgvLJJh`G0elk-{I%no|POJv^xNM-TFAF}O z!P*_q5LzMBX7JjO;jy|ncF4VV7tWNiH9#?Gkc`iZC)h0s?f@e>D2?KL=d~#?OU{$5 zC?Oo5ZYbBKNrAn-L>!cJ4sbQPF>>7I&xQuddj_`l*w~TYO8h zr^Zi_YY8#VTZjD=xfkzfI$ZX1ZE(Uv*QNduRg`Kj?A4^YZi=yt{~V=E-FGDB$5oB_ zNh{Vr7(&To;t)oJSybWAB0%JOkD==QG_gGpQ>iL%ZT?|mW{fb?=XS0ZPH6+D;$!KA zE4K1r*tOb>3-D*%O$i~-K&RR-!1{7U3?ia}=c&)o+1f5%>aY)*s64B=ySY0`rC5y4 zf6iA`N}9gKCybS$peyN{Rod@Kd*P}>#@^_IcinL?i@fHSnNEddmk4?Hm9#dr?R`lh z*?1vCH@fXU`-$q+DFS67`5+Vvl$cRMZbQCsg`xTj=Wu*~O2<2W3rhPr4Nq+_n7pf+ zc$uyhd^v49KUGRa-h`Q>t|&Enbg9s+(GEQfP;)YOcSiVo(byLWgi z8U`dA7jjdD#OpJ?!h1rp;Db=Jy2wH*Nr1TGK4-Q3Z_Djqg3rOT1e+La;(yru`i9f_ zA-_vyjQFrEt_n~y|p-~$8U+%hsnB`T@)h0v4?_ps2LXoEUx2-^o&&4eF*UMtf1?c1h{#}(VtCXHXx{uA`bX*yPW+UI z8*EOnIl*i7_n_~;aXY?D_Mn;h+0%>D-EK{l_k_~Sqmo~kaW*gFTktoPu97K7hV{U) W$?2cIA^wXB* c.index < 50 ? 'blue' : 'red' + }] + }, + options: { + events: [], + scales: { + x: { + display: false, + min: 'Label 1', + max: 'Label 10', + }, + y: {display: false, max: 10} + }, + plugins: { + legend: false, + tooltip: false, + zoom: { + pan: { + enabled: true, + mode: 'x', + } + } + }, + layout: { + padding: 2 + } + } + }, + options: { + spriteText: true, + run(chart) { + const steps = 16; + const n = Math.sqrt(steps); + const side = 512 / n; + for (let i = 0; i < steps; i++) { + const col = i % n; + const row = Math.floor(i / n); + chart.pan({x: -200}); + chart.update(); + ctx.drawImage(chart.canvas, col * side, row * side, side, side); + } + Chart.helpers.clearCanvas(chart.canvas); + chart.ctx.drawImage(canvas, 0, 0); + } + } +}; diff --git a/test/fixtures/pan/category-x-10.png b/test/fixtures/pan/category-x-10.png new file mode 100644 index 0000000000000000000000000000000000000000..4e21c20c16a7f358f3834fbd4769a11300e66408 GIT binary patch literal 17646 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 literal 0 HcmV?d00001 diff --git a/test/fixtures/pan/category-x-25.js b/test/fixtures/pan/category-x-25.js new file mode 100644 index 00000000..1a74b2b1 --- /dev/null +++ b/test/fixtures/pan/category-x-25.js @@ -0,0 +1,68 @@ +const labels = []; +const data = []; +for (let i = 1; i <= 100; i++) { + labels.push('Label ' + i); + data.push(Math.sin(i / 100 * Math.PI) * 10); +} + +const canvas = document.createElement('canvas'); +canvas.width = 512; +canvas.height = 512; +const ctx = canvas.getContext('2d'); + +module.exports = { + tolerance: 0.02, + config: { + type: 'bar', + data: { + labels, + datasets: [{ + data, + barPercentage: 1, + categoryPercentage: 1, + backgroundColor: c => c.index < 50 ? 'blue' : 'red' + }] + }, + options: { + events: [], + scales: { + x: { + display: false, + min: 'Label 75', + max: 'Label 100', + }, + y: {display: false, max: 10} + }, + plugins: { + legend: false, + tooltip: false, + zoom: { + pan: { + enabled: true, + mode: 'x', + } + } + }, + layout: { + padding: 2 + } + } + }, + options: { + spriteText: true, + run(chart) { + const steps = 16; + const n = Math.sqrt(steps); + const side = 512 / n; + for (let i = 0; i < steps; i++) { + const col = i % n; + const row = Math.floor(i / n); + chart.pan({x: 50}); + chart.update(); + ctx.drawImage(chart.canvas, col * side, row * side, side, side); + } + Chart.helpers.clearCanvas(chart.canvas); + chart.ctx.drawImage(canvas, 0, 0); + } + } +}; diff --git a/test/fixtures/pan/category-x-25.png b/test/fixtures/pan/category-x-25.png new file mode 100644 index 0000000000000000000000000000000000000000..ac8ee4f5fe27e5e72fe06c8426303e8b11da2ba9 GIT binary patch literal 18967 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 c.index < 50 ? 'blue' : 'red' }] }, options: { events: [], scales: { x: { - display: true, + display: false, min: 'Label 1', max: 'Label 5' }, - y: {display: false} + y: {display: false, max: 10} }, plugins: { legend: false, @@ -54,24 +54,15 @@ module.exports = { const steps = 16; const n = Math.sqrt(steps); const side = 512 / n; - return new Promise((resolve) => { - let i = 0; - const next = () => { - if (i < steps) { - const col = i % n; - const row = Math.floor(i / n); - i++; - - ctx.drawImage(chart.canvas, col * side, row * side, side, side); - Simulator.gestures.pan(chart.canvas, {deltaX: -100, deltaY: 0, duration: 25}, next); - } else { - Chart.helpers.clearCanvas(chart.canvas); - chart.ctx.drawImage(canvas, 0, 0); - resolve(); - } - }; - next(); - }); + for (let i = 0; i < steps; i++) { + const col = i % n; + const row = Math.floor(i / n); + chart.pan({x: -200}); + chart.update(); + ctx.drawImage(chart.canvas, col * side, row * side, side, side); + } + Chart.helpers.clearCanvas(chart.canvas); + chart.ctx.drawImage(canvas, 0, 0); } } }; diff --git a/test/fixtures/pan/category-x-5.png b/test/fixtures/pan/category-x-5.png new file mode 100644 index 0000000000000000000000000000000000000000..abab150b4e2812386ffc8267bdc6fb9d7f97dd36 GIT binary patch literal 13583 zcmeHOd011|w%_L@K?D&gA}TUeY7wCXMHv)Kv?|)Fu|<(8LZ|~Of*=lvKu)ZvtteOr zq((qRs09QC1rcAB1FQkBvMy{A1y%-IuSBKb7o9i807Kx*p)MzYPTMi z@;;w-VQBn#HPg=mnF%|u`UR4HKg?hlCY<>3&ChDnoJY7MRSY_3!CW>NnNOS_Rc5d5 zJF|QB@$=`~h8>elx=?kh<9TK0ir+6EDGsU1uIn-^mhan=dU5J8#Y_`YXE&EQ+J6ce z=eOm?GJodiAwu;TCS($d8u@b~KZcm7Dcu^?)^YT0CkP^xGBh9z2%c7&sJpxW`ZRp#Lu0 zBYCD>>>wU>v1%Whwd2hM`eEfYObx_ycK-omTW7bVR%a~AiTynE1pRlmgD|Vzxw$^F zIGKVMy#w_tB$I1J85;qE>67A#UtQI4whj(QqcHb3>6yx`z?{jU$q0 z#ucAqk1(&0t3A~mDKPA4G$flFt?rsoaJk-rTr66jbd zoTo?bL-wyo5VNTSc&5hc+; zquliHBbg)%sb54$sE6#+$HA+g=~k!ZU5RIDAoqi?rVRYqHr)lekMpw~;I+v^k$sK1 zoYPpFHX1yKU~lo)ca-Y)t=@k3};2r!)intQN)F;9z%yj6b`8Mo&hR2UMD zRv~E-)a-cVPh1EHv<-I8Zuxo)i@VSFDQmTfbi0NzTrz@kHfnzm6tJ zAt_-M=HGcz9Z*riJ_HN9U@q50WoS{^FI+I+)g}Ww?~}X2vyo&Duji(hj{tXUOEG>I zHkPR6pn`?`sBwPtz<+=5hLzx?JO|m9*zU&Mz@m<8X6@-OatU}Ky^+$Mjj*VK@cKh+ zUOY#QF=ia%@@or3DuWRO^{H3B2P|7Q18- zDi2ChgGCwev9TXX$1PA>#h`9EY+|fNd`1FiR-)eUr^B5r`SL;3%wO8EFKl!qGSHPw&an!EGtkKJVIWgD`Fe%#D8Mw+d{P^B`*IvT<62L(*u3nb&Pwrx+fD@BA z-m4bTYx2PN!c+g5TYU)ZrepWv6m))SjeP;=($@U0Hts-diQvs1N(0?3eh#68q$b;b1keh$HNY8n^F)q7q`Y0ISAT+4^13& z7fJl)^j!}oF%sER34EM}6jbN=ZcRO5fMkaiqL@WqtCzQ=2c1_q!12;Vc6MAIN+$Z}Du9*9a5@*6dg``57WH#7l; zU<+I?H`c%2oSVJ`EXAX-j~|!|GqCz1m@8|kCBTV)xuN8A`|VosQ|5# zTr)H(dP$ETQw>ebj`eN#ia?joVXCj;jfgiiStvF&88p|@`cWc%HeMwpwXjiH8DgPz z)M*25XOh4f6*63E#fZwRSEnk!wTQT}rX@Z8JmXcu{WzP9aWo*)_93gN*a_Sz+&5H9 zL18BOr2&nfLNL8lmpW=dpN370*~*rBb+nbgR<4ht+6)PQ_qE|??e`iD%iK)$2jW8= z39H0KZS{cNhEa;)F|K^cD(K(e2-8 zkmO7zv$?@H(OYzu(f<^gfCB|QHk9Pq%s^?$a$yNx4=6 zrm1_h-|&nL%x!-a>D?04G$y3E%`>EXaVKZKqukhgrMLt`E5Jt{SmM$tcvN!^i>bEFlRF^)zHlW@0pEtBU4=mydnrm}g zEy5a8r4@GKX+*i5&1;$wVHaD-^&Cf8_l6xa3I2>iD^n~{?f?LtCzmKzf|hEKMtNkP22Y8n0-g(QlSuO`mN}{ITmP9oikg#X;W; zKQa_6r3GE2MDwQ-=byMtKOT3)5sp&Q-KrGSJ=pvF;=OAn#}R-386MUI1@LVn@76mO zdx0Uc{cEDX(m>Jai?B2~D0!47Y-OTn*@)V|2z!CQ9b6K=aw1JLWxDTWinnf1SC&j9 zZhd8?Y!@~2;>xZCcZI1@2Y@De6+)Qys829Y$wa+!#9MbP;$8)z08v=DNQV|fO)hWq z>uy(jT|7n8tJIV63X`&q1Q>SslV(kb<^cp{lMEm6nFobW5dTDuICw1zaS!ukwm|&E z=&Zcjep7un+@a6MT>V}+y?UGo2j8EuFu;dgFAgp0a3;5Nbb=>>#yCyf)rDw)Bcz*B zqi$Y2d;3-|`QD?LP2FkCf4C8Z+hHj!S*`mmv0 zrs1%Vs0{=nEs#I|`|$B12nOeX-Y!j51KpJHUN;?a^8$^xD?9~zCbG%Lmu9ccz>ob; zB_SETEDk&y9FHV3V@4w5XsJHoRQH3q98+~Ti0C%c;}vO~V8<@ruen(rHWk4*mL$im#E(AJN8PaV&bOCkqPV8X z?v0x6d78jLG4q}y9Hl>w_;p9i?QK%8Vz~hf@KM0RybPYaKaP&J5c%wDT4c9VG;mzK z;qwK0FOcTePmzf@Ase)7-x`3hdY~0=3ZCkV!0W6~cay03n%VuMn7%HL>7y?n2IfUh zn-dDvvup{p1E8gC{{w_VWfc}fJ)C$0HMDh!CY^a#3JCro*)8uN0lT@*MtqM|!n3yE zD-akEM8zY}3ws}TuieXAB>G`z;|vyZow@E}p)8INOz$eL=bsQu{qDW0;aaL-5hu_s;!<1dl14cSou6_&L)8~QOWGPv_3yr8V zXJj%~yxhXvu{DO3{}dF}Z4K&gm+}9T^RU$+o3T3IgYYF&xcvq7YxQ!n2Al8t;C`y6 z$9hi0N2+EYlv{d)kW>d1oN^t$=YF-q6Qw)B*D7Qa?P-iqK+RQHvS%(>nICZA75~QU2!x^`La@6q6~Psv%p9>QCfGXrnuu&U-7~- z;KGeRX$`3vfb@z+y!i<*BhYmW(LcIUmWJsEFya$DUqWm@wyac63? zSgb6w@&@%QIqbQ!Ho|P%^gr3lXNa_xWs%B7F^U(cYq`9 z>QZ*mwJxmgwdkA_m&#HEtWxzB^>-t)l3YOuzBoezU(szE2PJ^EEMr3 zN8TW6{@SDcXFV4?w8q{Jd6eAr3>}MQ=gc6SwWs?&A|=nd_+iF(i@Qs;%40T)pKmjO znpLi0ctJ8QZj}dAa6BBK@c(~`JP_zI@a{PhIae(limYXdQP#7nL^dAp+@il4iAF6Y zqIzo&I9r!oFh~3qEK0L5^AlRYQuDN^SmgC=E-pfLw#%sT8Aim06-#OFlD3nuRJV2M)JNH1{o9a#?T4BdF7-+haq;fiDxBDqg88AsWMBTUS9vt}wHwBFCpIg}yely>!X1o{Gf*P3f%HkWIhE&BuvDEn z+SSgje?1Qp*Qg?fGTpTXhFq!Dz&1LVu-KOng1yw8Yak zf{7!wRv=KJw2tfTS5{xXn0OU^AnD8W0BOxD$$4@UK=9xhVcXcbF&JA zlna$R1QXpGlZ^Gmdn~;2k^&VB%bGvvuQkko(UZZY8mRj~qegQQHHCcHxe$6wGs@RM zA7+#YYY{aAtZMb*Q6> zgZ(SJDA=~*h4L6Ip-YnedjoG%Dy;5eZ|$J-_?%ng?dn}%0A_(7>R!I=H+bH<56$4n zEgt#p-0sWTUWywTtj>)^oS@B-FXHe!S3T0A1QR^ILFKngdOPK8UwQkLVTTh^cm&lL zEZAg+dYjalgvqif=p=u6we?P%&`vRbSHL{^F!g>tu(F=+80zWfe}gEP*7z{OLbu}} zvHZ}LPYlz_M3U4sMz_FGy40)7d z!2RS0qa~Xd<#7><6FA=e<}c(qNb(JD1dP-y4%2=NpvhYXGaCJUVCey=J(T02@bSNP z3j%XHW^o5q-q46R4}%KnZA`k)FcGEqZ~ezYndEN@`P)dkSO2GXi;|7WoPY25fvO<+ z7ZxN{voHVi?28I~D)9Z=2Cr1$Q-MzfKGg)oUodjojv6Xqrg6yj($L0e_>T#vj>-{E zu^|JcIdXktBtT-IKJ5cuu(tR5gqzDYf6$Oe@)V<;4XkYoa+b=g&AZoxlCR E04-q)$^ZZW literal 0 HcmV?d00001 diff --git a/test/fixtures/pan/category-x-50.js b/test/fixtures/pan/category-x-50.js new file mode 100644 index 00000000..48bf941a --- /dev/null +++ b/test/fixtures/pan/category-x-50.js @@ -0,0 +1,67 @@ +const labels = []; +const data = []; +for (let i = 1; i <= 100; i++) { + labels.push('Label ' + i); + data.push(Math.sin(i / 100 * Math.PI) * 10); +} + +const canvas = document.createElement('canvas'); +canvas.width = 512; +canvas.height = 512; +const ctx = canvas.getContext('2d'); + +module.exports = { + tolerance: 0.02, + config: { + type: 'bar', + data: { + labels, + datasets: [{ + data, + barPercentage: 1, + categoryPercentage: 1, + backgroundColor: c => c.index < 50 ? 'blue' : 'red' + }] + }, + options: { + events: [], + scales: { + x: { + display: false, + min: 'Label 50', + max: 'Label 100', + }, + y: {display: false, max: 10} + }, + plugins: { + legend: false, + tooltip: false, + zoom: { + pan: { + enabled: true, + mode: 'x', + } + } + }, + layout: { + padding: 2 + } + } + }, + options: { + run(chart) { + const steps = 16; + const n = Math.sqrt(steps); + const side = 512 / n; + for (let i = 0; i < steps; i++) { + const col = i % n; + const row = Math.floor(i / n); + chart.pan({x: 25}); + chart.update(); + ctx.drawImage(chart.canvas, col * side, row * side, side, side); + } + Chart.helpers.clearCanvas(chart.canvas); + chart.ctx.drawImage(canvas, 0, 0); + } + } +}; diff --git a/test/fixtures/pan/category-x-50.png b/test/fixtures/pan/category-x-50.png new file mode 100644 index 0000000000000000000000000000000000000000..83ec882fbe35eb8f06a18e39069e2e3d4cfcdd47 GIT binary patch literal 23174 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 E3r(YrCjbBd diff --git a/test/specs/defaults.spec.js b/test/specs/defaults.spec.js index 803eba08..cce2ca2c 100644 --- a/test/specs/defaults.spec.js +++ b/test/specs/defaults.spec.js @@ -3,7 +3,6 @@ describe('defaults', function() { pan: { enabled: false, mode: 'xy', - speed: 20, threshold: 10, modifierKey: null, }, diff --git a/types/options.d.ts b/types/options.d.ts index 2f345617..46cc7afc 100644 --- a/types/options.d.ts +++ b/types/options.d.ts @@ -88,11 +88,6 @@ export interface PanOptions { overScaleMode?: Mode | { (char: Chart): Mode }; - /** - * On category scale, factor of pan velocity - */ - speed?: number; - /** * Minimal pan distance required before actually applying pan */ From be5f3a0a8d2bf293e8e1b24905d591231baca87e Mon Sep 17 00:00:00 2001 From: Jukka Kurkela Date: Wed, 28 Apr 2021 17:12:03 +0300 Subject: [PATCH 2/2] Restore hammer-simulator for one test --- karma.conf.js | 1 + package-lock.json | 13 +++++++++++++ package.json | 1 + test/fixtures/pan/category-x-5.js | 27 ++++++++++++++++++--------- test/fixtures/pan/category-x-5.png | Bin 13583 -> 13322 bytes 5 files changed, 33 insertions(+), 9 deletions(-) diff --git a/karma.conf.js b/karma.conf.js index 5a3cf5a9..f814d2a0 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -60,6 +60,7 @@ module.exports = function(karma) { {pattern: 'test/fixtures/**/*.json', included: false}, {pattern: 'test/fixtures/**/*.png', included: false}, {pattern: 'node_modules/chart.js/dist/chart.js'}, + {pattern: 'node_modules/hammer-simulator/index.js'}, {pattern: 'node_modules/hammerjs/hammer.js'}, {pattern: 'node_modules/chartjs-adapter-date-fns/dist/chartjs-adapter-date-fns.bundle.js'}, {pattern: 'test/index.js'}, diff --git a/package-lock.json b/package-lock.json index e2d1060a..40721e19 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,6 +26,7 @@ "eslint-plugin-es": "^4.1.0", "eslint-plugin-html": "^6.1.2", "eslint-plugin-markdown": "^2.0.1", + "hammer-simulator": "^0.0.1", "jasmine": "^3.7.0", "karma": "^6.3.2", "karma-chrome-launcher": "^3.1.0", @@ -8165,6 +8166,12 @@ "node": ">=6.0" } }, + "node_modules/hammer-simulator": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/hammer-simulator/-/hammer-simulator-0.0.1.tgz", + "integrity": "sha1-7tO85CtDMgF1o/T4NP4gjl+iSho=", + "dev": true + }, "node_modules/hammerjs": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/hammerjs/-/hammerjs-2.0.8.tgz", @@ -24601,6 +24608,12 @@ "strip-bom-string": "^1.0.0" } }, + "hammer-simulator": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/hammer-simulator/-/hammer-simulator-0.0.1.tgz", + "integrity": "sha1-7tO85CtDMgF1o/T4NP4gjl+iSho=", + "dev": true + }, "hammerjs": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/hammerjs/-/hammerjs-2.0.8.tgz", diff --git a/package.json b/package.json index c31604e0..fe6e4817 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ "eslint-plugin-es": "^4.1.0", "eslint-plugin-html": "^6.1.2", "eslint-plugin-markdown": "^2.0.1", + "hammer-simulator": "^0.0.1", "jasmine": "^3.7.0", "karma": "^6.3.2", "karma-chrome-launcher": "^3.1.0", diff --git a/test/fixtures/pan/category-x-5.js b/test/fixtures/pan/category-x-5.js index af1e2eea..19210de0 100644 --- a/test/fixtures/pan/category-x-5.js +++ b/test/fixtures/pan/category-x-5.js @@ -54,15 +54,24 @@ module.exports = { const steps = 16; const n = Math.sqrt(steps); const side = 512 / n; - for (let i = 0; i < steps; i++) { - const col = i % n; - const row = Math.floor(i / n); - chart.pan({x: -200}); - chart.update(); - ctx.drawImage(chart.canvas, col * side, row * side, side, side); - } - Chart.helpers.clearCanvas(chart.canvas); - chart.ctx.drawImage(canvas, 0, 0); + return new Promise((resolve) => { + let i = 0; + const next = () => { + if (i < steps) { + const col = i % n; + const row = Math.floor(i / n); + i++; + + ctx.drawImage(chart.canvas, col * side, row * side, side, side); + Simulator.gestures.pan(chart.canvas, {deltaX: -350, deltaY: 0, duration: 50}, next); + } else { + Chart.helpers.clearCanvas(chart.canvas); + chart.ctx.drawImage(canvas, 0, 0); + resolve(); + } + }; + next(); + }); } } }; diff --git a/test/fixtures/pan/category-x-5.png b/test/fixtures/pan/category-x-5.png index abab150b4e2812386ffc8267bdc6fb9d7f97dd36..4d7d19954021b240a3203affa4a77fb0a21b2e93 100644 GIT binary patch literal 13322 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%0A_(7>R!I=H+bH<56$4n zEgt#p-0sWTUWywTtj>)^oS@B-FXHe!S3T0A1QR^ILFKngdOPK8UwQkLVTTh^cm&lL zEZAg+dYjalgvqif=p=u6we?P%&`vRbSHL{^F!g>tu(F=+80zWfe}gEP*7z{OLbu}} zvHZ}LPYlz_M3U4sMz_FGy40)7d z!2RS0qa~Xd<#7><6FA=e<}c(qNb(JD1dP-y4%2=NpvhYXGaCJUVCey=J(T02@bSNP z3j%XHW^o5q-q46R4}%KnZA`k)FcGEqZ~ezYndEN@`P)dkSO2GXi;|7WoPY25fvO<+ z7ZxN{voHVi?28I~D)9Z=2Cr1$Q-MzfKGg)oUodjojv6Xqrg6yj($L0e_>T#vj>-{E zu^|JcIdXktBtT-IKJ5cuu(tR5gqzDYf6$Oe@)V<;4XkYoa+b=g&AZoxlCR E04-q)$^ZZW