@progress/kendo-charts 2.4.0-dev.202405211537 → 2.4.0-dev.202406100726

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/dist/cdn/js/kendo-charts.js +1 -1
  2. package/dist/cdn/main.js +1 -1
  3. package/dist/es/chart/legend/legend-layout.js +4 -2
  4. package/dist/es/common/event-map.js +17 -0
  5. package/dist/es/common/event-utils.js +61 -0
  6. package/dist/es/common/get-supported-features.js +55 -0
  7. package/dist/es/common/noop.js +1 -0
  8. package/dist/es/common/now.js +3 -0
  9. package/dist/es/common/observable.js +1 -3
  10. package/dist/es/{map/scroller → common}/user-events.js +43 -131
  11. package/dist/es/common.js +7 -0
  12. package/dist/es/map/layers/layer.js +2 -5
  13. package/dist/es/map/layers/marker.js +3 -3
  14. package/dist/es/map/map.js +6 -6
  15. package/dist/es/map/navigator.js +3 -3
  16. package/dist/es/map/scroller/draggable.js +6 -11
  17. package/dist/es/map/scroller/fx.js +2 -2
  18. package/dist/es/map/scroller/scroller.js +7 -12
  19. package/dist/es/map/utils.js +9 -339
  20. package/dist/es/map/zoom.js +3 -3
  21. package/dist/es/sankey/label.js +21 -7
  22. package/dist/es/sankey/legend.js +16 -4
  23. package/dist/es/sankey/link.js +11 -4
  24. package/dist/es/sankey/sankey.js +67 -15
  25. package/dist/es/services/dom-events-builder.js +2 -4
  26. package/dist/es2015/chart/legend/legend-layout.js +4 -2
  27. package/dist/es2015/common/event-map.js +17 -0
  28. package/dist/es2015/common/event-utils.js +61 -0
  29. package/dist/es2015/common/get-supported-features.js +55 -0
  30. package/dist/es2015/common/noop.js +1 -0
  31. package/dist/es2015/common/now.js +3 -0
  32. package/dist/es2015/common/observable.js +1 -3
  33. package/dist/es2015/{map/scroller → common}/user-events.js +39 -131
  34. package/dist/es2015/common.js +7 -0
  35. package/dist/es2015/map/layers/layer.js +2 -5
  36. package/dist/es2015/map/layers/marker.js +3 -3
  37. package/dist/es2015/map/map.js +6 -6
  38. package/dist/es2015/map/navigator.js +3 -3
  39. package/dist/es2015/map/scroller/draggable.js +6 -11
  40. package/dist/es2015/map/scroller/fx.js +2 -2
  41. package/dist/es2015/map/scroller/scroller.js +7 -12
  42. package/dist/es2015/map/utils.js +8 -339
  43. package/dist/es2015/map/zoom.js +3 -3
  44. package/dist/es2015/sankey/label.js +19 -6
  45. package/dist/es2015/sankey/legend.js +15 -5
  46. package/dist/es2015/sankey/link.js +9 -4
  47. package/dist/es2015/sankey/sankey.js +66 -17
  48. package/dist/es2015/services/dom-events-builder.js +2 -4
  49. package/dist/npm/main.js +2795 -2975
  50. package/dist/npm/sankey.d.ts +4 -0
  51. package/dist/systemjs/kendo-charts.js +1 -1
  52. package/package.json +1 -1
@@ -6,19 +6,19 @@ import {
6
6
  addClass,
7
7
  Observable,
8
8
  isFunction,
9
- setDefaultOptions
9
+ setDefaultOptions,
10
+ on,
11
+ off,
12
+ UserEvents
10
13
  } from '../../common';
11
14
 
12
15
  import {
13
16
  convertToHtml,
14
17
  prepend,
15
18
  wrapInner,
16
- contains,
17
19
  hasNativeScrolling,
18
- on,
19
- off,
20
- proxy,
21
20
  wheelDeltaY,
21
+ proxy,
22
22
  setDefaultEvents
23
23
  } from '../utils';
