Skip to content

Commit

Permalink
add concept of numericPrecision
Browse files Browse the repository at this point in the history
  • Loading branch information
ericyd committed Jan 9, 2024
1 parent 78362c6 commit b4e97ca
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 1 deletion.
18 changes: 17 additions & 1 deletion lib/components/tag.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ import { pickBy } from '../util.js'
* @property {Array<Tag>} children
*/
export class Tag {
/**
* When < Infinity, will drop decimal values beyond this precision.
* For example, when numericPrecision = 3, 12.34567 will be rounded to 12.345
* @type {number}
*/
numericPrecision = Infinity

/**
* @param {string} tagName
* @param {Record<string, unknown>} attributes
Expand Down Expand Up @@ -89,13 +96,22 @@ export class Tag {
*/
addChild(child) {
child.setVisualAttributes(this.visualAttributes())
// TODO: I don't really like this pattern, but it's quick-n-dirty. There should be a more generalized concept of "inheritable attributes".
// The idea here is if the parent's precision has never been set, then just use the child's precision. Otherwise, use the parent's precision.
child.numericPrecision = this.numericPrecision === Infinity ? child.numericPrecision : this.numericPrecision
this.children.push(child)
return child
}

#formatAttributes() {
return Object.entries(this.attributes)
.map(([key, value]) => `${key}="${value}"`)
.map(([key, value]) => {
if (typeof value === 'number' && this.numericPrecision < Infinity && this.numericPrecision >= 0) {
const rounded = Math.round(value * 10 ** this.numericPrecision) / 10 ** this.numericPrecision
return `${key}="${rounded}"`
}
return `${key}="${value}"`
})
.join(' ')
}

Expand Down
16 changes: 16 additions & 0 deletions lib/components/tag.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ describe('Tag', () => {
const t = new Tag('test', { fill: 'red' })
assert.strictEqual(t.render(), '<test fill="red"></test>')
})

it('should round numeric attributes to the specified precision', () => {
const t = new Tag('test', { x: 1.23456 })
t.numericPrecision = 2
assert.strictEqual(t.render(), '<test x="1.23"></test>')
})
})

describe('setVisualAttributes', () => {
Expand Down Expand Up @@ -58,5 +64,15 @@ describe('Tag', () => {
assert.strictEqual(child.attributes.fill, '#0f0')
assert.strictEqual(child.attributes.stroke, undefined)
})

it('should set numericPrecision', () => {
const t = new Tag('test')
t.numericPrecision = 2
const child = new Tag('test')
assert.strictEqual(child.numericPrecision, Infinity)
// @ts-expect-error this is either a lint error or a TS error. It's a test so it's fine
t.addChild(child)
assert.strictEqual(child.numericPrecision, 2)
})
})
})

0 comments on commit b4e97ca

Please sign in to comment.