@progress/kendo-charts 2.9.0 → 2.10.0-develop.2

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.
@@ -4,11 +4,19 @@ import { INITIAL_ANIMATION_DURATION, BAR, START_SCALE } from '../constants';
4
4
 
5
5
  import { X, Y } from '../../common/constants';
6
6
  import { interpolateValue, setDefaultOptions } from '../../common';
7
+ import { easingMap } from './easingMap';
7
8
 
8
9
  class BarChartAnimation extends draw.Animation {
9
10
 
10
11
  setup() {
11
12
  const { element, options } = this;
13
+ if (options.motion && options.motion.enabled) {
14
+ options.motion.duration = options.motionConfig.initialDuration;
15
+ if (options.easing && easingMap[options.easing]) {
16
+ options.motion.easing = easingMap[options.easing];
17
+ }
18
+ }
19
+
12
20
  const bbox = element.bbox();
13
21
 
14
22
  if (bbox) {
@@ -6,6 +6,10 @@ import { setDefaultOptions } from '../../common';
6
6
 
7
7
  class BubbleAnimation extends draw.Animation {
8
8
  setup() {
9
+ if (this.options.motion && this.options.motion.enabled) {
10
+ this.options.motion.duration = this.options.motionConfig.initialDuration;
11
+ this.options.motion.easing = this.options.motionConfig.elasticEasing;
12
+ }
9
13
  const center = this.center = this.element.bbox().center();
10
14
  this.element.transform(geom.transform()
11
15
  .scale(START_SCALE, START_SCALE, center)
@@ -3,9 +3,16 @@ import { drawing as draw } from '@progress/kendo-drawing';
3
3
  import { INITIAL_ANIMATION_DURATION } from '../constants';
4
4
 
5
5
  import { interpolateValue, setDefaultOptions } from '../../common';
6
+ import { easingMap } from './easingMap';
6
7
 
7
8
  class ClipAnimation extends draw.Animation {
8
9
  setup() {
10
+ if (this.options.motion && this.options.motion.enabled) {
11
+ this.options.motion.duration = this.options.motionConfig.initialDuration;
12
+ if (this.options.easing && easingMap[this.options.easing]) {
13
+ this.options.motion.easing = easingMap[this.options.easing];
14
+ }
15
+ }
9
16
  this._setEnd(this.options.box.x1);
10
17
  }
11
18
 
@@ -0,0 +1,8 @@
1
+ export const easingMap = {
2
+ swing: [0.3583, 0, 0.6422, 1],
3
+ linear: [0, 0, 1, 1],
4
+ ease: [0.25, 0.1, 0.25, 1],
5
+ "ease-in": [0.42, 0, 1, 1],
6
+ "ease-out": [0, 0, 0.58, 1],
7
+ "ease-in-out": [0.42, 0, 0.58, 1]
8
+ };
@@ -6,6 +6,10 @@ import { setDefaultOptions } from '../../common';
6
6
 
7
7
  class FadeInAnimation extends draw.Animation {
8
8
  setup() {
9
+ if (this.options.motion && this.options.motion.enabled) {
10
+ this.options.motion.duration = this.options.motionConfig.fadeInDuration;
11
+ this.options.motion.easing = this.options.motionConfig.linearEasing;
12
+ }
9
13
  this.fadeTo = this.element.opacity();
10
14
  this.element.opacity(0);
11
15
  }
@@ -6,6 +6,10 @@ import { setDefaultOptions } from '../../common';
6
6
 
7
7
  class PieAnimation extends draw.Animation {
8
8
  setup() {
9
+ if (this.options.motion && this.options.motion.enabled) {
10
+ this.options.motion.duration = this.options.motionConfig.initialDuration;
11
+ this.options.motion.easing = this.options.motionConfig.elasticEasing;
12
+ }
9
13
  this.element.transform(geom.transform()
10
14
  .scale(START_SCALE, START_SCALE, this.options.center)
11
15
  );
@@ -366,11 +366,15 @@ class Chart {
366
366
  model.renderVisual();
367
367
 
368
368
  const transitions = this.options.transitions;
369
+ const motionConfig = this.options.motion || {};
370
+ const motion = {
371
+ enabled: motionConfig.enabled
372
+ };
369
373
  if (transitions !== false) {
370
374
  model.traverse(function(element) {
371
375
  if (element.animation) {
372
376
  const loading = (transitions && transitions !== true) ? transitions.loading : transitions;
373
- element.animation.options = Object.assign({}, element.animation.options, loading);
377
+ element.animation.options = Object.assign({}, element.animation.options, loading, {motionConfig, motion});
374
378
  element.animation.setup();
375
379
  }
376
380
  });
@@ -2311,6 +2315,9 @@ function triggerPaneRender(panes) {
2311
2315
 
2312
2316
  setDefaultOptions(Chart, {
2313
2317
  renderAs: "",
2318
+ motion: {
2319
+ enabled: false,
2320
+ },
2314
2321
  chartArea: {},
2315
2322
  legend: {
2316
2323
  visible: true,
@@ -51,6 +51,42 @@ const getSeriesColors = (element) => {
51
51
  return result;
52
52
  };
53
53
 
54
+ const parseToMS = (value) => {
55
+ // Handle CSS time values (e.g., "200ms", "0.5s", ".3s")
56
+ if (typeof value === 'string' && value.endsWith('ms')) {
57
+ return parseFloat(value);
58
+ } else if (typeof value === 'string' && value.endsWith('s')) {
59
+ return parseFloat(value) * 1000;
60
+ }
61
+ return parseFloat(value);
62
+ };
63
+
64
+ function parseCubicBezier(input) {
65
+ const s = input.trim();
66
+ const m = s.match(
67
+ /cubic-bezier\s*\(\s*([+-]?\d*\.?\d+)\s*,\s*([+-]?\d*\.?\d+)\s*,\s*([+-]?\d*\.?\d+)\s*,\s*([+-]?\d*\.?\d+)\s*\)\s*/i
68
+ );
69
+
70
+ return m ? [Number(m[1]), Number(m[2]), Number(m[3]), Number(m[4])] : [0, 0, 1, 1];
71
+ }
72
+
73
+ function parseEasing(input) {
74
+ switch (input) {
75
+ case "linear":
76
+ return [0, 0, 1, 1];
77
+ case "ease":
78
+ return [0.25, 0.1, 0.25, 1];
79
+ case "ease-in":
80
+ return [0.42, 0, 1, 1];
81
+ case "ease-out":
82
+ return [0, 0, 0.58, 1];
83
+ case "ease-in-out":
84
+ return [0.42, 0, 0.58, 1];
85
+ default:
86
+ return input ? parseCubicBezier(input) : [0, 0, 1, 1];
87
+ }
88
+ }
89
+
54
90
  // -----------------------------------------------------------------------------
55
91
  // CSS Variable Groups (shared + component specific)
56
92
  // -----------------------------------------------------------------------------
@@ -84,7 +120,11 @@ const chartVariables = {
84
120
  notesBg: "--kendo-chart-notes-bg",
85
121
  notesBorder: "--kendo-chart-notes-border",
86
122
  notesLines: "--kendo-chart-notes-lines",
87
- inactive: "--kendo-chart-inactive"
123
+ inactive: "--kendo-chart-inactive",
124
+ initialAnimationDuration: '--kendo-duration-steady',
125
+ fadeInAnimationDuration: '--kendo-duration-rapid',
126
+ elasticEasing: '--kendo-easing-elastic',
127
+ linearEasing: '--kendo-easing-linear',
88
128
  };
89
129
 
90
130
  // Sankey-specific variables (in addition to shared)
@@ -252,6 +292,13 @@ export const chartTheme = (element) => {
252
292
  },
253
293
  });
254
294
 
295
+ const motion = {
296
+ initialDuration: parseToMS(getProp(element, vars.initialAnimationDuration)),
297
+ fadeInDuration: parseToMS(getProp(element, vars.fadeInAnimationDuration)),
298
+ elasticEasing: parseEasing(getProp(element, vars.elasticEasing)),
299
+ linearEasing: parseEasing(getProp(element, vars.linearEasing)),
300
+ };
301
+
255
302
  return {
256
303
  axisDefaults: {
257
304
  crosshair: {
@@ -329,6 +376,7 @@ export const chartTheme = (element) => {
329
376
  title: {
330
377
  font: paneTitleFont(element),
331
378
  }
332
- }
379
+ },
380
+ motion
333
381
  };
334
382
  };
@@ -7,7 +7,8 @@ import { getVersion } from '../utils/index';
7
7
  const BYTE = "byte";
8
8
 
9
9
  export class Utf8Encoder {
10
- constructor() {
10
+ constructor(options = {}) {
11
+ this.includeBOM = options.includeBOM !== undefined ? options.includeBOM : true;
11
12
  this.initProperties();
12
13
 
13
14
  this.mode = DataModeInstances[this.encodingMode];
@@ -39,7 +40,7 @@ export class Utf8Encoder {
39
40
  }
40
41
 
41
42
  encode(str) {
42
- let result = this.utfBOM;
43
+ let result = this.includeBOM ? this.utfBOM : "";
43
44
 
44
45
  for (let i = 0; i < str.length; i++) {
45
46
  result += this.encodeCharacter(str.charCodeAt(i));
@@ -539,7 +539,8 @@ export function calculateDarkModulesRatioScore(darkModules, total) {
539
539
 
540
540
  export function createQRCodeDataEncoder(encoding) {
541
541
  if (encoding && encoding.toLowerCase().indexOf("utf_8") >= 0) {
542
- return new Utf8Encoder();
542
+ const includeBOM = encoding.toLowerCase().indexOf("no_bom") < 0;
543
+ return new Utf8Encoder({ includeBOM });
543
544
  }
544
545
 
545
546
  return new IsoEncoder();
@@ -4,11 +4,19 @@ import { INITIAL_ANIMATION_DURATION, BAR, START_SCALE } from '../constants';
4
4
 
5
5
  import { X, Y } from '../../common/constants';
6
6
  import { interpolateValue, setDefaultOptions } from '../../common';
7
+ import { easingMap } from './easingMap';
7
8
 
8
9
  class BarChartAnimation extends draw.Animation {
9
10
 
10
11
  setup() {
11
12
  const { element, options } = this;
13
+ if (options.motion && options.motion.enabled) {
14
+ options.motion.duration = options.motionConfig.initialDuration;
15
+ if (options.easing && easingMap[options.easing]) {
16
+ options.motion.easing = easingMap[options.easing];
17
+ }
18
+ }
19
+
12
20
  const bbox = element.bbox();
13
21
 
14
22
  if (bbox) {
@@ -6,6 +6,10 @@ import { setDefaultOptions } from '../../common';
6
6
 
7
7
  class BubbleAnimation extends draw.Animation {
8
8
  setup() {
9
+ if (this.options.motion && this.options.motion.enabled) {
10
+ this.options.motion.duration = this.options.motionConfig.initialDuration;
11
+ this.options.motion.easing = this.options.motionConfig.elasticEasing;
12
+ }
9
13
  const center = this.center = this.element.bbox().center();
10
14
  this.element.transform(geom.transform()
11
15
  .scale(START_SCALE, START_SCALE, center)
@@ -3,9 +3,16 @@ import { drawing as draw } from '@progress/kendo-drawing';
3
3
  import { INITIAL_ANIMATION_DURATION } from '../constants';
4
4
 
5
5
  import { interpolateValue, setDefaultOptions } from '../../common';
6
+ import { easingMap } from './easingMap';
6
7
 
7
8
  class ClipAnimation extends draw.Animation {
8
9
  setup() {
10
+ if (this.options.motion && this.options.motion.enabled) {
11
+ this.options.motion.duration = this.options.motionConfig.initialDuration;
12
+ if (this.options.easing && easingMap[this.options.easing]) {
13
+ this.options.motion.easing = easingMap[this.options.easing];
14
+ }
15
+ }
9
16
  this._setEnd(this.options.box.x1);
10
17
  }
11
18
 
@@ -0,0 +1,8 @@
1
+ export const easingMap = {
2
+ swing: [0.3583, 0, 0.6422, 1],
3
+ linear: [0, 0, 1, 1],
4
+ ease: [0.25, 0.1, 0.25, 1],
5
+ "ease-in": [0.42, 0, 1, 1],
6
+ "ease-out": [0, 0, 0.58, 1],
7
+ "ease-in-out": [0.42, 0, 0.58, 1]
8
+ };
@@ -6,6 +6,10 @@ import { setDefaultOptions } from '../../common';
6
6
 
7
7
  class FadeInAnimation extends draw.Animation {
8
8
  setup() {
9
+ if (this.options.motion && this.options.motion.enabled) {
10
+ this.options.motion.duration = this.options.motionConfig.fadeInDuration;
11
+ this.options.motion.easing = this.options.motionConfig.linearEasing;
12
+ }
9
13
  this.fadeTo = this.element.opacity();
10
14
  this.element.opacity(0);
11
15
  }
@@ -6,6 +6,10 @@ import { setDefaultOptions } from '../../common';
6
6
 
7
7
  class PieAnimation extends draw.Animation {
8
8
  setup() {
9
+ if (this.options.motion && this.options.motion.enabled) {
10
+ this.options.motion.duration = this.options.motionConfig.initialDuration;
11
+ this.options.motion.easing = this.options.motionConfig.elasticEasing;
12
+ }
9
13
  this.element.transform(geom.transform()
10
14
  .scale(START_SCALE, START_SCALE, this.options.center)
11
15
  );
@@ -366,11 +366,15 @@ class Chart {
366
366
  model.renderVisual();
367
367
 
368
368
  const transitions = this.options.transitions;
369
+ const motionConfig = this.options.motion || {};
370
+ const motion = {
371
+ enabled: motionConfig.enabled
372
+ };
369
373
  if (transitions !== false) {
370
374
  model.traverse(function(element) {
371
375
  if (element.animation) {
372
376
  const loading = (transitions && transitions !== true) ? transitions.loading : transitions;
373
- element.animation.options = Object.assign({}, element.animation.options, loading);
377
+ element.animation.options = Object.assign({}, element.animation.options, loading, {motionConfig, motion});
374
378
  element.animation.setup();
375
379
  }
376
380
  });
@@ -2311,6 +2315,9 @@ function triggerPaneRender(panes) {
2311
2315
 
2312
2316
  setDefaultOptions(Chart, {
2313
2317
  renderAs: "",
2318
+ motion: {
2319
+ enabled: false,
2320
+ },
2314
2321
  chartArea: {},
2315
2322
  legend: {
2316
2323
  visible: true,
@@ -51,6 +51,42 @@ const getSeriesColors = (element) => {
51
51
  return result;
52
52
  };
53
53
 
54
+ const parseToMS = (value) => {
55
+ // Handle CSS time values (e.g., "200ms", "0.5s", ".3s")
56
+ if (typeof value === 'string' && value.endsWith('ms')) {
57
+ return parseFloat(value);
58
+ } else if (typeof value === 'string' && value.endsWith('s')) {
59
+ return parseFloat(value) * 1000;
60
+ }
61
+ return parseFloat(value);
62
+ };
63
+
64
+ function parseCubicBezier(input) {
65
+ const s = input.trim();
66
+ const m = s.match(
67
+ /cubic-bezier\s*\(\s*([+-]?\d*\.?\d+)\s*,\s*([+-]?\d*\.?\d+)\s*,\s*([+-]?\d*\.?\d+)\s*,\s*([+-]?\d*\.?\d+)\s*\)\s*/i
68
+ );
69
+
70
+ return m ? [Number(m[1]), Number(m[2]), Number(m[3]), Number(m[4])] : [0, 0, 1, 1];
71
+ }
72
+
73
+ function parseEasing(input) {
74
+ switch (input) {
75
+ case "linear":
76
+ return [0, 0, 1, 1];
77
+ case "ease":
78
+ return [0.25, 0.1, 0.25, 1];
79
+ case "ease-in":
80
+ return [0.42, 0, 1, 1];
81
+ case "ease-out":
82
+ return [0, 0, 0.58, 1];
83
+ case "ease-in-out":
84
+ return [0.42, 0, 0.58, 1];
85
+ default:
86
+ return input ? parseCubicBezier(input) : [0, 0, 1, 1];
87
+ }
88
+ }
89
+
54
90
  // -----------------------------------------------------------------------------
55
91
  // CSS Variable Groups (shared + component specific)
56
92
  // -----------------------------------------------------------------------------
@@ -84,7 +120,11 @@ const chartVariables = {
84
120
  notesBg: "--kendo-chart-notes-bg",
85
121
  notesBorder: "--kendo-chart-notes-border",
86
122
  notesLines: "--kendo-chart-notes-lines",
87
- inactive: "--kendo-chart-inactive"
123
+ inactive: "--kendo-chart-inactive",
124
+ initialAnimationDuration: '--kendo-duration-steady',
125
+ fadeInAnimationDuration: '--kendo-duration-rapid',
126
+ elasticEasing: '--kendo-easing-elastic',
127
+ linearEasing: '--kendo-easing-linear',
88
128
  };
89
129
 
90
130
  // Sankey-specific variables (in addition to shared)
@@ -252,6 +292,13 @@ export const chartTheme = (element) => {
252
292
  },
253
293
  });
254
294
 
295
+ const motion = {
296
+ initialDuration: parseToMS(getProp(element, vars.initialAnimationDuration)),
297
+ fadeInDuration: parseToMS(getProp(element, vars.fadeInAnimationDuration)),
298
+ elasticEasing: parseEasing(getProp(element, vars.elasticEasing)),
299
+ linearEasing: parseEasing(getProp(element, vars.linearEasing)),
300
+ };
301
+
255
302
  return {
256
303
  axisDefaults: {
257
304
  crosshair: {
@@ -329,6 +376,7 @@ export const chartTheme = (element) => {
329
376
  title: {
330
377
  font: paneTitleFont(element),
331
378
  }
332
- }
379
+ },
380
+ motion
333
381
  };
334
382
  };
@@ -7,7 +7,8 @@ import { getVersion } from '../utils/index';
7
7
  const BYTE = "byte";
8
8
 
9
9
  export class Utf8Encoder {
10
- constructor() {
10
+ constructor(options = {}) {
11
+ this.includeBOM = options.includeBOM !== undefined ? options.includeBOM : true;
11
12
  this.initProperties();
12
13
 
13
14
  this.mode = DataModeInstances[this.encodingMode];
@@ -39,7 +40,7 @@ export class Utf8Encoder {
39
40
  }
40
41
 
41
42
  encode(str) {
42
- let result = this.utfBOM;
43
+ let result = this.includeBOM ? this.utfBOM : "";
43
44
 
44
45
  for (let i = 0; i < str.length; i++) {
45
46
  result += this.encodeCharacter(str.charCodeAt(i));
@@ -539,7 +539,8 @@ export function calculateDarkModulesRatioScore(darkModules, total) {
539
539
 
540
540
  export function createQRCodeDataEncoder(encoding) {
541
541
  if (encoding && encoding.toLowerCase().indexOf("utf_8") >= 0) {
542
- return new Utf8Encoder();
542
+ const includeBOM = encoding.toLowerCase().indexOf("no_bom") < 0;
543
+ return new Utf8Encoder({ includeBOM });
543
544
  }
544
545
 
545
546
  return new IsoEncoder();