/* @jest-environment jsdom */ import {SizedConfig, LineLayerConfig, RectLayerSpec} from '../types' import {PlotEnv} from './PlotEnv' import {newTable} from './newTable' import {COUNT} from '../constants/columnKeys' import * as lineTransformModule from '../transforms/line' import * as histogramTransformModule from '../transforms/histogram' describe('PlotEnv', () => { describe('config updates and memoization', () => { let histogramTransformSpy let lineTransformSpy beforeEach(() => { histogramTransformSpy = jest.spyOn( histogramTransformModule, 'histogramTransform' ) lineTransformSpy = jest.spyOn(lineTransformModule, 'lineTransform') }) afterEach(() => { histogramTransformSpy.mockRestore() lineTransformSpy.mockRestore() }) it('updates xScale when xDomain is updated without resetting domains', () => { const plotEnv = new PlotEnv() const aData = [10, 11, 12, 13, 14, 15, 16, 17, 18, 19] const table = newTable(10).addColumn('a', 'long', 'number', aData) const config: SizedConfig = { table, width: 1000, height: 500, xDomain: [10, 19], onSetXDomain: () => {}, onResetXDomain: () => {}, layers: [{type: 'histogram', x: 'a'}], } plotEnv.config = config const rangePadding = plotEnv['rangePadding'] expect(plotEnv.xScale(10)).toEqual(rangePadding) expect(plotEnv.xScale(19)).toEqual( 1000 - plotEnv.margins.left - plotEnv.margins.right - rangePadding * 2 ) plotEnv.config = {...config, xDomain: [10, 28]} expect(plotEnv.xScale(10)).toEqual(rangePadding) expect(plotEnv.xScale(28)).toEqual( 1000 - plotEnv.margins.left - plotEnv.margins.right - rangePadding * 2 ) }) it('updates xScale when xDomain is updated and domains are reset', () => { const plotEnv = new PlotEnv() const aData = [10, 11, 12, 13, 14, 15, 16, 17, 18, 19] const table = newTable(10).addColumn('a', 'long', 'number', aData) const config: SizedConfig = { table, width: 1000, height: 500, xDomain: [10, 19], includeXDomainZoom: true, onSetXDomain: () => {}, onResetXDomain: () => {}, layers: [{type: 'histogram', x: 'a'}], } plotEnv.config = config const rangePadding = plotEnv['rangePadding'] expect(plotEnv.xScale(10)).toEqual(rangePadding) expect(plotEnv.xScale(19)).toEqual( 1000 - plotEnv.margins.left - plotEnv.margins.right - rangePadding * 2 ) plotEnv.config = {...config, xDomain: [10, 28]} plotEnv.resetDomains() expect(plotEnv.xScale(10)).toEqual(rangePadding) expect(plotEnv.xScale(28)).toEqual( 1000 - plotEnv.margins.left - plotEnv.margins.right - rangePadding * 2 ) }) it('runs bin stat when x domain changes', () => { const plotEnv = new PlotEnv() const aData = [10, 11, 12, 13, 14, 15, 16, 17, 18, 19] const table = newTable(10).addColumn('a', 'long', 'number', aData) const config: SizedConfig = { table, width: 1000, height: 500, xDomain: [10, 19], onSetXDomain: () => {}, onResetXDomain: () => {}, layers: [{type: 'histogram', x: 'a', binCount: 10}], } plotEnv.config = config const getFirstBinCount = () => (plotEnv.getSpec(0) as RectLayerSpec).table.getColumn( COUNT, 'number' )[0] expect(getFirstBinCount()).toEqual(1) plotEnv.config = {...config, xDomain: [10, 28]} expect(getFirstBinCount()).toEqual(2) expect(histogramTransformSpy).toHaveBeenCalledTimes(2) }) it('runs bin stat when histogram layer x mapping changes', () => { const plotEnv = new PlotEnv() const aData = [10, 11, 12, 13, 14, 15, 16, 17, 18, 19] const bData = [10, 10, 10, 10, 10, 10, 10, 10, 10, 19] const table = newTable(10) .addColumn('a', 'long', 'number', aData) .addColumn('b', 'long', 'number', bData) const config: SizedConfig = { table, width: 1000, height: 500, layers: [{type: 'histogram', x: 'a', binCount: 10}], } plotEnv.config = config const getFirstBinCount = () => (plotEnv.getSpec(0) as RectLayerSpec).table.getColumn( COUNT, 'number' )[0] expect(getFirstBinCount()).toEqual(1) plotEnv.config = { ...config, layers: [{type: 'histogram', x: 'b', binCount: 10}], } expect(getFirstBinCount()).toEqual(9) expect(histogramTransformSpy).toHaveBeenCalledTimes(2) }) it('does not run bin stat when histogram fillOpacity change', () => { const plotEnv = new PlotEnv() const aData = [10, 11, 12, 13, 14, 15, 16, 17, 18, 19] const table = newTable(10).addColumn('a', 'long', 'number', aData) const config: SizedConfig = { table, width: 1000, height: 500, layers: [{type: 'histogram', x: 'a', binCount: 10, fillOpacity: 1}], } plotEnv.config = config expect(histogramTransformSpy).toHaveBeenCalledTimes(0) plotEnv.getSpec(0) expect(histogramTransformSpy).toHaveBeenCalledTimes(1) plotEnv.config = { ...config, layers: [{type: 'histogram', x: 'a', binCount: 10, fillOpacity: 0.5}], } plotEnv.getSpec(0) expect(histogramTransformSpy).toHaveBeenCalledTimes(1) }) it('updating line interpolation should not reset the x domain', () => { const plotEnv = new PlotEnv() const aData = [10, 11, 12, 13, 14, 15, 16, 17, 18, 19] const bData = [10, 10, 10, 10, 10, 10, 10, 10, 10, 19] const table = newTable(10) .addColumn('a', 'long', 'number', aData) .addColumn('b', 'long', 'number', bData) const config: SizedConfig = { table, width: 1000, height: 500, layers: [{type: 'line', x: 'b', y: 'a', interpolation: 'linear'}], } plotEnv.config = config plotEnv.xDomain = [12, 15] expect(plotEnv.xDomain).toEqual([12, 15]) plotEnv.config = { ...config, layers: [ {...config.layers[0], interpolation: 'monotoneX'} as LineLayerConfig, ], } expect(plotEnv.xDomain).toEqual([12, 15]) }) it('does not run line stat when x domain changes', () => { const plotEnv = new PlotEnv() const aData = [10, 11, 12, 13, 14, 15, 16, 17, 18, 19] const bData = [10, 10, 10, 10, 10, 10, 10, 10, 10, 19] const table = newTable(10) .addColumn('a', 'long', 'number', aData) .addColumn('b', 'long', 'number', bData) const config: SizedConfig = { table, width: 1000, height: 500, xDomain: [10, 19], onSetXDomain: () => {}, onResetXDomain: () => {}, layers: [{type: 'line', x: 'b', y: 'a'}], } plotEnv.config = config expect(lineTransformSpy).toHaveBeenCalledTimes(0) plotEnv.getSpec(0) expect(lineTransformSpy).toHaveBeenCalledTimes(1) plotEnv.config = {...config, xDomain: [12, 14]} plotEnv.getSpec(0) expect(lineTransformSpy).toHaveBeenCalledTimes(1) }) it('resets uncontrolled domain state when x mapping changes', () => { const plotEnv = new PlotEnv() const aData = [10, 11, 12, 13, 14, 15, 16, 17, 18, 19] const bData = [10, 10, 10, 10, 10, 10, 10, 10, 10, 19] const table = newTable(10) .addColumn('a', 'long', 'number', aData) .addColumn('b', 'long', 'number', bData) const config: SizedConfig = { table, width: 1000, height: 500, layers: [{type: 'line', x: 'b', y: 'a'}], } plotEnv.config = config expect(plotEnv.xDomain).toEqual([10, 19]) plotEnv.xDomain = [12, 16] expect(plotEnv.xDomain).toEqual([12, 16]) plotEnv.config = { ...config, layers: [{type: 'line', x: 'a', y: 'b'}], // Swap mappings } expect(plotEnv.xDomain).toEqual([10, 19]) }) }) })