Skip to content

Commit

Permalink
Use median in histogram
Browse files Browse the repository at this point in the history
  • Loading branch information
ehmicky committed Sep 5, 2021
1 parent 59f73e4 commit 5654953
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 57 deletions.
2 changes: 1 addition & 1 deletion src/report/reporters/histogram/abscissa.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { separatorColor } from '../../utils/colors.js'
import { TICK_MIDDLE, HORIZONTAL_LINE } from './characters.js'

// Retrieve the horizontal line and the abscissa below the main content.
// Includes the tick above the mean positions and their labels.
// Includes the tick above the median and its label.
export const getAbscissa = function (width, positions) {
const bottomLine = getBottomLine(width, positions)
const labels = getLabels(width, positions)
Expand Down
23 changes: 19 additions & 4 deletions src/report/reporters/histogram/content.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { getAbscissa } from './abscissa.js'
import { getMeanPositions } from './positions.js'
import { getHistogramRows } from './rows.js'

// Retrieve histogram main content
Expand All @@ -10,13 +9,16 @@ export const getContent = function ({
width,
mini,
}) {
const { positions, meanIndex, meanMaxWidth } = getMeanPositions(stats, width)
const { positions, medianIndex, medianMaxWidth } = getMedianPositions(
stats,
width,
)
const rows = getHistogramRows({
histogram,
width,
height,
meanIndex,
meanMaxWidth,
medianIndex,
medianMaxWidth,
})

if (mini) {
Expand All @@ -27,3 +29,16 @@ export const getContent = function ({
return `${rows}
${abscissa}`
}

// Compute positions of the median tick.
// When `histogram` has a single item, it is in the first bucket.
// Also compute the maximum width between the median and either the start or end
// Also computes `medianIndex|medianMaxWidth` used for the color gradient.
const getMedianPositions = function ({ median, min, max }, width) {
const medianPercentage =
max.raw === min.raw ? 0 : (median.raw - min.raw) / (max.raw - min.raw)
const medianIndex = Math.round((width - 1) * medianPercentage)
const positions = [{ ...median, index: medianIndex }]
const medianMaxWidth = Math.max(medianIndex, width - 1 - medianIndex)
return { positions, medianIndex, medianMaxWidth }
}
14 changes: 6 additions & 8 deletions src/report/reporters/histogram/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,17 @@ const getContentWidth = function (combinations, mini, screenWidth) {

const serializeHistogram = function ({
combination,
combination: { stats },
combination: {
stats,
stats: { median },
},
width,
height,
mini,
}) {
const titleBlock = getTitleBlock(combination, height, mini)

if (hasLowLoops(stats)) {
if (median === undefined) {
return titleBlock
}

Expand All @@ -57,9 +60,4 @@ const serializeHistogram = function ({
return concatBlocks([titleBlock, minBlock, content, maxBlock])
}

// When using `showPrecision` and not enough loops are available.
const hasLowLoops = function ({ mean, meanMin }) {
return mean === undefined && meanMin === undefined
}

export const histogram = { reportTerminal }
export const histogram = { reportTerminal, capabilities: { debugStats: true } }
33 changes: 0 additions & 33 deletions src/report/reporters/histogram/positions.js

This file was deleted.

28 changes: 17 additions & 11 deletions src/report/reporters/histogram/rows.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ export const getHistogramRows = function ({
histogram,
width,
height,
meanIndex,
meanMaxWidth,
medianIndex,
medianMaxWidth,
}) {
const frequencies = getFrequencies(histogram, width)
const columns = getHistogramColumns({
frequencies,
meanIndex,
meanMaxWidth,
medianIndex,
medianMaxWidth,
height,
})
return Array.from({ length: height }, (_, index) =>
Expand All @@ -30,13 +30,17 @@ export const getHistogramRows = function ({
// Computes the terminal height of each column for reporting.
const getHistogramColumns = function ({
frequencies,
meanIndex,
meanMaxWidth,
medianIndex,
medianMaxWidth,
height,
}) {
const maxHeight = getMaxHeight(frequencies, height)
return frequencies.map(
getHistogramColumn.bind(undefined, { maxHeight, meanIndex, meanMaxWidth }),
getHistogramColumn.bind(undefined, {
maxHeight,
medianIndex,
medianMaxWidth,
}),
)
}

Expand All @@ -49,7 +53,7 @@ const getMaxHeight = function (frequencies, height) {
// `heightLevel` is the integer part (full character) and `charIndex` is the
// fractional part (final character on top of column).
const getHistogramColumn = function (
{ maxHeight, meanIndex, meanMaxWidth },
{ maxHeight, medianIndex, medianMaxWidth },
frequency,
columnIndex,
) {
Expand All @@ -58,14 +62,16 @@ const getHistogramColumn = function (
const charIndex = Math.ceil(
(columnHeight - heightLevel) * (HISTOGRAM_CHARS.length - 1),
)
const color = getColumnColor(columnIndex, meanIndex, meanMaxWidth)
const color = getColumnColor(columnIndex, medianIndex, medianMaxWidth)
return { heightLevel, charIndex, color }
}

// Computes the column gradient color.
const getColumnColor = function (columnIndex, meanIndex, meanMaxWidth) {
const getColumnColor = function (columnIndex, medianIndex, medianMaxWidth) {
const colorPercentage =
meanMaxWidth === 0 ? 0 : Math.abs(meanIndex - columnIndex) / meanMaxWidth
medianMaxWidth === 0
? 0
: Math.abs(medianIndex - columnIndex) / medianMaxWidth
return graphGradientColor(colorPercentage)
}

Expand Down

0 comments on commit 5654953

Please sign in to comment.