PageSourceSearch

https://www.tourisme-creuse.com/app/dist/tourisme-creuse/addons/wo…/es-modules/Core/Axis/Stacking/StackItem.js

js tourisme-creuse.com collected 2026-10-02 05:52:42 UTC 10,169 bytes, 277 lines download raw bytes

1/* *
2 *
3 *  (c) 2010-2024 Torstein Honsi
4 *
5 *  License: www.highcharts.com/license
6 *
7 *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
8 *
9 * */
10'use strict';
11import T from '../../Templating.js';
12const { format } = T;
13import SeriesRegistry from '../../Series/SeriesRegistry.js';
14const { series: Series } = SeriesRegistry;
15import U from '../../Utilities.js';
16const { destroyObjectProperties, fireEvent, getAlignFactor, isNumber, pick } = U;
17/* *
18 *
19 *  Class
20 *
21 * */
22/**
23 * The class for stacks. Each stack, on a specific X value and either negative
24 * or positive, has its own stack item.
25 * @private
26 */
27class StackItem {
28    /* *
29     *
30     *  Constructor
31     *
32     * */
33    constructor(axis, options, negativeValue, x, stackOption) {
34        const inverted = axis.chart.inverted, reversed = axis.reversed;
35        this.axis = axis;
36        // The stack goes to the left either if the stack has negative value
37        // or when axis is reversed. XOR operator.
38        const isNegative = (this.isNegative = !!negativeValue !== !!reversed);
39        // Save the options to be able to style the label
40        this.options = options = options || {};
41        // Save the x value to be able to position the label later
42        this.x = x;
43        // Initialize total value
44        this.total = null;
45        this.cumulative = null;
46        // This will keep each points' extremes stored by series.index and point
47        // index
48        this.points = {};
49        this.hasValidPoints = false;
50        // Save the stack option on the series configuration object,
51        // and whether to treat it as percent
52        this.stack = stackOption;
53        this.leftCliff = 0;
54        this.rightCliff = 0;
55        // The align options and text align varies on whether the stack is
56        // negative and if the chart is inverted or not.
57        // First test the user supplied value, then use the dynamic.
58        this.alignOptions = {
59            align: options.align ||
60                (inverted ? (isNegative ? 'left' : 'right') : 'center'),
61            verticalAlign: options.verticalAlign ||
62                (inverted ? 'middle' : isNegative ? 'bottom' : 'top'),
63            y: options.y,
64            x: options.x
65        };
66        this.textAlign =
67            options.textAlign ||
68                (inverted ? (!isNegative ? 'left' : 'right') : 'center');
69    }
70    /* *
71     *
72     *  Functions
73     *
74     * */
75    /**
76     * @private
77     */
78    destroy() {
79        destroyObjectProperties(this, this.axis);
80    }
81    /**
82     * Renders the stack total label and adds it to the stack label group.
83     * @private
84     */
85    render(group) {
86        const chart = this.axis.chart, options = this.options, formatOption = options.format, 
87        // Format the text in the label.
88        str = formatOption ?
89            format(formatOption, this, chart) :
90            options.formatter.call(this);
91        // Change the text to reflect the new total and set visibility to hidden
92        // in case the series is hidden
93        if (this.label) {
94            this.label.attr({ text: str, visibility: 'hidden' });
95        }
96        else {
97            // Create new label
98            this.label = chart.renderer.label(str, null, void 0, options.shape, void 0, void 0, options.useHTML, false, 'stack-labels');
99            const attr = {
100                r: options.borderRadius || 0,
101                text: str,
102                // Set default padding to 5 as it is in datalabels #12308
103                padding: pick(options.padding, 5),
104                visibility: 'hidden' // Hidden until setOffset is called
105            };
106            if (!chart.styledMode) {
107                attr.fill = options.backgroundColor;
108                attr.stroke = options.borderColor;
109                attr['stroke-width'] = options.borderWidth;
110                this.label.css(options.style || {});
111            }
112            this.label.attr(attr);
113            if (!this.label.added) {
114                this.label.add(group); // Add to the labels-group
115            }
116        }
117        // Rank it higher than data labels (#8742)
118        this.label.labelrank = chart.plotSizeY;
119        fireEvent(this, 'afterRender');
120    }
121    /**
122     * Sets the offset that the stack has from the x value and repositions the
123     * label.
124     * @private
125     */
126    setOffset(xOffset, width, boxBottom, boxTop, defaultX, xAxis) {
127        const { alignOptions, axis, label, options, textAlign } = this, chart = axis.chart, stackBox = this.getStackBox({
128            xOffset,
129            width,
130            boxBottom,
131            boxTop,
132            defaultX,
133            xAxis
134        }), { verticalAlign } = alignOptions;
135        if (label && stackBox) {
136            const labelBox = label.getBBox(void 0, 0), padding = label.padding;
137            let isJustify = pick(options.overflow, 'justify') === 'justify', visible;
138            // Reset alignOptions property after justify #12337
139            alignOptions.x = options.x || 0;
140            alignOptions.y = options.y || 0;
141            // Calculate the adjusted Stack position, to take into consideration
142            // The size if the labelBox and vertical alignment as
143            // well as the text alignment. It's need to be done to work with
144            // default SVGLabel.align/justify methods.
145            const { x, y } = this.adjustStackPosition({
146                labelBox,
147                verticalAlign,
148                textAlign
149            });
150            stackBox.x -= x;
151            stackBox.y -= y;
152            // Align the label to the adjusted box.
153            label.align(alignOptions, false, stackBox);
154            // Check if label is inside the plotArea #12294
155            visible = chart.isInsidePlot(label.alignAttr.x + alignOptions.x + x, label.alignAttr.y + alignOptions.y + y);
156            if (!visible) {
157                isJustify = false;
158            }
159            if (isJustify) {
160                // Justify stackLabel into the alignBox
161                Series.prototype.justifyDataLabel.call(axis, label, alignOptions, label.alignAttr, labelBox, stackBox);
162            }
163            // Add attr to avoid the default animation of justifyDataLabel.
164            // Also add correct rotation with its rotation origin. #15129
165            label.attr({
166                x: label.alignAttr.x,
167                y: label.alignAttr.y,
168                rotation: options.rotation,
169                rotationOriginX: labelBox.width *
170                    getAlignFactor(options.textAlign || 'center'),
171                rotationOriginY: labelBox.height / 2
172            });
173            // Check if the dataLabel should be visible.
174            if (pick(!isJustify && options.crop, true)) {
175                visible =
176                    isNumber(label.x) &&
177                        isNumber(label.y) &&
178                        chart.isInsidePlot(label.x - padding + (label.width || 0), label.y) &&
179                        chart.isInsidePlot(label.x + padding, label.y);
180            }
181            label[visible ? 'show' : 'hide']();
182        }
183        fireEvent(this, 'afterSetOffset', { xOffset, width });
184    }
185    /**
186     * Adjust the stack BBox position, to take into consideration the alignment
187     * of the dataLabel. This is necessary to make the stackDataLabel work with
188     * core methods like `SVGLabel.adjust` and `Series.justifyDataLabel`.
189     * @param AdjustStackPositionProps
190     * @return {{x: number, y: number}} Adjusted BBox position of the stack.
191     */
192    adjustStackPosition({ labelBox, verticalAlign, textAlign }) {
193        return {
194            x: labelBox.width / 2 +
195                (labelBox.width / 2) * (2 * getAlignFactor(textAlign) - 1),
196            y: (labelBox.height / 2) * 2 * (1 - getAlignFactor(verticalAlign))
197        };
198    }
199    /**
200     * Get the bbox of the stack.
201     * @private
202     * @function Highcharts.StackItem#getStackBox
203     * @return {BBoxObject} The x, y, height, width of the stack.
204     */
205    getStackBox(stackBoxProps) {
206        const stackItem = this, axis = this.axis, chart = axis.chart, { boxTop, defaultX, xOffset, width, boxBottom } = stackBoxProps, totalStackValue = axis.stacking.usePercentage ?
207            100 :
208            pick(boxTop, this.total, 0), y = axis.toPixels(totalStackValue), xAxis = stackBoxProps.xAxis || chart.xAxis[0], x = pick(defaultX, xAxis.translate(this.x)) + xOffset, yZero = axis.toPixels(boxBottom ||
209            (isNumber(axis.min) &&
210                axis.logarithmic &&
211                axis.logarithmic.lin2log(axis.min)) ||
212            0), height = Math.abs(y - yZero), inverted = chart.inverted, neg = stackItem.isNegative;
213        return inverted ?
214            {
215                x: (neg ? y : y - height) - chart.plotLeft,
216                y: xAxis.height - x - width + xAxis.top - chart.plotTop,
217                width: height,
218                height: width
219            } : {
220            x: x + xAxis.transB - chart.plotLeft,
221            y: (neg ? y - height : y) - chart.plotTop,
222            width: width,
223            height: height
224        };
225    }
226}
227/* *
228 *
229 *  Default Export
230 *
231 * */
232export default StackItem;
233/* *
234 *
235 *  API Declarations
236 *
237 * */
238/**
239 * Stack of data points
240 *
241 * @product highcharts
242 *
243 * @interface Highcharts.StackItemObject
244 */ /**
245* Alignment settings
246* @name Highcharts.StackItemObject#alignOptions
247* @type {Highcharts.AlignObject}
248*/ /**
249* Related axis
250* @name Highcharts.StackItemObject#axis
251* @type {Highcharts.Axis}
252*/ /**
253* Cumulative value of the stacked data points
254* @name Highcharts.StackItemObject#cumulative
255* @type {number}
256*/ /**
257* True if on the negative side
258* @name Highcharts.StackItemObject#isNegative
259* @type {boolean}
260*/ /**
261* Related SVG element
262* @name Highcharts.StackItemObject#label
263* @type {Highcharts.SVGElement}
264*/ /**
265* Related stack options
266* @name Highcharts.StackItemObject#options
267* @type {Highcharts.YAxisStackLabelsOptions}
268*/ /**
269* Total value of the stacked data points
270* @name Highcharts.StackItemObject#total
271* @type {number}
272*/ /**
273* Shared x value of the stack
274* @name Highcharts.StackItemObject#x
275* @type {number}
276*/
277''; // Keeps doclets above in JS file

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.