diff --git a/ui/src/logs/constants/index.ts b/ui/src/logs/constants/index.ts index b223283d0a..70452245d9 100644 --- a/ui/src/logs/constants/index.ts +++ b/ui/src/logs/constants/index.ts @@ -138,6 +138,17 @@ export enum SeverityLevelOptions { debug = 'debug', } +export const SEVERITY_SORTING_ORDER = { + [SeverityLevelOptions.emerg]: 1, + [SeverityLevelOptions.alert]: 2, + [SeverityLevelOptions.crit]: 3, + [SeverityLevelOptions.err]: 4, + [SeverityLevelOptions.warning]: 5, + [SeverityLevelOptions.notice]: 6, + [SeverityLevelOptions.info]: 7, + [SeverityLevelOptions.debug]: 8, +} + export const DEFAULT_SEVERITY_LEVELS = { [SeverityLevelOptions.emerg]: SeverityColorOptions.ruby, [SeverityLevelOptions.alert]: SeverityColorOptions.fire, diff --git a/ui/src/logs/containers/LogsPage.tsx b/ui/src/logs/containers/LogsPage.tsx index 187a9bb1d1..6ed30609f8 100644 --- a/ui/src/logs/containers/LogsPage.tsx +++ b/ui/src/logs/containers/LogsPage.tsx @@ -36,10 +36,18 @@ import PointInTimeDropDown from 'src/logs/components/PointInTimeDropDown' import {getDeep} from 'src/utils/wrappers' import {colorForSeverity} from 'src/logs/utils/colors' import OverlayTechnology from 'src/reusable_ui/components/overlays/OverlayTechnology' -import {SeverityFormatOptions, SECONDS_TO_MS} from 'src/logs/constants' +import { + SeverityFormatOptions, + SEVERITY_SORTING_ORDER, + SECONDS_TO_MS, +} from 'src/logs/constants' import {Source, Namespace} from 'src/types' -import {HistogramData, HistogramColor} from 'src/types/histogram' +import { + HistogramData, + HistogramColor, + HistogramDatum, +} from 'src/types/histogram' import { Filter, SeverityLevelColor, @@ -327,12 +335,20 @@ class LogsPage extends Component { colorScale={colorForSeverity} colors={histogramColors} onBarClick={this.handleBarClick} + onSortChartBars={this.handleSortHistogramBars} /> )} ) } + private handleSortHistogramBars = ( + a: HistogramDatum, + b: HistogramDatum + ): number => { + return SEVERITY_SORTING_ORDER[b.group] - SEVERITY_SORTING_ORDER[a.group] + } + private get header(): JSX.Element { const { sources, diff --git a/ui/src/shared/components/HistogramChart.tsx b/ui/src/shared/components/HistogramChart.tsx index 22f49459a6..a676a5ec16 100644 --- a/ui/src/shared/components/HistogramChart.tsx +++ b/ui/src/shared/components/HistogramChart.tsx @@ -15,6 +15,7 @@ import { HoverData, ColorScale, HistogramColor, + SortFn, } from 'src/types/histogram' const PADDING_TOP = 0.2 @@ -32,6 +33,7 @@ interface Props { colors: HistogramColor[] colorScale: ColorScale onBarClick?: (time: string) => void + onSortChartBars: SortFn } interface State { @@ -46,7 +48,15 @@ class HistogramChart extends PureComponent { } public render() { - const {width, height, data, colorScale, colors, onBarClick} = this.props + const { + width, + height, + data, + colorScale, + colors, + onBarClick, + onSortChartBars, + } = this.props const {margins} = this if (width === 0 || height === 0) { @@ -99,6 +109,7 @@ class HistogramChart extends PureComponent { onHover={this.handleHover} colors={colors} onBarClick={onBarClick} + onSortChartBars={onSortChartBars} /> diff --git a/ui/src/shared/components/HistogramChartBars.tsx b/ui/src/shared/components/HistogramChartBars.tsx index 95b94d9fba..b3236f0648 100644 --- a/ui/src/shared/components/HistogramChartBars.tsx +++ b/ui/src/shared/components/HistogramChartBars.tsx @@ -12,6 +12,7 @@ import { TooltipAnchor, ColorScale, HistogramColor, + SortFn, } from 'src/types/histogram' const BAR_BORDER_RADIUS = 3 @@ -29,20 +30,24 @@ const getBarWidth = ({data, xScale, width}): number => { return Math.round(width / barCount - BAR_PADDING_SIDES) } -type SortFn = (a: HistogramDatum, b: HistogramDatum) => number - -const getSortFn = (data: HistogramData): SortFn => { - const counts = {} - - for (const d of data) { - if (counts[d.group]) { - counts[d.group] += d.value - } else { - counts[d.group] = d.value - } +interface BarGroup { + key: string + clip: { + x: number + y: number + width: number + height: number } - - return (a, b) => counts[b.group] - counts[a.group] + bars: Array<{ + key: string + group: string + x: number + y: number + width: number + height: number + fill: string + }> + data: HistogramData } const getBarGroups = ({ @@ -53,14 +58,14 @@ const getBarGroups = ({ colorScale, hoverData, colors, + onSortChartBars, }: Partial): BarGroup[] => { const barWidth = getBarWidth({data, xScale, width}) - const sortFn = getSortFn(data) const visibleData = data.filter(d => d.value !== 0) const timeGroups = Object.values(_.groupBy(visibleData, 'time')) for (const timeGroup of timeGroups) { - timeGroup.sort(sortFn) + timeGroup.sort(onSortChartBars) } let hoverDataKeys = [] @@ -143,6 +148,7 @@ interface Props { colors: HistogramColor[] onHover: (h: HoverData) => void onBarClick?: (time: string) => void + onSortChartBars: SortFn } interface State { @@ -229,7 +235,7 @@ class HistogramChartBars extends PureComponent { return } - const {data} = hoverGroup + const data = _.get(hoverGroup, 'data').reverse() const barGroup = e.currentTarget as SVGGElement const boundingRect = barGroup.getBoundingClientRect() const boundingRectHeight = boundingRect.bottom - boundingRect.top diff --git a/ui/src/types/histogram.ts b/ui/src/types/histogram.ts index 5870bdd419..0c3a0b5b2c 100644 --- a/ui/src/types/histogram.ts +++ b/ui/src/types/histogram.ts @@ -36,3 +36,5 @@ export interface HistogramColor { group: string color: string } + +export type SortFn = (a: HistogramDatum, b: HistogramDatum) => number diff --git a/ui/test/shared/components/HistogramChart.test.tsx b/ui/test/shared/components/HistogramChart.test.tsx index 33d53fffc0..d147448598 100644 --- a/ui/test/shared/components/HistogramChart.test.tsx +++ b/ui/test/shared/components/HistogramChart.test.tsx @@ -14,8 +14,8 @@ describe('HistogramChart', () => { width: 600, height: 400, colorScale: () => 'blue', - onZoom: () => {}, colors: [], + onSortChartBars: (a, b) => a.value - b.value, } const wrapper = mount() @@ -30,8 +30,8 @@ describe('HistogramChart', () => { width: 0, height: 0, colorScale: () => 'blue', - onZoom: () => {}, colors: [], + onSortChartBars: (a, b) => a.value - b.value, } const wrapper = mount() @@ -50,8 +50,8 @@ describe('HistogramChart', () => { width: 600, height: 400, colorScale: () => 'blue', - onZoom: () => {}, colors: [], + onSortChartBars: (a, b) => a.value - b.value, } const wrapper = mount() @@ -70,8 +70,8 @@ describe('HistogramChart', () => { width: 600, height: 400, colorScale: () => 'blue', - onZoom: () => {}, colors: [], + onSortChartBars: (a, b) => a.value - b.value, } const wrapper = mount() diff --git a/ui/test/shared/components/__snapshots__/HistogramChart.test.tsx.snap b/ui/test/shared/components/__snapshots__/HistogramChart.test.tsx.snap index d21c11979a..cf884bb94c 100644 --- a/ui/test/shared/components/__snapshots__/HistogramChart.test.tsx.snap +++ b/ui/test/shared/components/__snapshots__/HistogramChart.test.tsx.snap @@ -7,7 +7,7 @@ exports[`HistogramChart displays a HistogramChartSkeleton if empty data is passe data={Array []} dataStatus="Done" height={400} - onZoom={[Function]} + onSortChartBars={[Function]} width={600} > `; @@ -174,7 +174,7 @@ exports[`HistogramChart displays the visualization with bars if nonempty data is } dataStatus="Done" height={400} - onZoom={[Function]} + onSortChartBars={[Function]} width={600} >