diff --git a/src/ChartInternal/data/data.ts b/src/ChartInternal/data/data.ts index 089e4e2a1..a79bbc2ea 100644 --- a/src/ChartInternal/data/data.ts +++ b/src/ChartInternal/data/data.ts @@ -854,6 +854,11 @@ export default { ratio = ( parseFloat(String(Math.max(d.value, 0))) / state.current.dataMax ) * config.radar_size_ratio; + } else if (type === "bar") { + const yScale = $$.getYScaleById.bind($$)(d.id); + const max = yScale.domain().reduce((a, c) => c - a); + + ratio = Math.abs(d.value) / max; } } diff --git a/src/ChartInternal/internals/redraw.ts b/src/ChartInternal/internals/redraw.ts index c3dc6b624..06528bec1 100644 --- a/src/ChartInternal/internals/redraw.ts +++ b/src/ChartInternal/internals/redraw.ts @@ -34,9 +34,6 @@ export default { $$.updateDimension(true); } - // text - $$.hasDataLabel() && $$.updateText(durationForExit); - // update circleY based on updated parameters if (!$$.hasArcType() || state.hasRadar) { $$.updateCircleY && $$.updateCircleY(); @@ -95,6 +92,9 @@ export default { $$.updateCircle(); } + // text + $$.hasDataLabel() && $$.updateText(durationForExit); + // title $$.redrawTitle && $$.redrawTitle(); diff --git a/src/ChartInternal/internals/text.ts b/src/ChartInternal/internals/text.ts index 38fe71214..c71538947 100644 --- a/src/ChartInternal/internals/text.ts +++ b/src/ChartInternal/internals/text.ts @@ -13,8 +13,11 @@ import {AxisType} from "../../../types/types"; export default { - opacityForText(): "1" | "0" { - return this.hasDataLabel() ? "1" : "0"; + opacityForText(d): "1" | "0" { + const $$ = this; + + return $$.isBarType(d) && !$$.meetsBarLabelThreshold(d) ? + "0" : ($$.hasDataLabel ? "1" : "0"); }, /** @@ -63,7 +66,7 @@ export default { const classText = $$.classText.bind($$); $el.text = $el.main.selectAll(`.${CLASS.texts}`).selectAll(`.${CLASS.text}`) - .data(d => (this.isRadarType(d) ? d.values : dataFn(d))); + .data(d => ($$.isRadarType(d) ? d.values : dataFn(d))); $el.text.exit() .transition() diff --git a/src/ChartInternal/shape/bar.ts b/src/ChartInternal/shape/bar.ts index 89f35109f..825c88cf1 100644 --- a/src/ChartInternal/shape/bar.ts +++ b/src/ChartInternal/shape/bar.ts @@ -132,6 +132,14 @@ export default { this.getBars(i).classed(CLASS.EXPANDED, false); }, + meetsBarLabelThreshold(d): boolean { + const $$ = this; + const {config} = $$; + const threshold = config.bar_label_threshold; + + return Math.abs($$.getRatio("bar", d)) >= threshold; + }, + generateDrawBar(barIndices, isSub?: boolean): Function { const $$ = this; const {config} = $$; @@ -186,6 +194,7 @@ export default { generateGetBarPoints(barIndices, isSub?: boolean): Function { const $$ = this; const {config} = $$; + const axis = isSub ? $$.axis.subX : $$.axis.x; const barTargetsNum = $$.getIndicesMax(barIndices) + 1; const barW = $$.getBarW(axis, barTargetsNum); diff --git a/src/config/Options/shape/bar.ts b/src/config/Options/shape/bar.ts index 8e708b413..21532ff1f 100644 --- a/src/config/Options/shape/bar.ts +++ b/src/config/Options/shape/bar.ts @@ -12,6 +12,7 @@ export default { * @memberof Options * @type {object} * @property {object} bar Bar object + * @property {number} [bar.label.threshold=0] Set threshold ratio to show/hide labels. * @property {number} [bar.padding=0] The padding pixel value between each bar. * @property {number} [bar.radius] Set the radius of bar edge in pixel. * - **NOTE:** Works only for non-stacked bar @@ -42,6 +43,12 @@ export default { * ratio: 0.5 * } * + * label: { + * // 0.1(10%) ratio value means, the minimum ratio to show text label relative to the y Axis domain range value. + * // if data value is below than 0.1, text label will be hidden. + * threshold: 0.1, + * }, + * * // will not have offset between each bar elements for interaction * sensitivity: 0, * @@ -65,6 +72,7 @@ export default { * zerobased: false * } */ + bar_label_threshold: 0, bar_padding: 0, bar_radius: undefined, bar_radius_ratio: undefined, diff --git a/src/config/Options/shape/donut.ts b/src/config/Options/shape/donut.ts index aec653b32..befa9f880 100644 --- a/src/config/Options/shape/donut.ts +++ b/src/config/Options/shape/donut.ts @@ -14,7 +14,7 @@ export default { * @property {object} donut Donut object * @property {boolean} [donut.label.show=true] Show or hide label on each donut piece. * @property {Function} [donut.label.format] Set formatter for the label on each donut piece. - * @property {number} [donut.label.threshold=0.05] Set threshold to show/hide labels. + * @property {number} [donut.label.threshold=0.05] Set threshold ratio to show/hide labels. * @property {number|Function} [donut.label.ratio=undefined] Set ratio of labels position. * @property {boolean} [donut.expand=true] Enable or disable expanding donut pieces. * @property {number} [donut.expand.rate=0.98] Set expand rate. @@ -33,6 +33,9 @@ export default { * // to multiline, return with '\n' character * // return value +"%\nLine1\n2Line2"; * }, + * + * // 0.1(10%) ratio value means, the minimum ratio to show text label relative to the total value. + * // if data value is below than 0.1, text label will be hidden. * threshold: 0.1, * * // set ratio callback. Should return ratio value diff --git a/src/config/Options/shape/pie.ts b/src/config/Options/shape/pie.ts index 1160faac5..e1a42ec62 100644 --- a/src/config/Options/shape/pie.ts +++ b/src/config/Options/shape/pie.ts @@ -14,7 +14,7 @@ export default { * @property {object} pie Pie object * @property {boolean} [pie.label.show=true] Show or hide label on each pie piece. * @property {Function} [pie.label.format] Set formatter for the label on each pie piece. - * @property {number} [pie.label.threshold=0.05] Set threshold to show/hide labels. + * @property {number} [pie.label.threshold=0.05] Set threshold ratio to show/hide labels. * @property {number|Function} [pie.label.ratio=undefined] Set ratio of labels position. * @property {boolean|object} [pie.expand=true] Enable or disable expanding pie pieces. * @property {number} [pie.expand.rate=0.98] Set expand rate. @@ -34,6 +34,9 @@ export default { * // to multiline, return with '\n' character * // return value +"%\nLine1\n2Line2"; * }, + * + * // 0.1(10%) ratio value means, the minimum ratio to show text label relative to the total value. + * // if data value is below than 0.1, text label will be hidden. * threshold: 0.1, * * // set ratio callback. Should return ratio value diff --git a/test/shape/bar-spec.ts b/test/shape/bar-spec.ts index ce0f1e9ef..f4de88442 100644 --- a/test/shape/bar-spec.ts +++ b/test/shape/bar-spec.ts @@ -602,4 +602,71 @@ describe("SHAPE BAR", () => { expect(chart.$.tooltip.selectAll(".name").size()).to.be.equal(1); }); }); + + describe("bar label.threshold", () => { + before(() => { + args = { + data: { + columns: [ + ["data1", 30, 230], + ["data2", 1000, 0], + ["data3", -30, -230], + ["data4", -1000, 0] + ], + type: "bar", + groups: [ + ["data1", "data2"] + ], + labels: true + }, + bar: { + label: { + threshold: 0.1 + } + } + }; + }); + + const checkLabel = function(expected) { + const hiddenIds = chart.internal.state.hiddenTargetIds; + + const res = chart.$.text.texts.filter(function(d) { + return hiddenIds.indexOf(d.id) === -1 && this.style.fillOpacity === "1"; + }).nodes().map(n => +n.textContent); + + expect(res).to.be.deep.equal(expected); + } + + it("check data label shown #1", done => { + checkLabel([1000, -1000]); + + // when + chart.hide("data2"); + + setTimeout(() => { + checkLabel([230, -230, -1000]); + done(); + }, 350); + }); + + it("check data label shown #2", done => { + // when + chart.hide(["data2", "data4"]); + + setTimeout(() => { + checkLabel([230, -230]); + done(); + }, 350); + }); + + it("check data label shown #3", done => { + // when + chart.hide(["data1", "data2", "data4"]); + + setTimeout(() => { + checkLabel([-30, -230]); + done(); + }, 350); + }); + }); }); diff --git a/types/options.d.ts b/types/options.d.ts index 5a7a5140f..c78452682 100644 --- a/types/options.d.ts +++ b/types/options.d.ts @@ -285,6 +285,13 @@ export interface ChartOptions { headers?: Array<{ [key: string]: string; }>; + /** + * Set threshold ratio to show/hide labels. + */ + label?: { + threshold?: number; + } + /** * Set if min or max value will be 0 on bar chart. */ @@ -410,7 +417,7 @@ export interface ChartOptions { show?: boolean; /** - * Set threshold to show/hide labels. + * Set threshold ratio to show/hide labels. */ threshold?: number; @@ -471,7 +478,7 @@ export interface ChartOptions { show?: boolean; /** - * Set threshold to show/hide labels. + * Set threshold ratio to show/hide labels. */ threshold?: number;