// A DrawingML chart part drawn as an SVG picture (import/chart.ts): series values, // the file's own axis bounds, and the 1..n categories a chart without any gets. import { describe, it, expect } from 'vitest'; import { chartDataUrl, odfChartDataUrl } from '../../src/lib/import/chart'; const C = 'xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart"'; const A = 'xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"'; const points = (vals: number[]) => `` + vals.map((v, i) => `${v}`).join('') + ''; const chartXml = (plot: string, opts: { max?: string; cats?: string[] } = {}) => `` + `Phase Std` + `<${plot}>` + (opts.cats ? `` + opts.cats.map((t, i) => `${t}`).join('') + '' : '') + `${points([1, 2, 3])}` + `interferogram` + `${opts.max ? `` : ''}` + `` + ``; const svgOf = (xml: string, accents: string[] = []) => { const url = chartDataUrl(xml, 400, 300, accents); expect(url?.startsWith('data:image/svg+xml')).toBe(true); return decodeURIComponent(url!.replace(/^data:image\/svg\+xml;charset=utf-8,/, '')); }; describe('a chart part', () => { it('draws its bars, title, axis title and the theme accent it names', () => { const svg = svgOf(chartXml('c:barChart'), ['#111111', '#22AA33']); expect(svg).toContain('Phase Std'); expect(svg).toContain('interferogram'); expect(svg).toContain('#22AA33'); expect((svg.match(/ { expect(svgOf(chartXml('c:barChart', { max: '10' }))).toContain('>10<'); expect(svgOf(chartXml('c:barChart'))).not.toContain('>10<'); }); it('numbers the categories 1..n when the file names none, and keeps the ones it does', () => { const plain = svgOf(chartXml('c:barChart')); expect(plain).toContain('>1<'); expect(plain).toContain('>3<'); expect(svgOf(chartXml('c:barChart', { cats: ['Mo', 'Di', 'Mi'] }))).toContain('>Di<'); }); it('draws a line and a pie chart, and declines a plot it cannot draw', () => { expect(svgOf(chartXml('c:lineChart'))).toContain(' plus the local table that holds its numbers ---- const NSDECL = 'xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0"' + ' xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0"' + ' xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"' + ' xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0"' + ' xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0"' + ' xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0"'; const row = (cells: string[]) => `${cells.map((c) => c).join('')}`; const strCell = (s: string) => `${s}`; const numCell = (v: number) => `${v}`; const odfChart = (cls: string) => `` + `` + `` + `` + `Phase Std` + `` + `interferogram` + `` + `` + `` + `` + `` + row([strCell(''), strCell('Series1')]) + row([strCell('Mo'), numCell(1)]) + row([strCell('Di'), numCell(2)]) + row([strCell('Mi'), numCell(3)]) + ``; const odfSvg = (cls: string) => { const doc = new DOMParser().parseFromString(odfChart(cls), 'application/xml'); const url = odfChartDataUrl(doc, 400, 300); expect(url?.startsWith('data:image/svg+xml')).toBe(true); return decodeURIComponent(url!.replace(/^data:image\/svg\+xml;charset=utf-8,/, '')); }; describe('an ODF chart object', () => { it('draws its series from the local table, in the file’s own colour', () => { const svg = odfSvg('chart:bar'); expect(svg).toContain('Phase Std'); expect(svg).toContain('interferogram'); expect(svg).toContain('#22AA33'); expect(svg).toContain('>Di<'); expect((svg.match(/ { expect(odfSvg('chart:bar')).toContain('>4<'); const doc = new DOMParser().parseFromString(odfChart('chart:surface'), 'application/xml'); expect(odfChartDataUrl(doc, 400, 300)).toBeNull(); }); });