diff --git a/src/tracks/stack/stack-track.ts b/src/tracks/stack/stack-track.ts index 3f8a04f..042ebfb 100644 --- a/src/tracks/stack/stack-track.ts +++ b/src/tracks/stack/stack-track.ts @@ -1,7 +1,8 @@ import { scaleLinear, ScaleLinear } from 'd3-scale'; import { select, Selection } from 'd3-selection'; +import { clamp } from '@equinor/videx-math'; import SvgTrack from '../svg-track'; -import { setAttrs, setProps } from '../../utils'; +import { getContrastYIQ, setAttrs, setProps } from '../../utils'; import { StackedTrackOptions, AreaData, TransformedAreaData } from './interfaces'; import { OnMountEvent, OnRescaleEvent, OnUpdateEvent } from '../interfaces'; @@ -30,7 +31,12 @@ function plotLabel( } g.select('g.label').remove(); - const fontSize = 18; + // Restrict fontSize to the smallest of 50% of width and 10% of height + let fontSize = Math.min(width * 0.5, height * 0.1); + + // Clamp to ensure fontSize remains readable + fontSize = clamp(fontSize, 8, 18); + if ((fontSize + 2) > height || (fontSize + 2) > width) { // Disregard any small areas that cannot display a single letter. return; @@ -52,10 +58,6 @@ function plotLabel( // we compute our own label offset so that it will rotate from the text middle // instead of the text baseline. const rad_angle = angle * Math.PI / 180; - const dx = Math.sin(rad_angle) * (fontSize + 1) / 3; - const dy = Math.cos(rad_angle) * (fontSize + 1) / 3; - labelX -= dx; - labelY += dy; const labelTransform = `translate(${labelX},${labelY})rotate(${angle})`; const labelGroup = g.append('g') @@ -65,14 +67,15 @@ function plotLabel( const label = labelGroup.append('text').text(d.name); setProps(label, { styles: { + 'dominant-baseline': 'middle', 'text-anchor': 'middle', 'text-rendering': 'optimizeSpeed', 'stroke-width': 0.5, }, attrs: { class: 'label', - fill: 'black', - stroke: '#333', + fill: getContrastYIQ(d.color), + stroke: getContrastYIQ(d.color), 'text-anchor': 'middle', 'font-size': `${fontSize}px`, }, diff --git a/src/utils/utils.ts b/src/utils/utils.ts index 9b9522a..18d04f1 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -57,3 +57,17 @@ export function debouncer(debounceInterval: number = 20) : DebounceFunction { return debounce; } + +/** + * Calculate font color based on background color + * Dark background will give white text color and vice versa + */ +export function getContrastYIQ(rgbString: string) { + const rgb = rgbString.replace(/[^\d,.]/g, '').split(','); + + const r = parseFloat(rgb[0]); + const g = parseFloat(rgb[1]); + const b = parseFloat(rgb[2]); + const yiq = ((r * 299) + (g * 587) + (b * 114)) / 1000; + return (yiq >= 110) ? 'black' : 'white'; +}