@opendata-ai/openchart-core 6.24.0 → 6.24.1

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opendata-ai/openchart-core",
3
- "version": "6.24.0",
3
+ "version": "6.24.1",
4
4
  "description": "Types, theme, colors, accessibility, and utilities for openchart",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Riley Hilliard",
@@ -65,30 +65,42 @@ export function findAccessibleColor(baseColor: string, bg: string, targetRatio =
65
65
  if (c == null) return baseColor;
66
66
 
67
67
  const bgLum = relativeLuminance(bg);
68
- // Determine direction: darken if bg is light, lighten if bg is dark.
69
- const bgIsLight = bgLum > 0.5;
70
-
71
- // Binary search for the lightness adjustment that hits the target ratio.
72
- let lo = 0;
73
- let hi = 1;
74
- let best = baseColor;
75
-
76
- for (let i = 0; i < 20; i++) {
77
- const mid = (lo + hi) / 2;
78
- const adjusted = bgIsLight
79
- ? rgb(c.r * (1 - mid), c.g * (1 - mid), c.b * (1 - mid))
80
- : rgb(c.r + (255 - c.r) * mid, c.g + (255 - c.g) * mid, c.b + (255 - c.b) * mid);
81
-
82
- const hex = adjusted.formatHex();
83
- const ratio = contrastRatio(hex, bg);
84
-
85
- if (ratio >= targetRatio) {
86
- best = hex;
87
- hi = mid; // try less adjustment
88
- } else {
89
- lo = mid; // need more adjustment
68
+ const baseLum = relativeLuminance(baseColor);
69
+
70
+ // Try both directions: prefer the one matching bg luminance, but fall back
71
+ // to the other if the base color is already at the extreme (e.g. white on
72
+ // a medium-luminance background can't be lightened, so darken instead).
73
+ const preferDarken = bgLum > 0.5;
74
+ const directions = preferDarken ? [true, false] : [false, true];
75
+
76
+ for (const darken of directions) {
77
+ // Skip impossible directions: can't lighten white or darken black.
78
+ if (!darken && baseLum > 0.95) continue;
79
+ if (darken && baseLum < 0.05) continue;
80
+
81
+ let lo = 0;
82
+ let hi = 1;
83
+ let best: string | null = null;
84
+
85
+ for (let i = 0; i < 20; i++) {
86
+ const mid = (lo + hi) / 2;
87
+ const adjusted = darken
88
+ ? rgb(c.r * (1 - mid), c.g * (1 - mid), c.b * (1 - mid))
89
+ : rgb(c.r + (255 - c.r) * mid, c.g + (255 - c.g) * mid, c.b + (255 - c.b) * mid);
90
+
91
+ const hex = adjusted.formatHex();
92
+ const ratio = contrastRatio(hex, bg);
93
+
94
+ if (ratio >= targetRatio) {
95
+ best = hex;
96
+ hi = mid;
97
+ } else {
98
+ lo = mid;
99
+ }
90
100
  }
101
+
102
+ if (best) return best;
91
103
  }
92
104
 
93
- return best;
105
+ return baseColor;
94
106
  }
package/src/types/spec.ts CHANGED
@@ -523,6 +523,8 @@ interface AnnotationBase {
523
523
  opacity?: number;
524
524
  /** Z-index for render ordering. Higher values render on top. */
525
525
  zIndex?: number;
526
+ /** When false, the annotation is always shown even at compact breakpoints. Default true. */
527
+ responsive?: boolean;
526
528
  }
527
529
 
528
530
  /**
@@ -588,13 +590,15 @@ export interface RangeAnnotation extends AnnotationBase {
588
590
  * Useful for baselines (zero), targets, or thresholds.
589
591
  */
590
592
  export interface RefLineAnnotation extends AnnotationBase {
591
- type: 'refline';
593
+ type: 'refline' | 'rule';
592
594
  /** X-axis value for a vertical reference line. */
593
595
  x?: string | number;
594
596
  /** Y-axis value for a horizontal reference line. */
595
597
  y?: string | number;
596
598
  /** Line style. */
597
599
  style?: 'solid' | 'dashed' | 'dotted';
600
+ /** Raw SVG dash pattern override, e.g. [4, 4]. Takes precedence over style. */
601
+ strokeDash?: number[];
598
602
  /** Line width in pixels. */
599
603
  strokeWidth?: number;
600
604
  /** Pixel offset for the reference line label. */
@@ -715,6 +719,8 @@ export interface LegendConfig {
715
719
  symbolLimit?: number;
716
720
  /** Maximum number of rows for top-positioned legends before truncation. Defaults to 2. */
717
721
  maxRows?: number;
722
+ /** Series names to exclude from the legend. Excluded series still render in the chart. */
723
+ exclude?: string[];
718
724
  }
719
725
 
720
726
  // ---------------------------------------------------------------------------
@@ -1408,7 +1414,7 @@ export function isRangeAnnotation(annotation: Annotation): annotation is RangeAn
1408
1414
 
1409
1415
  /** Check if an annotation is a RefLineAnnotation. */
1410
1416
  export function isRefLineAnnotation(annotation: Annotation): annotation is RefLineAnnotation {
1411
- return annotation.type === 'refline';
1417
+ return annotation.type === 'refline' || annotation.type === 'rule';
1412
1418
  }
1413
1419
 
1414
1420
  // ---------------------------------------------------------------------------