From 762dd88144a8c249206a22665fe74df0d41f509b Mon Sep 17 00:00:00 2001 From: gwyneblaidd Date: Fri, 8 Feb 2019 14:00:31 +0200 Subject: [PATCH] FLoat-bar support. _autoSkipp rolled back minbarlength. float-bar start fix start fix fix fix fixes fix fix fix fixes unittests comment removed reverse of borderSkipped --- src/controllers/controller.bar.js | 24 ++++++---- src/core/core.scale.js | 38 +++++++++++++++ src/scales/scale.linear.js | 34 ++++++------- src/scales/scale.logarithmic.js | 28 +++++------ .../floatBar/float-bar-horizontal.json | 43 +++++++++++++++++ .../floatBar/float-bar-horizontal.png | Bin 0 -> 8239 bytes .../float-bar-stacked-horizontal.json | 45 ++++++++++++++++++ .../floatBar/float-bar-stacked-horizontal.png | Bin 0 -> 7631 bytes .../floatBar/float-bar-stacked.json | 43 +++++++++++++++++ .../floatBar/float-bar-stacked.png | Bin 0 -> 7583 bytes .../controller.bar/floatBar/float-bar.json | 43 +++++++++++++++++ .../controller.bar/floatBar/float-bar.png | Bin 0 -> 8018 bytes 12 files changed, 258 insertions(+), 40 deletions(-) create mode 100644 test/fixtures/controller.bar/floatBar/float-bar-horizontal.json create mode 100644 test/fixtures/controller.bar/floatBar/float-bar-horizontal.png create mode 100644 test/fixtures/controller.bar/floatBar/float-bar-stacked-horizontal.json create mode 100644 test/fixtures/controller.bar/floatBar/float-bar-stacked-horizontal.png create mode 100644 test/fixtures/controller.bar/floatBar/float-bar-stacked.json create mode 100644 test/fixtures/controller.bar/floatBar/float-bar-stacked.png create mode 100644 test/fixtures/controller.bar/floatBar/float-bar.json create mode 100644 test/fixtures/controller.bar/floatBar/float-bar.png diff --git a/src/controllers/controller.bar.js b/src/controllers/controller.bar.js index 992333a25c2..ad9946a3078 100644 --- a/src/controllers/controller.bar.js +++ b/src/controllers/controller.bar.js @@ -162,6 +162,10 @@ module.exports = DatasetController.extend({ label: me.chart.data.labels[index] }; + if (helpers.isArray(dataset.data[index])) { + rectangle._model.borderSkipped = null; + } + me._updateElementGeometry(rectangle, index, reset); rectangle.pivot(); @@ -285,12 +289,13 @@ module.exports = DatasetController.extend({ var scale = me._getValueScale(); var isHorizontal = scale.isHorizontal(); var datasets = chart.data.datasets; - var value = +scale.getRightValue(datasets[datasetIndex].data[index]); + var value = scale._parseValue(datasets[datasetIndex].data[index]); var minBarLength = scale.options.minBarLength; var stacked = scale.options.stacked; var stack = meta.stack; - var start = 0; - var i, imeta, ivalue, base, head, size; + var start = value.start === undefined ? 0 : value.max >= 0 && value.min >= 0 ? value.min : value.max; + var length = value.start === undefined ? value.end : value.max >= 0 && value.min >= 0 ? value.max - value.min : value.min - value.max; + var i, imeta, ivalue, base, head, size, stackLength; if (stacked || (stacked === undefined && stack !== undefined)) { for (i = 0; i < datasetIndex; ++i) { @@ -301,8 +306,10 @@ module.exports = DatasetController.extend({ imeta.controller._getValueScaleId() === scale.id && chart.isDatasetVisible(i)) { - ivalue = +scale.getRightValue(datasets[i].data[index]); - if ((value < 0 && ivalue < 0) || (value >= 0 && ivalue > 0)) { + stackLength = scale._parseValue(datasets[i].data[index]); + ivalue = stackLength.start === undefined ? stackLength.end : stackLength.min >= 0 && stackLength.max >= 0 ? stackLength.max : stackLength.min; + + if ((value.min < 0 && ivalue < 0) || (value.max >= 0 && ivalue > 0)) { start += ivalue; } } @@ -310,12 +317,12 @@ module.exports = DatasetController.extend({ } base = scale.getPixelForValue(start); - head = scale.getPixelForValue(start + value); + head = scale.getPixelForValue(start + length); size = head - base; if (minBarLength !== undefined && Math.abs(size) < minBarLength) { size = minBarLength; - if (value >= 0 && !isHorizontal || value < 0 && isHorizontal) { + if (length >= 0 && !isHorizontal || length < 0 && isHorizontal) { head = base - minBarLength; } else { head = base + minBarLength; @@ -366,7 +373,8 @@ module.exports = DatasetController.extend({ helpers.canvas.clipArea(chart.ctx, chart.chartArea); for (; i < ilen; ++i) { - if (!isNaN(scale.getRightValue(dataset.data[i]))) { + var val = scale._parseValue(dataset.data[i]); + if (!isNaN(val.min) && !isNaN(val.max)) { rects[i].draw(); } } diff --git a/src/core/core.scale.js b/src/core/core.scale.js index 1f65bc564b6..aa8879928a5 100644 --- a/src/core/core.scale.js +++ b/src/core/core.scale.js @@ -523,6 +523,10 @@ module.exports = Element.extend({ if ((typeof rawValue === 'number' || rawValue instanceof Number) && !isFinite(rawValue)) { return NaN; } + // Float-bar support. Handling arrays + if (helpers.isArray(rawValue)) { + return [+this.getRightValue(rawValue[0]), +this.getRightValue(rawValue[1])]; + } // If it is in fact an object, dive in one more level if (rawValue) { if (this.isHorizontal()) { @@ -538,6 +542,40 @@ module.exports = Element.extend({ return rawValue; }, + _parseValue: function(raw) { + var value, start, end, min, max; + + if (helpers.isArray(raw)) { + value = this.getRightValue(raw); + start = value[0]; + end = value[1]; + min = Math.min(start, end); + max = Math.max(start, end); + } else { + value = +this.getRightValue(raw); + start = undefined; + end = value; + min = value; + max = value; + } + + return { + min: min, + max: max, + start: start, + end: end + }; + }, + + getScaleLabel: function(rawValue) { + var v = this._parseValue(rawValue); + if (v.start !== undefined) { + return '[' + v.start + ', ' + v.end + ']'; + } + + return +this.getRightValue(rawValue); + }, + /** * Used to get the value to display in the tooltip for the data at the given index * @param index diff --git a/src/scales/scale.linear.js b/src/scales/scale.linear.js index a2199b66e78..b1e47e3a01d 100644 --- a/src/scales/scale.linear.js +++ b/src/scales/scale.linear.js @@ -70,20 +70,25 @@ module.exports = LinearScaleBase.extend({ if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) { helpers.each(dataset.data, function(rawValue, index) { - var value = +me.getRightValue(rawValue); - if (isNaN(value) || meta.data[index].hidden) { + var value = me._parseValue(rawValue); + + if (isNaN(value.min) || isNaN(value.max) || meta.data[index].hidden) { return; } positiveValues[index] = positiveValues[index] || 0; negativeValues[index] = negativeValues[index] || 0; + if (value.min === 0 && !opts.ticks.beginAtZero) { + value.min = value.max; + } + if (opts.relativePoints) { positiveValues[index] = 100; - } else if (value < 0) { - negativeValues[index] += value; + } else if (value.min < 0 || value.max < 0) { + negativeValues[index] += value.min; } else { - positiveValues[index] += value; + positiveValues[index] += value.max; } }); } @@ -102,21 +107,18 @@ module.exports = LinearScaleBase.extend({ var meta = chart.getDatasetMeta(datasetIndex); if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) { helpers.each(dataset.data, function(rawValue, index) { - var value = +me.getRightValue(rawValue); - if (isNaN(value) || meta.data[index].hidden) { + var value = me._parseValue(rawValue); + + if (isNaN(value.min) || isNaN(value.max) || meta.data[index].hidden) { return; } - if (me.min === null) { - me.min = value; - } else if (value < me.min) { - me.min = value; + if (me.min === null || me.min > value.min) { + me.min = value.min; } - if (me.max === null) { - me.max = value; - } else if (value > me.max) { - me.max = value; + if (me.max === null || me.max < value.max) { + me.max = value.max; } }); } @@ -151,7 +153,7 @@ module.exports = LinearScaleBase.extend({ }, getLabelForIndex: function(index, datasetIndex) { - return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]); + return this.getScaleLabel(this.chart.data.datasets[datasetIndex].data[index]); }, // Utils diff --git a/src/scales/scale.logarithmic.js b/src/scales/scale.logarithmic.js index fd67f0b19a4..9f9252d773b 100644 --- a/src/scales/scale.logarithmic.js +++ b/src/scales/scale.logarithmic.js @@ -118,13 +118,13 @@ module.exports = Scale.extend({ helpers.each(dataset.data, function(rawValue, index) { var values = valuesPerStack[key]; - var value = +me.getRightValue(rawValue); + var value = me._parseValue(rawValue); // invalid, hidden and negative values are ignored - if (isNaN(value) || meta.data[index].hidden || value < 0) { + if (isNaN(value.min) || isNaN(value.max) || meta.data[index].hidden || value.max < 0 || value.max < 0) { return; } values[index] = values[index] || 0; - values[index] += value; + values[index] += value.max; }); } }); @@ -143,26 +143,22 @@ module.exports = Scale.extend({ var meta = chart.getDatasetMeta(datasetIndex); if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) { helpers.each(dataset.data, function(rawValue, index) { - var value = +me.getRightValue(rawValue); + var value = me._parseValue(rawValue); // invalid, hidden and negative values are ignored - if (isNaN(value) || meta.data[index].hidden || value < 0) { + if (isNaN(value.min) || isNaN(value.max) || meta.data[index].hidden || value.min < 0 || value.max < 0) { return; } - if (me.min === null) { - me.min = value; - } else if (value < me.min) { - me.min = value; + if (me.min === null || me.min > value.min) { + me.min = value.min; } - if (me.max === null) { - me.max = value; - } else if (value > me.max) { - me.max = value; + if (me.max === null || me.max < value.max) { + me.max = value.max; } - if (value !== 0 && (me.minNotZero === null || value < me.minNotZero)) { - me.minNotZero = value; + if (value.min !== 0 && (me.minNotZero === null || value.min < me.minNotZero)) { + me.minNotZero = value.min; } }); } @@ -247,7 +243,7 @@ module.exports = Scale.extend({ // Get the correct tooltip label getLabelForIndex: function(index, datasetIndex) { - return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]); + return this.getScaleLabel(this.chart.data.datasets[datasetIndex].data[index]); }, getPixelForTick: function(index) { diff --git a/test/fixtures/controller.bar/floatBar/float-bar-horizontal.json b/test/fixtures/controller.bar/floatBar/float-bar-horizontal.json new file mode 100644 index 00000000000..040a6867122 --- /dev/null +++ b/test/fixtures/controller.bar/floatBar/float-bar-horizontal.json @@ -0,0 +1,43 @@ +{ + "config": { + "type": "horizontalBar", + "data": { + "labels": ["2030", "2034", "2038", "2042"], + "datasets": [{ + "backgroundColor": "#FF6384", + "data": [11, [6,2], [-4,-7], -2] + }, { + "backgroundColor": "#36A2EB", + "data": [[1,2], [3,4], [-2,-3], [1,4]] + }, { + "backgroundColor": "#FFCE56", + "data": [[0,1], [1,2], [-2,-1], [1,-7]] + }] + }, + "options": { + "title": false, + "legend": false, + "scales": { + "xAxes": [{ + "ticks": { + "source": "labels", + "display": false + } + }], + "yAxes": [{ + "ticks": { + "display": false, + "beginAtZero": true + } + }] + } + } + }, + "debug": false, + "options": { + "canvas": { + "height": 256, + "width": 512 + } + } +} diff --git a/test/fixtures/controller.bar/floatBar/float-bar-horizontal.png b/test/fixtures/controller.bar/floatBar/float-bar-horizontal.png new file mode 100644 index 0000000000000000000000000000000000000000..389c135e6a8c87abdc601f14040c75801e51fad4 GIT binary patch literal 8239 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 Q-_;nkloba(BZJE9v`YSH zQ;{i(qW<2W*h-YYNEkhOk{>}3>@E(Jy|BNR5=j6kgh?ilAqp4f>Qi^K>i^8u1@z(9>>pUA6V1&+~(%aGQ;{rPE>C)DB^ z@A-0yDhkKZa7mCHufJ}h^$KiR$TGp3cmgLlsl(_&t&DYLUIwJ$v+t?-aU|UaU*4dy zAZ<_l(ANcNoL=2@6||lPI1EJeKrISxamF5Myd58tg^>qDX|US?pTI6cE5gg880xx8 z46@nb+?=4kpu2-wUaaxe@d1zwXy($r%mH`MRKS{AVbR;hIZhFrhZ?v7o|#*84aj@~ z)I9yqnD5939C5mox2PuMCJq+M_J#g|fVb~wtnBl6)t6wxTu9w*CF+|XJ6_x5INHKb zP&b^h*~U*h+B zX5g%y?Xm7y350<9a)rC23@W!Z9-n1)`JLwfIpM-J^6!Mpx&-O38ur-lAX4r%pJtmM RE(E|I9Zh|Wr)t!|e*;_8z)S!D literal 0 HcmV?d00001 diff --git a/test/fixtures/controller.bar/floatBar/float-bar-stacked-horizontal.json b/test/fixtures/controller.bar/floatBar/float-bar-stacked-horizontal.json new file mode 100644 index 00000000000..a1f06925272 --- /dev/null +++ b/test/fixtures/controller.bar/floatBar/float-bar-stacked-horizontal.json @@ -0,0 +1,45 @@ +{ + "config": { + "type": "horizontalBar", + "data": { + "labels": ["2030", "2034", "2038", "2042"], + "datasets": [{ + "backgroundColor": "#FF6384", + "data": [11, [6,2], [-4,-7], -2] + }, { + "backgroundColor": "#36A2EB", + "data": [[1,2], [3,4], [-2,-3], [1,4]] + }, { + "backgroundColor": "#FFCE56", + "data": [[0,1], [1,2], [-2,-1], [1,-7]] + }] + }, + "options": { + "title": false, + "legend": false, + "scales": { + "xAxes": [{ + "stacked": true, + "ticks": { + "source": "labels", + "display": false + } + }], + "yAxes": [{ + "stacked": true, + "ticks": { + "display": false, + "beginAtZero": true + } + }] + } + } + }, + "debug": false, + "options": { + "canvas": { + "height": 256, + "width": 512 + } + } +} diff --git a/test/fixtures/controller.bar/floatBar/float-bar-stacked-horizontal.png b/test/fixtures/controller.bar/floatBar/float-bar-stacked-horizontal.png new file mode 100644 index 0000000000000000000000000000000000000000..40207caa2697d26a46a4837de8fd2d3e6487c09a GIT binary patch literal 7631 zcmeI1X;hQf*2hmmi~$V|h@uPiO2|n70I?mAM{I+na@jx|4xLRc5-`{J`K~4&U36**7^ef8iJQ zaK(|~5?LyDV*hs4U3i)^d$X^LUt69VH-M$geAIAWy-4Vb_S-1OqPDY#pBWx|KOpX4 z+FXK^QKnH=_r{05Yhw==4^>l!GzNGECGUyWB zE8Ic~C5e-9E>72_iO1L8_FaeHwHcLyhy*>y*M2#jC5yLKMx~gjCLQ{Y#6smZV93#F zBmU8;@-#wC6bQStu1ZtpYRc8GNs;h^v_M&38E`=yR1TqtHElBihGEg;4iPMe(b};s zK$B5;!)XAGuX%+fCsMqV^>3ME(92kr_kY|BtPgf4Q=>O{OZ#3ph0Udcke%{(uID2j z;3`<)zFdJQAh?U6?I`F9f8bY;wpH+hd<<{wb`o<|{Muhpn@LRHx#94Dwy~dEnEeSQ zlT1##By(<|McB*_>X;6mchnW_o7_Wju4MDx_l0XOxDNzx-3nZ_cNV=_ejBPjvNS4*s?$1q&xjJ7uKjMh|0XA>>4IozhVSje8+#d8vJlsvUwrz= z)JVh#sdY4~#CCm0Hn8c~o+*58Pn(o69bFA)tCwhaQwf0-4Cr`>x&P?zf5N$-dqa;g zoLQ8XE)qop$@vM#Y+JCU>ecZ8bwbWN2!#QN-5zRBb8_Wrl-R8Z%yW&wISdXU-Mehy z?L@%An@%VP9Bs|x zSF6;D5OBpv)9~NksgD5&JlIN2m9@DbCiv`G$-u1DWJl%@x?}l4G0PeK|Gh@nt>~!N zotmm)3a7e9j!lOKa%JauD}#ilL9@{b8@LA!XKP;URw{v2;nt(62{-P>vpxHm44SMB zTXC`0K6T>;w*0{P<#gcJLI)xg(@zTDkt=y(UEmbubC6Lb;V8~+Y5Y^9A zza2ZegPdWAAtzXUlUDBQB7QPWil$)RE>tij0z0}q0wcCP+H0GP-dZQ$b?|~p!DQeX z>X3I0Q5>ds{w zsp{R>gdl`pu}6@OuE`l+AuUvP)epQ)wA^}$65fR8qyG(d7V!ZyaDvh3A$eK# zzP%(zF73=!U}YTTRjBFm+PI_TRxcXAUyW!I;YFCYiFNkVi2^-|Gg*DMGg%b7LIh?! z6XwmzxY5(MX}9$uNT@T(4Rv4NF+*}Bw-bS$eSxJ(veUrhki}u_7{z>;dsN!A5lt^K z%2M(&I&-fK2WGh(OBQRwXC!ITPwLjZazy-oI``vOl{Ur{3x~O#0btMD>_Mk|Eer7Xvb_2h}}Q2S6^V`JNO&<}~4v z?puObPET`Oe%29ckyx-vp!dDeK$1a|oB@a~KX)NhwuzvLj8&O@-GC|Gc>MuW4`9f7 zYIVsa$WzEw72;$}Pg-Ti;==tDln9Kvh}umMyUB0~Xc9qyz+ravXF&;wL=_{D+XEw# zn)if4dgY;|Xv(8Wil)HjXDN6OGG`?xj{^yK{GlG4+MG+3G|kQvg*S}`L(ja1)geV~ zU2$+yB`uFo$LR`)>Nw@)VV0A&ywd*7zIk_XMThodw^_Q*LQd7(wU}1lA-XJYuGO3n zSjoy-7!qigOqIU6rfxfTU}UQQur7b_%xQDc@Q(J;$uHW+StCcLyB%}{gGz0Zhnea+ z-R{CiWy2#g@dHB2PlA_IcAq2)j&@dCP&@V{fXklE{Y=NeuJj-2xm1*!<9}^WqbyBY zY1UV|>}apA;Am(9GB(sYv8U)5%_<5`=c-ntnHm`i1kuh^Q3k#7C~>5X_06X{3@rWZXl&ChR|pwhtZ2ht7fuo|7JQD@a%$ z%u`_OGHaAUq{qqio%gCuk1u8E*I>!9Hq`6VkfsmuHDmsAi0ZF}M>&t)ALZnp7sI`^ zQ|z-ykIU#4WO`)WgU!q9-DycqhBr|RMSCdCe)7C?eRtKXb1Uo?6HN+ihPlU>1ys%} zmp)h-+&{~HP`2vchGU8gv+jM`qT~MaY&XXR<&udy$Eo4$`8Nq0%oQX@3PgF2=eu8A zYs@>G?Z+KwbLQKbb~jmt3(CZeMZNoox|3^6y%-;LUFrs=P9zWXOvHg6+qii`4W-Qy z;Skti9bDuVe$KvQs=qVZr>!t2C}5hqFo-1vkJbcvIajXXPE^i1`f$%ZthGHFAe?zz zd_G{JlWEhJTrne04!)e0<<+vZ>;8u}Q4QrbcrwG|HcpJKh!%O| zkKa_|KhB;_E%6<$bDR;DJQ1j$4KJG*9|`8UO=kUxT2Vt`fUxO0C`D@H0tUUIaFkw> zM_Zt}L*Z*#TJ^UqRIF<{?YgZFNI_D0m=UY4X^E4xe?qtDJ2ee+**d>eNAA%sN%E*1R35ft}8=6ji`=RD;6-jgyrX+}t<-2i} z6H;np0bSqVAz*BGC=(pzvY+}SN~hyq)=8xLqd8g+PQ1dF;{Ild3{tE94idHj3ynh< zs1R1b_c5UC59s6?>n(;0YgwOKjsOZ}*0#XGp`Ga_M4+62AANp6)`YAeLa8%XA*d{tdR5Tb)Lx zpXts&=_AbsNc?R)ngliW(~(Fsk@`YUI6dh562Bp5uDR~qAyf7G??xLZMkh-a*nK+| z2*vzJpzEXw-Mrt-PgfZgpuD%P57i;MBt>)axDcVO9h&%?R~vO3b=)9*IvGkN7v~Gt z;CDI8-$4(1IWNm=VtGIOU)BPppk|+^ovtNatFmq!n+O&Op6uXmEbdh^pAYx#P*J)# zRiEwGR>sn;S}EeEa%S(u@aC~B{vrMz_wEPpg5L*I{murpb;8bF6ykWpQPgA7F5E|B zK2lgZ|M(mX)jTen*ZcvXyjlp*4+kWl|KJljqD<($hTu6l5~`wo78UCmix&h`hvnzt z5tGz27GkO1R{3R>+hu(s`J!X`AApLsgN`Hg6@RBuGxe;9UW;`7Q*LDq|1=6;_1Z_L z>Xna9O>Ur=VE@#3ls-V9aAa_44X%Gq9(tUc!xn#7EX%k%#&k3Q^n3#>M;< z`x`M(Ilg#%eLWmw2sRnru)%N|VDI>6xAcF@{H2Ok=KnH%GOnocE`TrNeP#w(dyj|w E9qzPom;e9( literal 0 HcmV?d00001 diff --git a/test/fixtures/controller.bar/floatBar/float-bar-stacked.json b/test/fixtures/controller.bar/floatBar/float-bar-stacked.json new file mode 100644 index 00000000000..d721f3f1079 --- /dev/null +++ b/test/fixtures/controller.bar/floatBar/float-bar-stacked.json @@ -0,0 +1,43 @@ +{ + "config": { + "type": "bar", + "data": { + "labels": ["2030", "2034", "2038", "2042"], + "datasets": [{ + "backgroundColor": "#FF6384", + "data": [11, [6,2], [-4,-7], -2] + }, { + "backgroundColor": "#36A2EB", + "data": [[1,2], [3,4], [-2,-3], [1,4]] + }, { + "backgroundColor": "#FFCE56", + "data": [[0,1], [1,2], [-2,-1], [1,-7]] + }] + }, + "options": { + "title": false, + "legend": false, + "scales": { + "xAxes": [{ + "stacked": true, + "ticks": { + "display": false + } + }], + "yAxes": [{ + "stacked": true, + "ticks": { + "display": false + } + }] + } + } + }, + "debug": false, + "options": { + "canvas": { + "height": 256, + "width": 512 + } + } +} diff --git a/test/fixtures/controller.bar/floatBar/float-bar-stacked.png b/test/fixtures/controller.bar/floatBar/float-bar-stacked.png new file mode 100644 index 0000000000000000000000000000000000000000..2ad016193824500ddc76c3d7e1ed8d2aa1e0437c GIT binary patch literal 7583 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 EH(N$QGSYOvR&}BJmr+jkwT=(S4V*ZhPij|fJ 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 literal 0 HcmV?d00001