mirror of
https://github.com/tabler/tabler.git
synced 2026-10-12 13:17:00 +04:00
157 lines
6.3 KiB
TypeScript
157 lines
6.3 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
import { chartStyle, chartConfig, type ChartData } from './chart-script'
|
|
|
|
describe('chartStyle', () => {
|
|
it('emits an id-scoped color custom property per serie', () => {
|
|
const data: ChartData = {
|
|
series: [
|
|
{ name: 'A', data: [1, 2], color: 'red' },
|
|
{ name: 'B', data: [3] },
|
|
],
|
|
color: 'green',
|
|
}
|
|
const css = chartStyle({ id: 'demo', data })
|
|
expect(css).toContain('--chart-demo-color-0: color-mix(in srgb, transparent, var(--tblr-red) 100%)')
|
|
expect(css).toContain('--chart-demo-color-1: color-mix(in srgb, transparent, var(--tblr-green) 100%)')
|
|
expect(css.startsWith('<style>')).toBe(true)
|
|
})
|
|
|
|
it('fills an area with a wash of each serie color', () => {
|
|
const css = chartStyle({
|
|
id: 'a',
|
|
data: {
|
|
type: 'area',
|
|
series: [
|
|
{ name: 'A', data: [1], color: 'green' },
|
|
{ name: 'B', data: [2], color: 'pink' },
|
|
],
|
|
},
|
|
})
|
|
expect(css).toContain('--chart-a-fill-0: color-mix(in srgb, transparent, var(--tblr-green) 16%)')
|
|
expect(css).toContain('--chart-a-fill-1: color-mix(in srgb, transparent, var(--tblr-pink) 16%)')
|
|
})
|
|
|
|
it('falls back to the public palette when a serie names no color', () => {
|
|
const css = chartStyle({
|
|
id: 'p',
|
|
data: {
|
|
series: [
|
|
{ name: 'A', data: [1] },
|
|
{ name: 'B', data: [2] },
|
|
{ name: 'C', data: [3] },
|
|
],
|
|
},
|
|
})
|
|
expect(css).toContain('--chart-p-color-0: color-mix(in srgb, transparent, var(--tblr-chart-1) 100%)')
|
|
expect(css).toContain('--chart-p-color-1: color-mix(in srgb, transparent, var(--tblr-chart-2) 100%)')
|
|
expect(css).toContain('--chart-p-color-2: color-mix(in srgb, transparent, var(--tblr-chart-3) 100%)')
|
|
})
|
|
|
|
it('adds box variables for box plots', () => {
|
|
const css = chartStyle({ id: 'b', data: { type: 'boxPlot', series: [{ 'name': 'A', 'color': 'green', 'box-data': [{ x: 'Jan', y: [1, 2, 3, 4, 5] }] }] } })
|
|
expect(css).toContain('--chart-b-box-upper: color-mix(in srgb, transparent, var(--tblr-green) 100%)')
|
|
expect(css).toContain('--chart-b-box-lower: color-mix(in srgb, transparent, var(--tblr-green) 40%)')
|
|
})
|
|
})
|
|
|
|
describe('chartConfig', () => {
|
|
it('builds a config with the chart type and height in px', () => {
|
|
const { config } = chartConfig({ id: 'demo', data: { type: 'line', series: [] }, height: 10 })
|
|
expect(config.chart).toMatchObject({ type: 'line', height: 160 })
|
|
})
|
|
|
|
it('renders a polar area from plain numbers and labels, like a pie', () => {
|
|
const { config } = chartConfig({
|
|
id: 'demo',
|
|
data: {
|
|
type: 'polarArea',
|
|
series: [
|
|
{ name: 'A', data: 12 },
|
|
{ name: 'B', data: 8 },
|
|
],
|
|
},
|
|
height: 10,
|
|
})
|
|
expect(config.series).toEqual([12, 8])
|
|
expect(config.labels).toEqual(['A', 'B'])
|
|
expect(config.yaxis).toBeUndefined()
|
|
})
|
|
|
|
it('turns a bar chart into a funnel', () => {
|
|
const { config } = chartConfig({ id: 'demo', data: { type: 'bar', funnel: true, series: [{ name: 'Pipeline', data: [3, 2, 1] }] }, height: 10 })
|
|
expect(config.plotOptions).toMatchObject({ bar: { isFunnel: true, horizontal: true, distributed: true } })
|
|
})
|
|
|
|
it('passes the { x, y } points of the newer chart types straight through', () => {
|
|
const points = [{ x: 'Research', y: [1, 2] }]
|
|
const { config } = chartConfig({ id: 'demo', data: { type: 'rangeBar', series: [{ 'name': 'Roadmap', 'range-data': points }] }, height: 10 })
|
|
expect(config.series).toEqual([{ name: 'Roadmap', data: points }])
|
|
})
|
|
|
|
it('builds threshold and marker lines from the annotation shorthand', () => {
|
|
const { config } = chartConfig({
|
|
id: 'demo',
|
|
data: { 'series': [], 'annotations-y': [{ value: 99.9, label: 'SLA 99.9%' }], 'annotations-x': [{ value: 'Apr', color: 'azure' }] },
|
|
height: 10,
|
|
})
|
|
expect(config.annotations).toMatchObject({
|
|
yaxis: [{ y: 99.9, borderColor: 'var(--tblr-red)', label: { text: 'SLA 99.9%' } }],
|
|
xaxis: [{ x: 'Apr', borderColor: 'var(--tblr-azure)' }],
|
|
})
|
|
})
|
|
|
|
it('puts the second y axis on the right and binds each axis to its serie', () => {
|
|
const { config } = chartConfig({
|
|
id: 'demo',
|
|
data: {
|
|
'series': [
|
|
{ name: 'Revenue', data: [1] },
|
|
{ name: 'Orders', data: [2] },
|
|
],
|
|
'y-axes': [{ 'series-name': 'Revenue' }, { 'series-name': 'Orders', 'opposite': true }],
|
|
},
|
|
height: 10,
|
|
})
|
|
expect(config.yaxis).toMatchObject([
|
|
{ seriesName: 'Revenue', opposite: undefined },
|
|
{ seriesName: 'Orders', opposite: true },
|
|
])
|
|
})
|
|
|
|
it('points a brush chart at its target and names every chart', () => {
|
|
const { config } = chartConfig({
|
|
id: 'traffic-brush',
|
|
data: { 'series': [], 'brush-target': 'traffic-zoom', 'selection-from': 1, 'selection-to': 2 },
|
|
height: 10,
|
|
})
|
|
expect(config.chart).toMatchObject({
|
|
id: 'traffic-brush',
|
|
brush: { enabled: true, target: 'traffic-zoom' },
|
|
selection: { enabled: true, xaxis: { min: 1, max: 2 } },
|
|
})
|
|
})
|
|
|
|
it('returns the x-formatter as a separate expression instead of embedding it', () => {
|
|
const { config, xFormatterExpr } = chartConfig({ id: 'demo', data: { 'series': [], 'x-formatter': 'val + "K"' }, height: 10 })
|
|
expect(xFormatterExpr).toBe('val + "K"')
|
|
expect(JSON.stringify(config)).not.toContain('val + "K"')
|
|
})
|
|
|
|
it('returns the y-formatter as a separate expression instead of embedding it', () => {
|
|
const { config, yFormatterExpr } = chartConfig({ id: 'demo', data: { 'series': [], 'y-formatter': 'val.toLocaleString("en-US")' }, height: 10 })
|
|
expect(yFormatterExpr).toBe('val.toLocaleString("en-US")')
|
|
expect(JSON.stringify(config)).not.toContain('toLocaleString')
|
|
})
|
|
|
|
it('uses the ApexCharts 7 legend marker options', () => {
|
|
const { config } = chartConfig({ id: 'demo', data: { series: [], legend: true }, height: 10 })
|
|
expect(config.legend).toMatchObject({ markers: { size: 5, strokeWidth: 0, shape: 'circle' } })
|
|
})
|
|
|
|
it('hides line points, including the hover dot, with hide-points', () => {
|
|
const { config } = chartConfig({ id: 'demo', data: { 'series': [], 'hide-points': true }, height: 10 })
|
|
expect(config.markers).toEqual({ size: 0, hover: { sizeOffset: 0 } })
|
|
expect(config).not.toHaveProperty('point')
|
|
})
|
|
})
|