diff --git a/src/ChartInternal/data/data.ts b/src/ChartInternal/data/data.ts index b0f8d0171..960ba900c 100644 --- a/src/ChartInternal/data/data.ts +++ b/src/ChartInternal/data/data.ts @@ -899,14 +899,18 @@ export default { const value = d?.value; if (isArray(value)) { - // @ts-ignore - const index = { - areaRange: ["high", "mid", "low"], - candlestick: ["open", "high", "low", "close", "volume"] - }[type].indexOf(key); - - return index >= 0 && value ? value[index] : undefined; - } else if (value) { + if (type === "bar") { + return value.reduce((a, c) => c - a); + } else { + // @ts-ignore + const index = { + areaRange: ["high", "mid", "low"], + candlestick: ["open", "high", "low", "close", "volume"] + }[type].indexOf(key); + + return index >= 0 && value ? value[index] : undefined; + } + } else if (value && key) { return value[key]; } @@ -992,7 +996,9 @@ export default { const max = yScale.domain().reduce((a, c) => c - a); // when all data are 0, return 0 - ratio = max === 0 ? 0 : Math.abs(d.value) / max; + ratio = max === 0 ? 0 : Math.abs( + $$.getRangedData(d, null, type) / max + ); } else if (type === "treemap") { ratio /= $$.getTotalDataSum(true); } diff --git a/src/ChartInternal/internals/format.ts b/src/ChartInternal/internals/format.ts index 166f58bd8..f7ec79f4b 100644 --- a/src/ChartInternal/internals/format.ts +++ b/src/ChartInternal/internals/format.ts @@ -2,7 +2,7 @@ * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ -import {isValue, isFunction, isObjectType} from "../../module/util"; +import {isArray, isValue, isFunction, isObjectType} from "../../module/util"; import type {AxisType} from "../../../types/types"; /** @@ -65,7 +65,7 @@ export default { dataLabelFormat(targetId: string): Function { const $$ = this; const dataLabels = $$.config.data_labels; - const defaultFormat = v => (isValue(v) ? +v : ""); + const defaultFormat = v => (isArray(v) ? v.join("~") : (isValue(v) ? +v : "")); let format = defaultFormat; // find format according to axis id diff --git a/src/ChartInternal/internals/text.ts b/src/ChartInternal/internals/text.ts index f5de80001..0aa0e955c 100644 --- a/src/ChartInternal/internals/text.ts +++ b/src/ChartInternal/internals/text.ts @@ -255,7 +255,7 @@ export default { * @returns {string|null} * @private */ - updateTextBacgroundColor(d: IDataRow | IArcData): string | null { + updateTextBackgroundColor(d: IDataRow | IArcData): string | null { const $$ = this; const {$el, config} = $$; const backgroundColor = config.data_labels_backgroundColors; @@ -293,7 +293,7 @@ export default { $$.$el.text .style("fill", $$.getStylePropValue($$.updateTextColor)) - .attr("filter", $$.updateTextBacgroundColor.bind($$)) + .attr("filter", $$.updateTextBackgroundColor.bind($$)) .style("fill-opacity", forFlow ? 0 : $$.opacityForText.bind($$)) .each(function(d: IDataRow, i: number) { // do not apply transition for newly added text elements @@ -410,7 +410,7 @@ export default { const rect = getBoundingRect(textElement); if (isBarType) { - const isPositive = d.value >= 0; + const isPositive = $$.getRangedData(d, null, "bar") >= 0; if (isRotated) { const w = ( diff --git a/src/ChartInternal/shape/arc.ts b/src/ChartInternal/shape/arc.ts index 67353a0e7..e6c27bdc7 100644 --- a/src/ChartInternal/shape/arc.ts +++ b/src/ChartInternal/shape/arc.ts @@ -440,7 +440,7 @@ export default { if ($$.shouldShowArcLabel()) { selection .style("fill", $$.updateTextColor.bind($$)) - .attr("filter", $$.updateTextBacgroundColor.bind($$)) + .attr("filter", $$.updateTextBackgroundColor.bind($$)) .each(function(d) { const node = d3Select(this); const updated = $$.updateAngle(d); diff --git a/src/ChartInternal/shape/shape.ts b/src/ChartInternal/shape/shape.ts index b1c37bb2f..7954a0220 100644 --- a/src/ChartInternal/shape/shape.ts +++ b/src/ChartInternal/shape/shape.ts @@ -273,6 +273,8 @@ export default { if (isNumber(d)) { value = d; + } else if ($$.isAreaRangeType(d)) { + value = $$.getBaseValue(d, "mid"); } else if (isStackNormalized) { value = $$.getRatio("index", d, true); } else if ($$.isBubbleZType(d)) { diff --git a/test/internals/text-spec.ts b/test/internals/text-spec.ts index a63ac16b1..b98968940 100644 --- a/test/internals/text-spec.ts +++ b/test/internals/text-spec.ts @@ -9,7 +9,7 @@ import {select as d3Select} from "d3-selection"; import {format as d3Format} from "d3-format"; import util from "../assets/util"; import {$AXIS, $SHAPE, $TEXT} from "../../src/config/classes"; -import {isNumber} from "../../src/module/util"; +import {isArray, isNumber} from "../../src/module/util"; describe("TEXT", () => { let chart; @@ -426,6 +426,69 @@ describe("TEXT", () => { }); }); + describe("on ranged value(AreaRange/Bar range) chart", () => { + before(() => { + args = { + data: { + columns: [ + ["data1", + [150, 140, 110], + [155, 130, 115], + [160, 135, 120], + ], + ["data2", [230, 340], 200, [-100, -50]] + ], + types: { + data1: "area-line-range", + data2: "bar" + }, + labels: { + colors: "black" + } + } + }; + }); + + it("should locate data labels in correct position", () => { + chart.$.text.texts.each(function(d) { + const text = isArray(d.value) ? d.value.join("~") : String(d.value); + + expect(this.textContent).to.be.equal(text); + }); + }); + + it("set option: data.labels.centered=true / data.labels.format", () => { + args.data.labels.centered = true; + + args.data.labels.format = function(value, id, index) { + return Array.isArray(value) ? value.join("-") : value; + }; + }); + + it("should locate data labels in correct position", () => { + const {$: {bar, text}} = chart; + const barText: number[] = []; + + text.texts.each(function(d) { + const text = isArray(d.value) ? d.value.join("-") : String(d.value); + + expect(this.textContent).to.be.equal(text); + + if (d.id === "data2") { + barText.push(+this.getAttribute("y")); + } + }); + + // check labels centered + bar.bars.each(function(d, i) { + const rect = this.getBoundingClientRect(); + + expect(barText[i]).to.be.closeTo((rect.height / 2) + rect.top, 2); + + }); + }); + }); + describe("for all targets", () => { before(() => { args = {