@humanforest/charts 0.3.2 → 0.3.3

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 (2) hide show
  1. package/package.json +2 -2
  2. package/src/FSparkline.vue +16 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@humanforest/charts",
3
- "version": "0.3.2",
3
+ "version": "0.3.3",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "src"
@@ -24,7 +24,7 @@
24
24
  "vue": "^3.5.22"
25
25
  },
26
26
  "dependencies": {
27
- "@humanforest/tokens": "^0.3.2"
27
+ "@humanforest/tokens": "^0.3.3"
28
28
  },
29
29
  "publishConfig": {
30
30
  "access": "public"
@@ -50,6 +50,12 @@ const props = withDefaults(
50
50
  area?: boolean;
51
51
  /** Marks the last point, so the series has an end rather than running off the edge. */
52
52
  endpoint?: boolean;
53
+ /**
54
+ * Takes the height its container gives it, with `height` as the floor. For a graphic in a space
55
+ * its surroundings have made taller (a KPI bleed row that a stretched card or a group has given
56
+ * more height), where the chart is the part that should grow. Works for both marks.
57
+ */
58
+ fill?: boolean;
53
59
  /**
54
60
  * Monotone interpolation, on by default. Monotone rather than a plain spline: it stays inside
55
61
  * the data's own range, so no peak appears between two points that neither of them reached.
@@ -71,7 +77,7 @@ const props = withDefaults(
71
77
  */
72
78
  mark?: 'line' | 'bar';
73
79
  }>(),
74
- { height: 32, color: 'var(--ui-primary)', area: false, endpoint: false, curve: true, mark: 'line', compare: undefined, compareColor: undefined },
80
+ { height: 32, color: 'var(--ui-primary)', area: false, endpoint: false, fill: false, curve: true, mark: 'line', compare: undefined, compareColor: undefined },
75
81
  );
76
82
 
77
83
  if (import.meta.env.DEV) {
@@ -155,14 +161,14 @@ const endpointTop = computed(() => {
155
161
  </script>
156
162
 
157
163
  <template>
158
- <div class="relative w-full" :style="{ height: `${height}px`, color }">
164
+ <div class="relative w-full" :class="fill ? 'h-full' : ''" :style="fill ? { minHeight: `${height}px`, color } : { height: `${height}px`, color }">
159
165
  <!-- Plain DOM rather than a mark: there are no axes, scales or tooltip to share with the XY
160
166
  container, so a flex row of columns is the whole implementation and costs no chart runtime.
161
167
  The 2px gap is fixed, so the bucket count sets how thin the bars get: n buckets across w
162
168
  pixels leaves (w - 2(n - 1)) / n each. A tile 280px wide holds 12 buckets at 21px and 60 at
163
169
  2.7px — still bars; past roughly 60 the gap outweighs the bar and the row reads as a
164
170
  texture, where the measure belongs to a line instead. -->
165
- <div v-if="mark === 'bar'" class="flex h-full w-full items-end gap-0.5" aria-hidden="true">
171
+ <div v-if="mark === 'bar'" class="flex w-full items-end gap-0.5" :class="fill ? 'absolute inset-0' : 'h-full'" aria-hidden="true">
166
172
  <span
167
173
  v-for="(v, i) in data"
168
174
  :key="i"
@@ -180,12 +186,17 @@ const endpointTop = computed(() => {
180
186
  <!-- No bottom margin: the graphic sits on the tile's own bottom edge, and 2px of clearance
181
187
  there reads as a misaligned card rather than as breathing room. The top keeps its 2px so a
182
188
  peak is not clipped by the stroke's own width, and the right reserves room for the endpoint
183
- dot when there is one. -->
189
+ dot when there is one. Under `fill` the container is laid over the root rather than sizing
190
+ it: the root takes the space it is given, floored at `height`, and Unovis measures that box,
191
+ never its own SVG (which would feed back) and never its 300px fallback for an empty box.
192
+ An inline style, not a utility: Unovis's own stylesheet pins `.unovis-xy-container` to
193
+ `position: relative`, and a class loses to it. -->
184
194
  <VisXYContainer
185
195
  v-else
186
196
  :key="themeVersion"
197
+ :style="fill ? { position: 'absolute', inset: '0' } : undefined"
187
198
  :data="points"
188
- :height="height"
199
+ :height="fill ? undefined : height"
189
200
  :margin="{ top: 2, right: endpoint ? 4 : 0, bottom: 0, left: 0 }"
190
201
  :y-domain="domain ?? undefined"
191
202
  :duration="motionDuration('slow')"