@coinbase/cds-mobile-visualization 3.4.0-beta.10 → 3.4.0-beta.11

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.
@@ -1,4 +1,4 @@
1
- import { applySerializableScale, isCategoricalScale, isLogScale, isNumericScale } from './scale';
1
+ import { applyBandScale, applySerializableScale, isCategoricalScale, isLogScale, isNumericScale } from './scale';
2
2
 
3
3
  /**
4
4
  * Position a label should be placed relative to the point
@@ -10,19 +10,38 @@ import { applySerializableScale, isCategoricalScale, isLogScale, isNumericScale
10
10
 
11
11
  /**
12
12
  * Get a point from a data value and a scale.
13
- * @note for categorical scales, the point will be centered within the band.
14
- * @note for log scales, zero and negative values are clamped to a small positive value.
15
- * @param data - the data value.
16
- * @param scale - the scale function.
17
- * @returns the pixel value (defaulting to 0 if data value is not defined in scale).
13
+ *
14
+ * @param dataValue - The data value to convert to a pixel position.
15
+ * @param scale - The scale function.
16
+ * @param anchor (@default 'middle') - For band scales, where to anchor the point within the band.
17
+ * @returns The pixel value (@default 0 if data value is not defined in scale).
18
18
  */
19
- export const getPointOnScale = (dataValue, scale) => {
20
- var _scale2;
19
+ export const getPointOnScale = function (dataValue, scale, anchor) {
20
+ var _scale;
21
+ if (anchor === void 0) {
22
+ anchor = 'middle';
23
+ }
21
24
  if (isCategoricalScale(scale)) {
22
- var _scale, _scale$bandwidth;
23
- const bandStart = (_scale = scale(dataValue)) != null ? _scale : 0;
24
- const bandwidth = (_scale$bandwidth = scale.bandwidth()) != null ? _scale$bandwidth : 0;
25
- return bandStart + bandwidth / 2;
25
+ var _bandScale$bandwidth, _bandScale$step;
26
+ const bandScale = scale;
27
+ const bandStart = bandScale(dataValue);
28
+ if (bandStart === undefined) return 0;
29
+ const bandwidth = (_bandScale$bandwidth = bandScale.bandwidth == null ? void 0 : bandScale.bandwidth()) != null ? _bandScale$bandwidth : 0;
30
+ const step = (_bandScale$step = bandScale.step == null ? void 0 : bandScale.step()) != null ? _bandScale$step : bandwidth;
31
+ const paddingOffset = (step - bandwidth) / 2;
32
+ const stepStart = bandStart - paddingOffset;
33
+ switch (anchor) {
34
+ case 'stepStart':
35
+ return stepStart;
36
+ case 'bandStart':
37
+ return bandStart;
38
+ case 'middle':
39
+ return bandStart + bandwidth / 2;
40
+ case 'bandEnd':
41
+ return bandStart + bandwidth;
42
+ case 'stepEnd':
43
+ return stepStart + step;
44
+ }
26
45
  }
27
46
 
28
47
  // For log scales, ensure the value is positive
@@ -30,23 +49,47 @@ export const getPointOnScale = (dataValue, scale) => {
30
49
  if (isLogScale(scale) && dataValue <= 0) {
31
50
  adjustedValue = 0.001; // Use a small positive value for log scales
32
51
  }
33
- return (_scale2 = scale(adjustedValue)) != null ? _scale2 : 0;
52
+ return (_scale = scale(adjustedValue)) != null ? _scale : 0;
34
53
  };
35
54
 
36
55
  /**
37
56
  * Get a point from a data value and a serializable scale (worklet-compatible).
38
- * @note for categorical scales, the point will be centered within the band.
39
- * @note for log scales, zero and negative values are clamped to a small positive value.
40
- * @param dataValue - the data value.
41
- * @param scale - the serializable scale object.
42
- * @returns the pixel value (defaulting to 0 if data value is not defined in scale).
57
+ *
58
+ * @param dataValue - The data value to convert to a pixel position.
59
+ * @param scale - The serializable scale function.
60
+ * @param anchor (@default 'middle') - For band scales, where to anchor the point within the band.
61
+ * @returns The pixel value (@default 0 if data value is not defined in scale).
43
62
  */
44
- export function getPointOnSerializableScale(dataValue, scale) {
63
+ export function getPointOnSerializableScale(dataValue, scale, anchor) {
45
64
  'worklet';
46
65
 
66
+ // Handle band scales with the specified position
67
+ if (anchor === void 0) {
68
+ anchor = 'middle';
69
+ }
47
70
  if (scale.type === 'band') {
48
- const bandStart = applySerializableScale(dataValue, scale);
49
- return bandStart + scale.bandwidth / 2;
71
+ const bandScale = scale;
72
+ const [domainMin, domainMax] = bandScale.domain;
73
+ const index = dataValue - domainMin;
74
+ const n = domainMax - domainMin + 1;
75
+ if (index < 0 || index >= n) {
76
+ return 0;
77
+ }
78
+ const bandStart = applyBandScale(dataValue, bandScale);
79
+ const paddingOffset = (bandScale.step - bandScale.bandwidth) / 2;
80
+ const stepStart = bandStart - paddingOffset;
81
+ switch (anchor) {
82
+ case 'stepStart':
83
+ return stepStart;
84
+ case 'bandStart':
85
+ return bandStart;
86
+ case 'middle':
87
+ return bandStart + bandScale.bandwidth / 2;
88
+ case 'bandEnd':
89
+ return bandStart + bandScale.bandwidth;
90
+ case 'stepEnd':
91
+ return stepStart + bandScale.step;
92
+ }
50
93
  }
51
94
 
52
95
  // For log scales, ensure the value is positive
@@ -53,10 +53,21 @@ export const getCategoricalScale = _ref2 => {
53
53
  const domainArray = Array.from({
54
54
  length: domain.max - domain.min + 1
55
55
  }, (_, i) => i);
56
- const scale = scaleBand().domain(domainArray).range([range.min, range.max]).padding(padding);
56
+ const scale = scaleBand().domain(domainArray).range([range.min, range.max]).paddingInner(padding).paddingOuter(padding / 2);
57
57
  return scale;
58
58
  };
59
59
 
60
+ /**
61
+ * Anchor position for points on a scale. Currently used only for band scales.
62
+ *
63
+ * For band scales, this determines where within the band to position a point:
64
+ * - `'stepStart'` - At the start of the step
65
+ * - `'bandStart'` - At the start of the band
66
+ * - `'middle'` - At the center of the band
67
+ * - `'bandEnd'` - At the end of the band
68
+ * - `'stepEnd'` - At the end of the step
69
+ */
70
+
60
71
  /**
61
72
  * Convert a D3 scale to a serializable scale configuration that can be used in worklets
62
73
  */
@@ -176,7 +187,7 @@ export function applyBandScale(value, scale) {
176
187
  if (index < 0 || index >= n) {
177
188
  return r0;
178
189
  }
179
- const paddingOffset = step - scale.bandwidth;
190
+ const paddingOffset = (step - scale.bandwidth) / 2;
180
191
  const bandStart = r0 + step * index + paddingOffset;
181
192
  return bandStart;
182
193
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coinbase/cds-mobile-visualization",
3
- "version": "3.4.0-beta.10",
3
+ "version": "3.4.0-beta.11",
4
4
  "description": "Coinbase Design System - Mobile Visualization Native",
5
5
  "repository": {
6
6
  "type": "git",
@@ -36,9 +36,9 @@
36
36
  "CHANGELOG"
37
37
  ],
38
38
  "peerDependencies": {
39
- "@coinbase/cds-common": "^8.35.1",
39
+ "@coinbase/cds-common": "^8.36.2",
40
40
  "@coinbase/cds-lottie-files": "^3.3.4",
41
- "@coinbase/cds-mobile": "^8.35.1",
41
+ "@coinbase/cds-mobile": "^8.36.2",
42
42
  "@coinbase/cds-utils": "^2.3.5",
43
43
  "@shopify/react-native-skia": "^1.12.4 || ^2.0.0",
44
44
  "react": "^18.3.1",
@@ -57,9 +57,9 @@
57
57
  "@babel/preset-env": "^7.28.0",
58
58
  "@babel/preset-react": "^7.27.1",
59
59
  "@babel/preset-typescript": "^7.27.1",
60
- "@coinbase/cds-common": "^8.35.1",
60
+ "@coinbase/cds-common": "^8.36.2",
61
61
  "@coinbase/cds-lottie-files": "^3.3.4",
62
- "@coinbase/cds-mobile": "^8.35.1",
62
+ "@coinbase/cds-mobile": "^8.36.2",
63
63
  "@coinbase/cds-utils": "^2.3.5",
64
64
  "@figma/code-connect": "^1.3.4",
65
65
  "@shopify/react-native-skia": "1.12.4",