UNPKG

16.3 kBJavaScriptView Raw
1/**
2 * Module, defining Axis Renderer for vertical axes.
3 */
4import { __extends } from "tslib";
5/**
6 * ============================================================================
7 * IMPORTS
8 * ============================================================================
9 * @hidden
10 */
11import { AxisRenderer } from "./AxisRenderer";
12import { AxisBullet } from "./AxisBullet";
13import { WavedLine } from "../../core/elements/WavedLine";
14import { WavedRectangle } from "../../core/elements/WavedRectangle";
15import { registry } from "../../core/Registry";
16import { percent, Percent } from "../../core/utils/Percent";
17import * as $math from "../../core/utils/Math";
18import * as $path from "../../core/rendering/Path";
19import * as $utils from "../../core/utils/Utils";
20import * as $type from "../../core/utils/Type";
21import { defaultRules, ResponsiveBreakpoints } from "../../core/utils/Responsive";
22/**
23 * ============================================================================
24 * MAIN CLASS
25 * ============================================================================
26 * @hidden
27 */
28/**
29 * A renderer for horizontal axis.
30 *
31 * @see {@link IAxisRendererEvents} for a list of available events
32 * @see {@link IAxisRendererAdapters} for a list of available Adapters
33 */
34var AxisRendererX = /** @class */ (function (_super) {
35 __extends(AxisRendererX, _super);
36 /**
37 * Constructor.
38 *
39 * @param axis Related axis
40 */
41 function AxisRendererX() {
42 var _this = _super.call(this) || this;
43 _this.className = "AxisRendererX";
44 _this.minGridDistance = 120;
45 _this.opposite = false;
46 _this.rotation = 0;
47 _this.width = percent(100);
48 _this.labels.template.horizontalCenter = "middle";
49 _this.applyTheme();
50 return _this;
51 }
52 /**
53 * @ignore
54 */
55 AxisRendererX.prototype.setAxis = function (axis) {
56 _super.prototype.setAxis.call(this, axis);
57 axis.layout = "vertical";
58 };
59 /**
60 * @ignore
61 */
62 AxisRendererX.prototype.updateGridContainer = function () {
63 var axis = this.axis;
64 if (axis) {
65 var gridContainer = this.gridContainer;
66 gridContainer.x = axis.pixelX;
67 gridContainer.width = axis.axisLength;
68 }
69 };
70 /**
71 * Called when rendered is attached to an Axis, as well as a property of
72 * Axis that might affect the appearance is updated.
73 *
74 * E.g. `axis.opposite`, `axis.inside`, etc.
75 *
76 * This method is called **before** draw, so that any related setting
77 * changed in this method can be changed.
78 *
79 * @todo Description (review)
80 * @ignore Exclude from docs
81 */
82 AxisRendererX.prototype.processRenderer = function () {
83 _super.prototype.processRenderer.call(this);
84 // can not do this in init, as axis is set later
85 var axis = this.axis;
86 if (axis) {
87 if (!(axis.width instanceof Percent)) {
88 axis.width = percent(100);
89 }
90 // @todo Is thi sneeded?
91 $utils.used(this.line);
92 var title = axis.title;
93 title.rotation = 0;
94 title.align = "center";
95 if (this.opposite) {
96 this.line.toFront();
97 title.toBack();
98 }
99 else {
100 title.toFront();
101 this.toBack();
102 this.line.toBack();
103 }
104 }
105 };
106 /**
107 * Updates some of the Axis tooltip's visual properties, related to
108 * rendering of the Axis.
109 *
110 * @todo Description (review)
111 * @ignore Exclude from docs
112 */
113 AxisRendererX.prototype.updateTooltip = function () {
114 var axis = this.axis;
115 if (axis) {
116 var bigNum = 1000;
117 var bbx = this.line.pixelX;
118 var bby = this.line.pixelY;
119 var bbw = this.axisLength;
120 var bbh = bigNum;
121 // top
122 if (this.opposite) {
123 if (!this.inside) {
124 bby = -bigNum;
125 bbh = bigNum;
126 }
127 }
128 // bottom
129 else {
130 if (this.inside) {
131 bby = -bigNum;
132 bbh = bigNum;
133 }
134 }
135 this.axis.updateTooltip("vertical", { x: bbx, y: bby, width: bbw, height: bbh });
136 }
137 };
138 /**
139 * Updates and positions a label element.
140 *
141 * @ignore Exclude from docs
142 * @param label Label element
143 * @param position Starting position
144 * @param endPosition Ending position
145 */
146 AxisRendererX.prototype.updateLabelElement = function (label, position, endPosition, location) {
147 if (!$type.hasValue(location)) {
148 location = label.location;
149 }
150 position = position + (endPosition - position) * location;
151 var point = this.positionToPoint(position);
152 label.isMeasured = !label.inside;
153 var deltaY = 0;
154 var verticalCenter;
155 var maxHeight = this.gridContainer.maxHeight;
156 if (this.opposite) {
157 if (label.inside) {
158 verticalCenter = "top";
159 if (label.valign == "bottom") {
160 deltaY = maxHeight;
161 verticalCenter = "bottom";
162 }
163 if (label.valign == "middle") {
164 deltaY = maxHeight / 2;
165 verticalCenter = "middle";
166 }
167 }
168 else {
169 verticalCenter = "bottom";
170 }
171 point.y = deltaY;
172 }
173 else {
174 if (label.inside) {
175 verticalCenter = "bottom";
176 if (label.valign == "top") {
177 deltaY = -maxHeight;
178 verticalCenter = "top";
179 }
180 if (label.valign == "middle") {
181 deltaY = -maxHeight / 2;
182 verticalCenter = "middle";
183 }
184 }
185 else {
186 verticalCenter = "top";
187 }
188 point.y += deltaY;
189 }
190 if (label.rotation == 0) {
191 // Apply fuzzy logic to verticalCenter only if labels are not rotated
192 label.verticalCenter = verticalCenter;
193 }
194 this.positionItem(label, point);
195 this.toggleVisibility(label, position, this.minLabelPosition, this.maxLabelPosition);
196 };
197 Object.defineProperty(AxisRendererX.prototype, "axisLength", {
198 /**
199 * Returns actual length of the Axis, in pixels.
200 *
201 * @return Length (px)
202 */
203 get: function () {
204 var axis = this.axis;
205 return (axis.measuredWidth - axis.pixelPaddingRight - axis.pixelPaddingLeft) || 0;
206 },
207 enumerable: true,
208 configurable: true
209 });
210 /**
211 * Converts relative position on axis to point coordinates.
212 *
213 * @param position Position (0-1)
214 * @param position2 Position (0-1) Position on the second axis
215 * @return Point
216 */
217 AxisRendererX.prototype.positionToPoint = function (position, position2) {
218 return { x: this.positionToCoordinate(position), y: 0 };
219 };
220 /**
221 * Converts a point at specific coordinates to a relative position (0-1)
222 * on the axis.
223 *
224 * @param point Point
225 * @return Position (0-1)
226 */
227 AxisRendererX.prototype.pointToPosition = function (point) {
228 return this.coordinateToPosition(point.x, point.y);
229 };
230 /**
231 * [getPositionRangePath description]
232 *
233 * @ignore Exclude from docs
234 * @todo Description
235 * @param startPosition Starting position
236 * @param endPosition End position
237 * @return SVG path
238 */
239 AxisRendererX.prototype.getPositionRangePath = function (startPosition, endPosition) {
240 var x1 = $math.fitToRange(this.positionToCoordinate(startPosition), 0, this.axisLength);
241 var x2 = $math.fitToRange(this.positionToCoordinate(endPosition), 0, this.axisLength);
242 var w = Math.abs(x2 - x1);
243 var h = this.getHeight();
244 var x = Math.min(x1, x2);
245 var y = 0;
246 return $path.rectToPath({
247 x: x,
248 y: y,
249 width: w,
250 height: h
251 }, true);
252 };
253 /**
254 * Updates and positions an axis break element.
255 *
256 * @ignore Exclude from docs
257 * @param axisBreak Break element
258 */
259 AxisRendererX.prototype.updateBreakElement = function (axisBreak) {
260 _super.prototype.updateBreakElement.call(this, axisBreak);
261 var startLine = axisBreak.startLine;
262 var endLine = axisBreak.endLine;
263 var fillShape = axisBreak.fillShape;
264 var startPoint = axisBreak.startPoint;
265 var endPoint = axisBreak.endPoint;
266 var y1 = axisBreak.pixelMarginLeft;
267 var y2 = this.getHeight() - axisBreak.pixelMarginTop - axisBreak.pixelMarginBottom;
268 startPoint.x = $math.fitToRange(startPoint.x, -1, this.axisLength + 1);
269 endPoint.x = $math.fitToRange(endPoint.x, -1, this.axisLength + 1);
270 if (startPoint.x == endPoint.x && (startPoint.x < 0 || startPoint.x > this.axisLength)) {
271 axisBreak.fillShape.__disabled = true;
272 }
273 else {
274 axisBreak.fillShape.__disabled = false;
275 }
276 startLine.y = y1;
277 startLine.width = 0;
278 startLine.height = y2;
279 endLine.y = y1;
280 endLine.width = 0;
281 endLine.height = y2;
282 fillShape.height = y2;
283 fillShape.width = Math.abs(endPoint.x - startPoint.x);
284 fillShape.y = y1;
285 fillShape.x = startPoint.x;
286 };
287 /**
288 * Updates and positions a grid element.
289 *
290 * @ignore Exclude from docs
291 * @param grid Grid element
292 * @param position Starting position
293 * @param endPosition End position
294 */
295 AxisRendererX.prototype.updateGridElement = function (grid, position, endPosition) {
296 position = position + (endPosition - position) * grid.location;
297 var point = this.positionToPoint(position);
298 //point.x = $utils.spritePointToSprite({x:point.x, y:0}, this, this.gridContainer).x;
299 grid.path = $path.moveTo({ x: 0, y: 0 }) + $path.lineTo({ x: 0, y: this.getHeight() });
300 this.positionItem(grid, point);
301 this.toggleVisibility(grid, position, 0, 1);
302 };
303 /**
304 * Updates and positions a tick element.
305 *
306 * @ignore Exclude from docs
307 * @param tick Tick element
308 * @param position Starting position
309 * @param endPosition End position
310 */
311 AxisRendererX.prototype.updateTickElement = function (tick, position, endPosition) {
312 position = position + (endPosition - position) * tick.location;
313 var point = this.positionToPoint(position);
314 var tickLength = tick.length;
315 point.y = $utils.spritePointToSprite({ x: 0, y: this.line.pixelY }, this.line.parent, this.gridContainer).y;
316 if (this.opposite) {
317 tickLength *= (tick.inside ? 1 : -1);
318 }
319 else {
320 tickLength *= (tick.inside ? -1 : 1);
321 }
322 tick.path = $path.moveTo({ x: 0, y: 0 }) + $path.lineTo({ x: 0, y: tickLength });
323 this.positionItem(tick, point);
324 this.toggleVisibility(tick, position, 0, 1);
325 };
326 /**
327 * Updates and positions the axis line element.
328 *
329 * @ignore Exclude from docs
330 */
331 AxisRendererX.prototype.updateAxisLine = function () {
332 this.line.path = $path.moveTo({ x: 0, y: 0 }) + $path.lineTo({ x: this.axisLength, y: 0 });
333 };
334 /**
335 * Updates and positions the base grid element.
336 *
337 * @ignore Exclude from docs
338 */
339 AxisRendererX.prototype.updateBaseGridElement = function () {
340 _super.prototype.updateBaseGridElement.call(this);
341 var axis = this.axis;
342 var h = this.getHeight();
343 var w = this.axisLength;
344 var baseGrid = this.baseGrid;
345 var x = axis.basePoint.x;
346 if (x < -0.2 || x > w + 0.2) {
347 baseGrid.hide(0);
348 }
349 else {
350 var y = $utils.spritePointToSprite({ x: 0, y: 0 }, this.gridContainer, baseGrid.parent).y;
351 baseGrid.path = $path.moveTo({ x: 0, y: 0 }) + $path.lineTo({ x: 0, y: h });
352 baseGrid.moveTo({ x: x, y: y });
353 baseGrid.show(0);
354 }
355 };
356 /**
357 * Creates visual elements for and axis break.
358 *
359 * @ignore Exclude from docs
360 * @param axisBreak Axis break
361 */
362 AxisRendererX.prototype.createBreakSprites = function (axisBreak) {
363 axisBreak.startLine = new WavedLine();
364 axisBreak.endLine = new WavedLine();
365 var wavedRectangle = new WavedRectangle();
366 wavedRectangle.setWavedSides(false, true, false, true);
367 axisBreak.fillShape = wavedRectangle;
368 };
369 /**
370 * @ignore
371 */
372 AxisRendererX.prototype.toAxisPosition = function (value) {
373 var inversedPosition = value;
374 var axis = this.axis;
375 if (axis) {
376 var relativePositionSprite = axis.relativePositionSprite;
377 var x = axis.pixelX;
378 if (relativePositionSprite) {
379 x = $utils.spritePointToSprite({ x: this.pixelX, y: 0 }, this.parent, relativePositionSprite).x;
380 }
381 else {
382 relativePositionSprite = axis.parent;
383 }
384 if (relativePositionSprite) {
385 var relativeX = x / relativePositionSprite.innerWidth;
386 var relativeWidth = axis.axisLength / relativePositionSprite.innerWidth;
387 return (inversedPosition - relativeX) / relativeWidth;
388 }
389 }
390 return value;
391 };
392 /**
393 * Updates and positions axis bullets.
394 *
395 * @ignore Exclude from docs
396 * @param bullet AxisBullet element
397 * @param position Starting position
398 * @param endPosition End position
399 */
400 AxisRendererX.prototype.updateBullet = function (bullet, position, endPosition) {
401 var location = 0.5;
402 if (bullet instanceof AxisBullet) {
403 location = bullet.location;
404 }
405 position = position + (endPosition - position) * location;
406 var point = this.positionToPoint(position);
407 point.y = $utils.spritePointToSprite({ x: 0, y: this.line.pixelY }, this.line.parent, this.gridContainer).y;
408 this.positionItem(bullet, point);
409 this.toggleVisibility(bullet, position, 0, 1);
410 };
411 return AxisRendererX;
412}(AxisRenderer));
413export { AxisRendererX };
414/**
415 * Register class in system, so that it can be instantiated using its name from
416 * anywhere.
417 *
418 * @ignore
419 */
420registry.registeredClasses["AxisRendererX"] = AxisRendererX;
421/**
422 * Add default responsive rules
423 */
424/**
425 * Put labels inside plot area.
426 * Disable first and last labels.
427 */
428defaultRules.push({
429 relevant: ResponsiveBreakpoints.heightXS,
430 state: function (target, stateId) {
431 if (target instanceof AxisRendererX) {
432 var state = target.states.create(stateId);
433 state.properties.inside = true;
434 state.properties.maxLabelPosition = 0.9;
435 state.properties.minLabelPosition = 0.1;
436 return state;
437 }
438 return null;
439 }
440});
441/**
442 * Disable labels altogather on very small charts
443 */
444defaultRules.push({
445 relevant: ResponsiveBreakpoints.heightXXS,
446 state: function (target, stateId) {
447 if (target instanceof AxisRendererX) {
448 var state = target.states.create(stateId);
449 state.properties.disabled = true;
450 return state;
451 }
452 return null;
453 }
454});
455//# sourceMappingURL=AxisRendererX.js.map
\No newline at end of file