-
Notifications
You must be signed in to change notification settings - Fork 34
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: Use correct scale when hovering over stacked line graphs (#153)
* fix: Use correct scale when hovering over stacked line graphs * fix: remove unnecessary options from createSampleTable * fix: use random decimals in Storybook * fix: update tests and improve code readability
- Loading branch information
Showing
7 changed files
with
374 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import {newTable} from '../newTable' | ||
|
||
interface SampleTableOptions { | ||
include_negative?: boolean | ||
all_negative?: boolean | ||
decimalPlaces?: number | ||
maxValue?: number | ||
numberOfRecords?: number | ||
recordsPerLine?: number | ||
} | ||
|
||
const getRandomNumber = ( | ||
max: number, | ||
decimalPlaces: number, | ||
include_negative?: boolean | ||
) => { | ||
const result = include_negative | ||
? Number((Math.random() * (2 * max + 1) - max).toFixed(decimalPlaces)) | ||
: Number((Math.random() * max).toFixed(decimalPlaces)) | ||
|
||
return result === -0 ? 0 : result // eslint-disable-line no-compare-neg-zero | ||
} | ||
|
||
export const COLUMN_KEY = 'cpu' | ||
|
||
export const createSampleTable = (options: SampleTableOptions) => { | ||
const { | ||
include_negative = false, | ||
all_negative = false, | ||
decimalPlaces = 2, | ||
maxValue = 100, | ||
numberOfRecords = 20, | ||
recordsPerLine = 5, | ||
} = options | ||
|
||
const now = Date.now() | ||
const TIME_COL = [] | ||
const VALUE_COL = [] | ||
const CPU_COL = [] | ||
|
||
for (let i = 0; i < numberOfRecords; i += 1) { | ||
let num = getRandomNumber(maxValue, decimalPlaces) | ||
if (include_negative) { | ||
num = all_negative | ||
? Math.abs(num) * -1 | ||
: getRandomNumber(maxValue, decimalPlaces, true) | ||
} | ||
VALUE_COL.push(num) | ||
CPU_COL.push(`${COLUMN_KEY}${Math.floor(i / recordsPerLine)}`) | ||
TIME_COL.push(now + (i % recordsPerLine) * 1000 * 60) | ||
} | ||
return newTable(numberOfRecords) | ||
.addColumn('_time', 'time', TIME_COL) | ||
.addColumn('_value', 'number', VALUE_COL) | ||
.addColumn('cpu', 'string', CPU_COL) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,227 @@ | ||
import {getPointsTooltipData} from './tooltip' | ||
import {NINETEEN_EIGHTY_FOUR} from '../constants/colorSchemes' | ||
import { | ||
FILL, | ||
STACKED_LINE_CUMULATIVE, | ||
LINE_COUNT, | ||
} from '../constants/columnKeys' | ||
import {getNominalColorScale, createGroupIDColumn} from '../transforms' | ||
import {lineTransform} from '../transforms/line' | ||
import {createSampleTable, COLUMN_KEY} from './fixtures/tooltip' | ||
|
||
describe('getPointsTooltipData', () => { | ||
let sampleTable | ||
const xColKey = '_time' | ||
const yColKey = '_value' | ||
const columnFormatter = () => x => String(x) | ||
let lineSpec | ||
let fillScale | ||
let hoveredValues | ||
let result | ||
let cumulativeValueColumn | ||
|
||
const numberOfRecords = 1000 | ||
const recordsPerLine = 10 | ||
let startingIndex | ||
|
||
const setUp = options => { | ||
const {hoveredRowIndices, position, ...tableOptions} = options | ||
sampleTable = createSampleTable(tableOptions) | ||
lineSpec = lineTransform( | ||
sampleTable, | ||
xColKey, | ||
yColKey, | ||
[COLUMN_KEY], | ||
NINETEEN_EIGHTY_FOUR, | ||
position | ||
) | ||
|
||
const [fillColumn, fillColumnMap] = createGroupIDColumn(sampleTable, [ | ||
COLUMN_KEY, | ||
]) | ||
fillScale = getNominalColorScale(fillColumnMap, NINETEEN_EIGHTY_FOUR) | ||
sampleTable = sampleTable.addColumn(FILL, 'number', fillColumn) | ||
|
||
const fillColumnFromSampleTable = sampleTable.getColumn(FILL, 'number') | ||
fillColumn.forEach((item, index) => | ||
expect(item).toEqual(fillColumnFromSampleTable[index]) | ||
) | ||
|
||
const allValues = sampleTable.getColumn('_value') | ||
hoveredValues = hoveredRowIndices.map(i => allValues[i]) | ||
} | ||
|
||
describe('tooltip for overlaid line graph', () => { | ||
const position = 'overlaid' | ||
|
||
it('should have a value column that is not necessarily sorted', () => { | ||
startingIndex = 3 | ||
const hoveredRowIndices = [] | ||
for (let i = startingIndex; i < numberOfRecords; i += recordsPerLine) { | ||
hoveredRowIndices.push(i) | ||
} | ||
setUp({ | ||
include_negative: true, | ||
all_negative: false, | ||
numberOfRecords, | ||
recordsPerLine, | ||
hoveredRowIndices, | ||
position, | ||
}) | ||
result = getPointsTooltipData( | ||
hoveredRowIndices, | ||
sampleTable, | ||
xColKey, | ||
yColKey, | ||
FILL, | ||
columnFormatter, | ||
[COLUMN_KEY], | ||
fillScale, | ||
'overlaid', | ||
lineSpec.lineData | ||
) | ||
const singleValueColumn = result.find(column => column.key === yColKey) | ||
expect(singleValueColumn.values.map(value => Number(value))).toEqual( | ||
hoveredValues | ||
) | ||
}) | ||
}) | ||
|
||
describe('tooltip for stacked line graph', () => { | ||
const position = 'stacked' | ||
|
||
afterEach(() => { | ||
const totalColumns = result.length | ||
const colorsCounter = {} | ||
|
||
result.forEach(column => { | ||
const {colors} = column | ||
colors.forEach(color => { | ||
if (!colorsCounter[color]) { | ||
colorsCounter[color] = 0 | ||
} | ||
colorsCounter[color] += 1 | ||
}) | ||
}) | ||
expect(Object.keys(colorsCounter).length).toEqual( | ||
numberOfRecords / recordsPerLine | ||
) | ||
expect( | ||
Object.values(colorsCounter).every( | ||
colorCount => colorCount === totalColumns | ||
) | ||
).toEqual(true) | ||
|
||
cumulativeValueColumn = result.find( | ||
column => column.key === STACKED_LINE_CUMULATIVE | ||
) | ||
expect(cumulativeValueColumn).toBeTruthy() | ||
expect( | ||
cumulativeValueColumn.values.every((value, index, arr) => { | ||
if (index === 0) { | ||
return true | ||
} | ||
return Number(arr[index - 1]) >= Number(value) | ||
}) | ||
).toEqual(true) | ||
|
||
expect(result.find(column => column.key === LINE_COUNT)).toBeTruthy() | ||
}) | ||
|
||
it('should create proper columns when all values are positive numbers', () => { | ||
startingIndex = 0 | ||
const hoveredRowIndices = [] | ||
for (let i = startingIndex; i < numberOfRecords; i += recordsPerLine) { | ||
hoveredRowIndices.push(i) | ||
} | ||
setUp({ | ||
include_negative: false, | ||
all_negative: false, | ||
numberOfRecords, | ||
recordsPerLine, | ||
hoveredRowIndices, | ||
position, | ||
}) | ||
result = getPointsTooltipData( | ||
hoveredRowIndices, | ||
sampleTable, | ||
xColKey, | ||
yColKey, | ||
FILL, | ||
columnFormatter, | ||
[COLUMN_KEY], | ||
fillScale, | ||
'stacked', | ||
lineSpec.lineData | ||
) | ||
const singleValueColumn = result.find(column => column.key === yColKey) | ||
expect(singleValueColumn).toBeTruthy() | ||
expect( | ||
singleValueColumn.values.map(value => Number(value)).reverse() | ||
).toEqual(hoveredValues) | ||
}) | ||
|
||
it('should create proper columns when all values are negative numbers', () => { | ||
startingIndex = 1 | ||
const hoveredRowIndices = [] | ||
for (let i = startingIndex; i < numberOfRecords; i += recordsPerLine) { | ||
hoveredRowIndices.push(i) | ||
} | ||
setUp({ | ||
include_negative: true, | ||
all_negative: true, | ||
numberOfRecords, | ||
recordsPerLine, | ||
hoveredRowIndices, | ||
position, | ||
}) | ||
result = getPointsTooltipData( | ||
hoveredRowIndices, | ||
sampleTable, | ||
xColKey, | ||
yColKey, | ||
FILL, | ||
columnFormatter, | ||
[COLUMN_KEY], | ||
fillScale, | ||
'stacked', | ||
lineSpec.lineData | ||
) | ||
const singleValueColumn = result.find(column => column.key === yColKey) | ||
|
||
expect(singleValueColumn).toBeTruthy() | ||
expect(singleValueColumn.values.map(value => Number(value))).toEqual( | ||
hoveredValues | ||
) | ||
}) | ||
|
||
it('should create proper columns when values can be positive or negative', () => { | ||
startingIndex = 2 | ||
const hoveredRowIndices = [] | ||
for (let i = startingIndex; i < numberOfRecords; i += recordsPerLine) { | ||
hoveredRowIndices.push(i) | ||
} | ||
setUp({ | ||
include_negative: true, | ||
all_negative: false, | ||
numberOfRecords, | ||
recordsPerLine, | ||
hoveredRowIndices, | ||
position, | ||
}) | ||
result = getPointsTooltipData( | ||
hoveredRowIndices, | ||
sampleTable, | ||
xColKey, | ||
yColKey, | ||
FILL, | ||
columnFormatter, | ||
[COLUMN_KEY], | ||
fillScale, | ||
'stacked', | ||
lineSpec.lineData | ||
) | ||
expect(result.find(column => column.key === yColKey)).toBeTruthy() | ||
}) | ||
}) | ||
}) |
Oops, something went wrong.