diff --git a/demo/demo.js b/demo/demo.js index 1f577f2ad..554fa2423 100644 --- a/demo/demo.js +++ b/demo/demo.js @@ -5684,6 +5684,50 @@ setTimeout(function() { } } }, + GaugeMinMax: [ + { + options: { + data: { + columns: [ + ["data1", 60] + ], + type: "gauge" + }, + gauge: { + min: 30, + max: 90 + } + } + }, + { + options: { + data: { + columns: [ + ["data1", 30] + ], + type: "gauge" + }, + gauge: { + enforceMinMax: true, + min: 50 + } + } + }, + { + options: { + data: { + columns: [ + ["data1", 120] + ], + type: "gauge" + }, + gauge: { + enforceMinMax: true, + max: 100 + } + } + }, + ], GaugeLabelMultiline: { options: { data: { diff --git a/src/ChartInternal/shape/arc.ts b/src/ChartInternal/shape/arc.ts index e6c27bdc7..be202cf57 100644 --- a/src/ChartInternal/shape/arc.ts +++ b/src/ChartInternal/shape/arc.ts @@ -299,7 +299,7 @@ export default { d.endAngle = d.startAngle; } - if (d.data && $$.hasMultiArcGauge()) { + if (d.data && (config.gauge_enforceMinMax || $$.hasMultiArcGauge())) { const gMin = config.gauge_min; const gMax = config.gauge_max; const gTic = radius / (gMax - gMin); diff --git a/src/ChartInternal/shape/gauge.ts b/src/ChartInternal/shape/gauge.ts index fa2f7b7a7..17883560b 100644 --- a/src/ChartInternal/shape/gauge.ts +++ b/src/ChartInternal/shape/gauge.ts @@ -43,7 +43,9 @@ export default { $$.getMinMaxData().max[0].value : $$.getTotalDataSum(state.rendered); // if gauge_max less than max, make max to max value - if (max + config.gauge_min * (config.gauge_min > 0 ? -1 : 1) > config.gauge_max) { + if (!config.gauge_enforceMinMax && ( + max + config.gauge_min * (config.gauge_min > 0 ? -1 : 1) > config.gauge_max + )) { config.gauge_max = max - config.gauge_min; } }, diff --git a/src/config/Options/shape/gauge.ts b/src/config/Options/shape/gauge.ts index 66e422a40..2f3f793a1 100644 --- a/src/config/Options/shape/gauge.ts +++ b/src/config/Options/shape/gauge.ts @@ -25,6 +25,9 @@ export default { * @property {boolean} [gauge.expand=true] Enable or disable expanding gauge. * @property {number} [gauge.expand.rate=0.98] Set expand rate. * @property {number} [gauge.expand.duration=50] Set the expand transition time in milliseconds. + * @property {boolean} [gauge.enforceMinMax=false] Enforce to given min/max value. + * - When `gauge.min=50` and given value is `30`, gauge will render as empty value. + * - When `gauge.max=100` and given value is `120`, gauge will render till 100, not surpassing max value. * @property {number} [gauge.min=0] Set min value of the gauge. * @property {number} [gauge.max=100] Set max value of the gauge. * @property {number} [gauge.startingAngle=-1 * Math.PI / 2] Set starting angle where data draws. @@ -55,6 +58,7 @@ export default { * - single * - multi * @property {number} [gauge.arcs.minWidth=5] Set minimal width of gauge arcs until the innerRadius disappears. + * @see [Demo: enforceMinMax, min/max](https://naver.github.io/billboard.js/demo/#GaugeChartOptions.GaugeMinMax) * @see [Demo: archLength](https://naver.github.io/billboard.js/demo/#GaugeChartOptions.GaugeArcLength) * @see [Demo: startingAngle](https://naver.github.io/billboard.js/demo/#GaugeChartOptions.GaugeStartingAngle) * @example @@ -90,6 +94,11 @@ export default { * rate: 1 * }, * + * // enforce min/max value. + * // when given value < min, will render as empty value. + * // when value > max, will render to given max value not surpassing it. + * enforceMinMax: true, + * * min: -100, * max: 200, * type: "single" // or 'multi' @@ -113,6 +122,7 @@ export default { gauge_label_format: <(() => string)|undefined> undefined, gauge_label_extents: <(() => string)|undefined> undefined, gauge_label_threshold: 0, + gauge_enforceMinMax: false, gauge_min: 0, gauge_max: 100, gauge_type: "single", diff --git a/test/shape/gauge-spec.ts b/test/shape/gauge-spec.ts index df99134e0..277898741 100644 --- a/test/shape/gauge-spec.ts +++ b/test/shape/gauge-spec.ts @@ -437,6 +437,72 @@ describe("SHAPE GAUGE", () => { }); }); + describe("min/max", () => { + let args = { + data: { + columns: [ + ["data1", 30] + ], + type: "gauge" + }, + gauge: { + type: "single", + enforceMinMax: true, + min: 50, + max: 100 + } + }; + let chart; + + beforeEach(() => { + chart = util.generate(args); + //console.log(JSON.stringify(args)); + }); + + it("shoudn't render data when given value is less than min.", () => { + const length = chart.$.arc.select(".bb-shapes path").node().getTotalLength(); + + expect(length < 100).to.be.true; + }); + + it("set options: gauge.type='multi'", () => { + args = { + data: { + columns: [ + ["data1", 30], + ["data2", 75], + ["data3", 130], + ], + type: "gauge" + }, + gauge: { + type: "multi", + enforceMinMax: true, + min: 50, + max: 100 + } + } + }); + + it("shoud render data shape in a range of min/max value.", done => { + const expected = [ + {value: 0, length: 70}, + {value: 50, length: 720}, + {value: 100, length: 1560} + ]; + + setTimeout(() => { + + chart.$.arc.selectAll(".bb-shapes").each(function(d, i) { + expect(parseInt(this.nextSibling.textContent)).to.be.equal(expected[i].value); + expect(this.querySelector("path").getTotalLength() < expected[i].length).to.be + }); + + done(); + }, 300); + }); + }); + describe("show multi-arc-gauge", () => { const args = { data: { diff --git a/types/options.shape.d.ts b/types/options.shape.d.ts index c77ebfe9e..351bd2dfb 100644 --- a/types/options.shape.d.ts +++ b/types/options.shape.d.ts @@ -367,6 +367,13 @@ export interface GaugeOptions { */ type?: GaugeTypes; + /** + * Enforce to given min/max value. + * - When `gauge.min=50` and given value is `30`, gauge will render as empty value. + * - When `gauge.max=100` and given value is `120`, gauge will render till 100, not surpassing max value. + */ + enforceMinMax?: boolean; + /** * Set min value of the gauge. */