createSvgBarRangePath function
Creates the d of the part of a bar between two ratios, across its whole thickness, in any group: the fill level of a bar graph (0 to the value) or a threshold zone. The ratios are clamped to [0, 1].
ts
import { createSvgBarRangePath } from 'utils';Signature
ts
export function createSvgBarRangePath(
target: SVGGraphicsElement,
bar: SvgBar,
fromRatio: number,
toRatio: number,
): stringParameters
| Name | Description |
|---|---|
target | The element in whose coordinates the path is written, such as the <path> that receives it. |
bar | The element giving the area of the bar, and its direction. |
fromRatio | The start of the range, from 0 (start of the bar) to 1 (end). |
toRatio | The end of the range, in the same way. |
Returns
The closed path data.
Errors
- Throws TypeError: When an element is not rendered.
Example
ts
const bar = { element: track, direction: 'up' } as const;
level.setAttribute('d', createSvgBarRangePath(level, bar, 0, ratio(value, max))); // the fill level
redZone.setAttribute('d', createSvgBarRangePath(redZone, bar, 0.8, 1)); // the top 20 %Tests
Line coverage: 100 %.
- ✅ draws a range of a up bar
- ✅ draws a range of a down bar
- ✅ draws a range of a right bar
- ✅ draws a range of a left bar
- ✅ throws a TypeError for a path that is not rendered
Source
src/svg-shape/create-svg-bar-range-path.ts (on GitHub)
Uses
clamp: Restricts a number to an interval.SvgBar: A bar gauge laid on the box of an element, forcreateSvgBarRangePathandcreateSvgBarTicksPath.
Files it needs
src/svg-shape/create-svg-bar-range-path.ts imports, directly or not:
src/math/clamp.tssrc/math/round-to-fraction-digits.tssrc/svg-shape/internal/format-coordinate.tssrc/svg-shape/internal/format-point.tssrc/svg-shape/internal/get-bar-edges.tssrc/svg-shape/internal/get-screen-matrix.tssrc/svg-shape/internal/lerp-point.tssrc/svg-shape/svg-bar.ts
Source code
ts
import { clamp } from '../math';
import { formatPoint, getBarEdges, lerpPoint } from './internal';
import type { SvgBar } from './svg-bar';
/**
* Creates the `d` of the part of a bar between two ratios, across its whole thickness, in any group: the fill
* level of a bar graph (0 to the value) or a threshold zone. The ratios are clamped to [0, 1].
*
* @param target - The element in whose coordinates the path is written, such as the `<path>` that receives it.
* @param bar - The element giving the area of the bar, and its direction.
* @param fromRatio - The start of the range, from 0 (start of the bar) to 1 (end).
* @param toRatio - The end of the range, in the same way.
* @returns The closed path data.
* @throws {TypeError} When an element is not rendered.
* @example
* const bar = { element: track, direction: 'up' } as const;
* level.setAttribute('d', createSvgBarRangePath(level, bar, 0, ratio(value, max))); // the fill level
* redZone.setAttribute('d', createSvgBarRangePath(redZone, bar, 0.8, 1)); // the top 20 %
*/
export function createSvgBarRangePath(
target: SVGGraphicsElement,
bar: SvgBar,
fromRatio: number,
toRatio: number,
): string {
const [start0, start1, end0, end1] = getBarEdges(bar, target);
const from = clamp(fromRatio);
const to = clamp(toRatio);
return `M ${formatPoint(lerpPoint(start0, end0, from))} L ${formatPoint(lerpPoint(start1, end1, from))} L ${formatPoint(lerpPoint(start1, end1, to))} L ${formatPoint(lerpPoint(start0, end0, to))} Z`;
}Test file
ts
import { createSvgBarRangePath } from './create-svg-bar-range-path';
import { renderSvg } from './testing';
describe(createSvgBarRangePath, () => {
it.for([
['up', 0, 0.25, 'M 0 100 L 20 100 L 20 75 L 0 75 Z'],
['down', 0.8, 1.5, 'M 0 80 L 20 80 L 20 100 L 0 100 Z'],
['right', -1, 0.5, 'M 0 0 L 0 100 L 10 100 L 10 0 Z'],
['left', 0, 0.5, 'M 20 0 L 20 100 L 10 100 L 10 0 Z'],
] as const)('draws a range of a %s bar', ([direction, from, to, expected]) => {
const byId = renderSvg('<rect id="track" width="20" height="100" /><path id="level" />');
expect(createSvgBarRangePath(byId('level'), { element: byId('track'), direction }, from, to)).toBe(expected);
});
it('throws a TypeError for a path that is not rendered', () => {
const byId = renderSvg('<rect id="track" width="20" height="100" />');
const notRendered = { getScreenCTM: (): null => null } as unknown as SVGGraphicsElement;
expect(() => {
createSvgBarRangePath(notRendered, { element: byId('track'), direction: 'up' }, 0, 1);
}).toThrow(TypeError);
});
});Keywords: create, svg, bar, range, path, svg shapes, function