24
24
 
@@ -34,10 +34,6 @@ import {
34
34
  TapCapture
35
35
  } from './draggable';
36
36
 
37
- import {
38
- UserEvents
39
- } from './user-events';
40
-
41
37
  var
42
38
  extend = Object.assign,
43
39
  abs = Math.abs,
@@ -382,8 +378,7 @@ export var Scroller = (function (Observable) {
382
378
  avoidScrolling = this.options.avoidScrolling,
383
379
 
384
380
  userEvents = new UserEvents(element, {
385
- touchAction: 'pan-y',
386
- fastTap: true,
381
+ touchAction: 'none',
387
382
  allowSelection: true,
388
383
  preventDragEvent: true,
389
384
  captureUpIfMoved: true,
@@ -394,7 +389,7 @@ export var Scroller = (function (Observable) {
394
389
  var velocityX = abs(e.x.velocity),
395
390
  velocityY = abs(e.y.velocity),
396
391
  horizontalSwipe = velocityX * 2 >= velocityY,
397
- originatedFromFixedContainer = contains(that.fixedContainer, e.event.target),
392
+ originatedFromFixedContainer = that.fixedContainer.contains(e.event.target),
398
393
  verticalSwipe = velocityY * 2 >= velocityX;
399
394
  if (!originatedFromFixedContainer && !avoidScrolling(e) && that.enabled && (dimensions.x.enabled && horizontalSwipe || dimensions.y.enabled && verticalSwipe)) {
400
395
  userEvents.capture();
@@ -1,15 +1,13 @@
1
- import {
2
- isFunction,
3
- isArray,
4
- hasOwnProperty
5
- } from '../common';
1
+ import { getSupportedFeatures } from '../common';
6
2
 
7
3
  /* eslint-disable arrow-body-style, no-useless-escape */
8
4
 
9
- var defineProperty = Object.defineProperty;
10
-
11
5
  export var extend = Object.assign;
12
6
 
7
+ export var proxy = function (method, context) {
8
+ return method.bind(context);
9
+ };
10
+
13
11
  export var convertToHtml = function (html) {
14
12
  var div = document.createElement("div");
15
13
  div.innerHTML = html;
@@ -65,331 +63,10 @@ export var toPixels = function (value) {
65
63
  return result;
66
64
  };
67
65
 
68
- var detectOS = function (ua) {
69
- var os = false, minorVersion, match = [],
70
- // notAndroidPhone = !/mobile safari/i.test(ua),
71
- agentRxs = {
72
- wp: /(Windows Phone(?: OS)?)\s(\d+)\.(\d+(\.\d+)?)/,
73
- fire: /(Silk)\/(\d+)\.(\d+(\.\d+)?)/,
74
- android: /(Android|Android.*(?:Opera|Firefox).*?\/)\s*(\d+)\.?(\d+(\.\d+)?)?/,
75
- iphone: /(iPhone|iPod).*OS\s+(\d+)[\._]([\d\._]+)/,
76
- ipad: /(iPad).*OS\s+(\d+)[\._]([\d_]+)/,
77
- meego: /(MeeGo).+NokiaBrowser\/(\d+)\.([\d\._]+)/,
78
- webos: /(webOS)\/(\d+)\.(\d+(\.\d+)?)/,
79
- blackberry: /(BlackBerry|BB10).*?Version\/(\d+)\.(\d+(\.\d+)?)/,
80
- playbook: /(PlayBook).*?Tablet\s*OS\s*(\d+)\.(\d+(\.\d+)?)/,
81
- windows: /(MSIE)\s+(\d+)\.(\d+(\.\d+)?)/,
82
- tizen: /(tizen).*?Version\/(\d+)\.(\d+(\.\d+)?)/i,
83
- sailfish: /(sailfish).*rv:(\d+)\.(\d+(\.\d+)?).*firefox/i,
84
- ffos: /(Mobile).*rv:(\d+)\.(\d+(\.\d+)?).*Firefox/
85
- },
86
- osRxs = {
87
- ios: /^i(phone|pad|pod)$/i,
88
- android: /^android|fire$/i,
89
- blackberry: /^blackberry|playbook/i,
90
- windows: /windows/,
91
- wp: /wp/,
92
- flat: /sailfish|ffos|tizen/i,
93
- meego: /meego/
94
- },
95
- formFactorRxs = {
96
- tablet: /playbook|ipad|fire/i
97
- },
98
- browserRxs = {
99
- omini: /Opera\sMini/i,
100
- omobile: /Opera\sMobi/i,
101
- firefox: /Firefox|Fennec/i,
102
- mobilesafari: /version\/.*safari/i,
103
- ie: /MSIE|Windows\sPhone/i,
104
- chrome: /chrome|crios/i,
105
- webkit: /webkit/i
106
- };
107
-
108
- for (var agent in agentRxs) {
109
- if (hasOwnProperty(agentRxs, agent)) {
110
- match = ua.match(agentRxs[agent]);
111
- if (match) {
112
- if (agent === "windows" && "plugins" in navigator) { return false; } // Break if not Metro/Mobile Windows
113
-
114
- os = {};
115
- os.device = agent;
116
- os.tablet = testRegex(agent, formFactorRxs, false);
117
- os.browser = testRegex(ua, browserRxs, "default");
118
- os.name = testRegex(agent, osRxs);
119
- os[os.name] = true;
120
- os.majorVersion = match[2];
121
- os.minorVersion = (match[3] || "0").replace("_", ".");
122
- minorVersion = os.minorVersion.replace(".", "").substr(0, 2);
123
- os.flatVersion = os.majorVersion + minorVersion + (new Array(3 - (minorVersion.length < 3 ? minorVersion.length : 2)).join("0"));
124
-
125
-
126
- break;
127
- }
128
- }
129
- }
130
-
131
- return os;
132
- };
133
-
134
- function testRegex(agent, regexes, dflt) {
135
- for (var regex in regexes) {
136
- if (hasOwnProperty(regexes, regex) && regexes[regex].test(agent)) {
137
- return regex;
138
- }
139
- }
140
- return dflt !== undefined ? dflt : agent;
141
- }
142
-
143
66
  export var hasNativeScrolling = function (userAgent) {
144
- var os = detectOS(userAgent);
145
- return os.ios || os.android;
146
- };
147
-
148
- var detectBrowser = function (userAgent) {
149
- var browser = false,
150
- match = [],
151
- browserRxs = {
152
- edge: /(edge)[ \/]([\w.]+)/i,
153
- webkit: /(chrome|crios)[ \/]([\w.]+)/i,
154
- safari: /(webkit)[ \/]([\w.]+)/i,
155
- opera: /(opera)(?:.*version|)[ \/]([\w.]+)/i,
156
- msie: /(msie\s|trident.*? rv:)([\w.]+)/i,
157
- mozilla: /(mozilla)(?:.*? rv:([\w.]+)|)/i
158
- };
159
-
160
- for (var agent in browserRxs) {
161
- if (hasOwnProperty(browserRxs, agent)) {
162
- match = userAgent.match(browserRxs[agent]);
163
-
164
- if (match) {
165
- browser = {};
166
- browser[agent] = true;
167
- browser[match[1].toLowerCase().split(" ")[0].split("/")[0]] = true;
168
- browser.version = parseInt(document.documentMode || match[2], 10);
169
-
170
- break;
171
- }
172
- }
173
- }
174
-
175
- return browser;
176
- };
177
-
178
- export var getEventMap = function () {
179
- var eventMap = {
180
- down: "touchstart mousedown",
181
- move: "mousemove touchmove",
182
- up: "mouseup touchend touchcancel",
183
- cancel: "mouseleave touchcancel"
184
- };
185
-
186
- var support = getSupportedFeatures();
187
-
188
- if (support.touch && (support.mobileOS.ios || support.mobileOS.android)) {
189
- eventMap = {
190
- down: "touchstart",
191
- move: "touchmove",
192
- up: "touchend touchcancel",
193
- cancel: "touchcancel"
194
- };
195
- } else if (support.pointers) {
196
- eventMap = {
197
- down: "pointerdown",
198
- move: "pointermove",
199
- up: "pointerup",
200
- cancel: "pointercancel pointerleave"
201
- };
202
- } else if (support.msPointers) {
203
- eventMap = {
204
- down: "MSPointerDown",
205
- move: "MSPointerMove",
206
- up: "MSPointerUp",
207
- cancel: "MSPointerCancel MSPointerLeave"
208
- };
209
- }
210
-
211
- return eventMap;
212
- };
213
-
214
- export var getSupportedFeatures = function () {
215
- var os = detectOS(navigator.userAgent);
216
- var browser = detectBrowser(navigator.userAgent);
217
-
218
- var chrome = browser.chrome,
219
- mobileChrome = browser.crios,
220
- mozilla = browser.mozilla,
221
- safari = browser.safari;
222
-
223
- var support = {};
224
-
225
- support.mobileOS = os;
226
- support.touch = "ontouchstart" in window;
227
- support.pointers = !chrome && !mobileChrome && !mozilla && !safari && window.PointerEvent;
228
- support.msPointers = !chrome && window.MSPointerEvent;
229
- support.mouseAndTouchPresent = support.touch && !(support.mobileOS.ios || support.mobileOS.android);
230
- support.eventCapture = document.documentElement.addEventListener;
231
-
232
- var table = document.createElement("table");
233
-
234
- var transitions = support.transitions = false,
235
- transforms = support.transforms = false;
236
-
237
- var STRING = "string";
238
-
239
- ["Moz", "webkit", "O", "ms"].forEach(function(prefix) {
240
- var hasTransitions = typeof table.style[prefix + "Transition"] === STRING;
241
-
242
- if (hasTransitions || typeof table.style[prefix + "Transform"] === STRING) {
243
- var lowPrefix = prefix.toLowerCase();
244
-
245
- transforms = {
246
- css: (lowPrefix !== "ms") ? "-" + lowPrefix + "-" : "",
247
- prefix: prefix,
248
- event: (lowPrefix === "o" || lowPrefix === "webkit") ? lowPrefix : ""
249
- };
250
-
251
- if (hasTransitions) {
252
- transitions = transforms;
253
- transitions.event = transitions.event ? transitions.event + "TransitionEnd" : "transitionend";
254
- }
255
-
256
- return false;
257
- }
258
- });
259
-
260
- table = null;
261
-
262
- support.transforms = transforms;
263
- support.transitions = transitions;
264
-
265
- support.delayedClick = function() {
266
- // only the mobile devices with touch events do this.
267
- if (support.touch) {
268
- // All iOS devices so far (by the time I am writing this, iOS 9.0.2 is the latest),
269
- // delay their click events.
270
- if (support.mobileOS.ios) {
271
- return true;
272
- }
273
-
274
- if (support.mobileOS.android) {
275
-
276
- if (!support.browser.chrome) { // older webkits and webviews delay the click
277
- return true;
278
- }
279
-
280
- // from here on, we deal with Chrome on Android.
281
- if (support.browser.version < 32) {
282
- return false;
283
- }
284
-
285
- // Chrome 32+ does conditional fast clicks if the view port is not user scalable.
286
- var meta = document.querySelector("meta[name=viewport]");
287
- var contentAttr = meta ? meta.getAttribute("content") : "";
288
- return !contentAttr.match(/user-scalable=no/i);
289
- }
290
- }
291
-
292
- return false;
293
- };
294
-
295
- return support;
296
- };
297
-
298
- export var ownsElement = function (parent, element) {
299
- if (!element) {
300
- return false;
301
- }
302
-
303
- var node = element.parentNode;
304
-
305
- while (node !== null) {
306
- if (node === parent) {
307
- return true;
308
- }
309
-
310
- node = node.parentNode;
311
- }
312
-
313
- return false;
314
- };
315
-
316
- export var contains = function (parent, element) {
317
- return parent === element || ownsElement(parent, element);
318
- };
319
-
320
- export var proxy = function (method, context) {
321
- return method.bind(context);
322
- };
323
-
324
- function isString(value) {
325
- return typeof(value) === "string";
326
- }
327
-
328
- export var on = function (element, events, filter, handler, useCapture) {
329
- addEventListeners(element, events, filter, handler, useCapture);
330
- };
331
-
332
- export var addEventListeners = function (element, events, filter, handler, useCapture) {
333
- var eventNames = isArray(events) ? events : (events || "").split(" ");
334
-
335
- eventNames.forEach(function(eventName) {
336
- addEventListener(element, eventName, filter, handler, useCapture);
337
- });
338
- };
339
-
340
- export var addEventListener = function (element, event, filter, handler, useCapture) {
341
- var eventHandler = handler;
342
- var eventFilter;
343
-
344
- if (filter && isFunction(filter) && !handler) {
345
- eventHandler = filter;
346
- } else if (filter && isString(filter) && isFunction(eventHandler)) {
347
- eventFilter = filter;
348
- }
349
-
350
- element.addEventListener(event, function(e) {
351
- var closestMatchingTarget = e.target ? e.target.closest(eventFilter) : null;
352
-
353
- if (!eventFilter ||
354
- (eventFilter && e.target && closestMatchingTarget)) {
355
- var currentTarget = eventFilter ? closestMatchingTarget : e.currentTarget;
356
-
357
- // reassign the property as it is a getters only
358
- defineProperty(e, "currentTarget", { value: currentTarget });
359
- // keep a reference to the top-level target
360
- defineProperty(e, "delegateTarget", { value: element });
361
-
362
- eventHandler(e);
363
- }
364
- }, Boolean(useCapture));
365
- };
366
-
367
- export var off = function (element, events, filter, handler, useCapture) {
368
- removeEventListeners(element, events, filter, handler, useCapture);
369
- };
370
-
371
- export var removeEventListeners = function (element, events, handler, useCapture) {
372
- var eventNames = isArray(events) ? events : (events || "").split(" ");
373
-
374
- eventNames.forEach(function(eventName) {
375
- removeEventListener(element, eventName, handler, useCapture);
376
- });
377
- };
378
-
379
- export var removeEventListener = function (element, event, handler, useCapture) {
380
- element.removeEventListener(event, handler, Boolean(useCapture));
381
- };
382
-
383
- export var applyEventMap = function (events) {
384
- var eventMap = getEventMap(navigator.userAgent);
385
- function queryEventMap(e) {
386
- return eventMap[e] || e;
387
- }
388
-
389
- var eventRegEx = /([^ ]+)/g;
390
- var appliedEvents = events.replace(eventRegEx, queryEventMap);
391
-
392
- return appliedEvents;
67
+ var ref = getSupportedFeatures(userAgent);
68
+ var mobileOS = ref.mobileOS;
69
+ return mobileOS.ios || mobileOS.android;
393
70
  };
394
71
 
395
72
  export var setDefaultEvents = function (type, events) {
@@ -406,8 +83,7 @@ export var setDefaultEvents = function (type, events) {
406
83
  }
407
84
  };
408
85
 
409
- export var wheelDeltaY = function (jQueryEvent) {
410
- var e = jQueryEvent.originalEvent || jQueryEvent;
86
+ export var wheelDeltaY = function (e) {
411
87
  var deltaY = e.wheelDeltaY;
412
88
  var delta;
413
89
 
@@ -422,12 +98,6 @@ export var wheelDeltaY = function (jQueryEvent) {
422
98
  return delta;
423
99
  };
424
100
 
425
- export var now = function () {
426
- return Number(new Date());
427
- };
428
-
429
- export var noop = function () {};
430
-
431
101
  export var renderPos = function (pos) {
432
102
  var result = [];
433
103
 
@@ -5,12 +5,12 @@ import {
5
5
  keys,
6
6
  hasClasses,
7
7
  setDefaultOptions,
8
- renderIcon
8
+ renderIcon,
9
+ on,
10
+ off,
9
11
  } from '../common';
10
12
 
11
13
  import {
12
- on,
13
- off,
14
14
  setDefaultEvents,
15
15
  convertToHtml
16
16
  } from './utils';
@@ -17,10 +17,15 @@ export var Label = (function (SankeyElement) {
17
17
  Label.prototype.getElement = function getElement () {
18
18
  var options = deepExtend({}, this.options, this.options.node.label);
19
19
  var node = options.node;
20
- var totalWidth = options.totalWidth;
21
- var position = options.position;
20
+ var diagramMinX = options.diagramMinX;
21
+ var diagramMaxX = options.diagramMaxX;
22
22
  var text = options.text;
23
23
  var offset = options.offset;
24
+ var rtl = options.rtl;
25
+ var position = options.position;
26
+ if (rtl && position !== INSIDE) {
27
+ position = position === BEFORE ? AFTER : BEFORE;
28
+ }
24
29
 
25
30
  if (!options.visible || !text) {
26
31
  return null;
@@ -28,13 +33,20 @@ export var Label = (function (SankeyElement) {
28
33
 
29
34
  var nodeBox = new Box(node.x0, node.y0, node.x1, node.y1);
30
35
  var visualOptions = this.visualOptions();
36
+ if (rtl && !visualOptions.align) {
37
+ visualOptions.align = 'right';
38
+ }
31
39
  var textbox = new TextBox(text, visualOptions);
32
40
  textbox.reflow(new Box());
33
41
  var textSizeBox = textbox.box;
34
-
35
- var goesOutside = node.x1 + textSizeBox.width() > totalWidth;
36
42
  var textY = nodeBox.center().y - (textSizeBox.height() / 2);
37
- var side = position === BEFORE || (position === INSIDE && goesOutside) ? BEFORE : AFTER;
43
+
44
+ var labelAfterLastNode = node.x1 + textSizeBox.width() > diagramMaxX;
45
+ var labelBeforeFirstNode = node.x0 - textSizeBox.width() < diagramMinX;
46
+ var side = position === BEFORE || (position === INSIDE && labelAfterLastNode) ? BEFORE : AFTER;
47
+ if (rtl) {
48
+ side = position === AFTER || (position === INSIDE && labelBeforeFirstNode) ? AFTER : BEFORE;
49
+ }
38
50
  var textOrigin = [side === BEFORE ? node.x0 - textSizeBox.width() : node.x1, textY];
39
51
 
40
52
  var textRect = new Box(textOrigin[0], textOrigin[1], textOrigin[0] + textSizeBox.width(), textOrigin[1] + textSizeBox.height());
@@ -67,11 +79,13 @@ setDefaultOptions(Label, {
67
79
  position: INSIDE, // inside, before, after
68
80
  });
69
81
 
70
- export var resolveLabelOptions = function (node, options, totalWidth) { return deepExtend({},
82
+ export var resolveLabelOptions = function (node, options, rtl, diagramMinX, diagramMaxX) { return deepExtend({},
71
83
  options,
72
84
  {
73
85
  node: node,
74
- totalWidth: totalWidth,
86
+ diagramMinX: diagramMinX,
87
+ diagramMaxX: diagramMaxX,
88
+ rtl: rtl,
75
89
  visual: node.label.visual,
76
90
  visible: node.label.visible,
77
91
  margin: node.label.margin,
@@ -1,7 +1,7 @@
1
1
  import { default as ChartLegend } from "../chart/legend/legend";
2
2
  import { SankeyElement } from "./element";
3
3
  import { setDefaultOptions } from '../common';
4
- import { BOTTOM, CENTER, POINTER } from "../common/constants";
4
+ import { BOTTOM, CENTER, LEFT, POINTER, RIGHT } from "../common/constants";
5
5
  import { AREA } from "../chart/constants";
6
6
 
7
7
  var sortData = function (a, b) {
@@ -11,6 +11,15 @@ var sortData = function (a, b) {
11
11
  return a.node.y0 - b.node.y0;
12
12
  };
13
13
 
14
+ var sortDataRTL = function (a, b) {
15
+ if (a.node.x1 - b.node.x1 !== 0) {
16
+ return a.node.x1 - b.node.x1;
17
+ }
18
+ return b.node.y0 - a.node.y0;
19
+ };
20
+
21
+ var sort = function (rtl) { return (rtl ? sortDataRTL : sortData); };
22
+
14
23
  export var Legend = (function (SankeyElement) {
15
24
  function Legend () {
16
25
  SankeyElement.apply(this, arguments);
@@ -23,8 +32,10 @@ export var Legend = (function (SankeyElement) {
23
32
  Legend.prototype.getElement = function getElement () {
24
33
  var options = this.options;
25
34
  var drawingRect = options.drawingRect;
35
+ var rtl = options.rtl;
26
36
  var nodes = options.nodes; if ( nodes === void 0 ) nodes = [];
27
37
  var item = options.item;
38
+ var position = options.position;
28
39
 
29
40
  if (options.visible === false || !nodes.length) {
30
41
  return null;
@@ -36,12 +47,13 @@ export var Legend = (function (SankeyElement) {
36
47
  background: item.areaBackground !== undefined ? item.areaBackground : node.color,
37
48
  opacity: item.areaOpacity !== undefined ? item.areaOpacity : node.opacity
38
49
  },
39
- node: node,
50
+ node: node
40
51
  }); });
41
52
 
42
- data.sort(sortData);
53
+ data.sort(sort(rtl));
43
54
 
44
- var legend = new ChartLegend(Object.assign({}, options, {data: data}));
55
+ var reverse = rtl && position !== LEFT && position !== RIGHT;
56
+ var legend = new ChartLegend(Object.assign({}, options, {data: data, reverse: reverse}), { rtl: rtl });
45
57
  legend.reflow(drawingRect);
46
58
 
47
59
  legend.renderVisual();
@@ -44,7 +44,7 @@ var angelBetweenTwoLines = function (line1, line2) {
44
44
  return Math.abs(a1 - a2);
45
45
  };
46
46
 
47
- var calculateControlPointsOffsetX = function (link) {
47
+ var calculateControlPointsOffsetX = function (link, rtl) {
48
48
  var x0 = link.x0;
49
49
  var x1 = link.x1;
50
50
  var y0 = link.y0;
@@ -76,7 +76,12 @@ var calculateControlPointsOffsetX = function (link) {
76
76
  // Another option is to assume the triangle is isosceles
77
77
  // => offset = Math.sqrt(2) * upperNarrowness;
78
78
 
79
- return y0 - y1 > 0 ? (-1) * offset : offset;
79
+ var sign = y0 - y1 > 0 ? (-1) : 1;
80
+ if (rtl) {
81
+ sign = -sign;
82
+ }
83
+
84
+ return sign * offset;
80
85
  };
81
86
 
82
87
  export var Link = (function (SankeyElement) {
@@ -129,7 +134,9 @@ export var Link = (function (SankeyElement) {
129
134
  if (!this.options.navigatable) {
130
135
  return;
131
136
  }
132
- var link = this.options.link;
137
+ var ref = this.options;
138
+ var link = ref.link;
139
+ var rtl = ref.rtl;
133
140
  var x0 = link.x0;
134
141
  var x1 = link.x1;
135
142
  var y0 = link.y0;
@@ -137,7 +144,7 @@ export var Link = (function (SankeyElement) {
137
144
  var xC = (x0 + x1) / 2;
138
145
  var halfWidth = link.width / 2;
139
146
 
140
- var offset = calculateControlPointsOffsetX(link);
147
+ var offset = calculateControlPointsOffsetX(link, rtl);
141
148
 
142
149
  this._highlight = new drawing.Path({ stroke: this.options.focusHighlight, visible: false })
143
150
  .moveTo(x0, y0 + halfWidth)