UNPKG

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