Sort histogram bars and tooltip in the order of severity
parent
2742c93bdb
commit
752e70f7ac
|
@ -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,
|
||||
|
|
|
@ -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<Props, State> {
|
|||
colorScale={colorForSeverity}
|
||||
colors={histogramColors}
|
||||
onBarClick={this.handleBarClick}
|
||||
onSortChartBars={this.handleSortHistogramBars}
|
||||
/>
|
||||
)}
|
||||
</AutoSizer>
|
||||
)
|
||||
}
|
||||
|
||||
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,
|
||||
|
|
|
@ -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<Props, State> {
|
|||
}
|
||||
|
||||
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<Props, State> {
|
|||
onHover={this.handleHover}
|
||||
colors={colors}
|
||||
onBarClick={onBarClick}
|
||||
onSortChartBars={onSortChartBars}
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
|
|
|
@ -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<Props>): 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<Props, State> {
|
|||
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
|
||||
|
|
|
@ -36,3 +36,5 @@ export interface HistogramColor {
|
|||
group: string
|
||||
color: string
|
||||
}
|
||||
|
||||
export type SortFn = (a: HistogramDatum, b: HistogramDatum) => number
|
||||
|
|
|
@ -14,8 +14,8 @@ describe('HistogramChart', () => {
|
|||
width: 600,
|
||||
height: 400,
|
||||
colorScale: () => 'blue',
|
||||
onZoom: () => {},
|
||||
colors: [],
|
||||
onSortChartBars: (a, b) => a.value - b.value,
|
||||
}
|
||||
|
||||
const wrapper = mount(<HistogramChart {...props} />)
|
||||
|
@ -30,8 +30,8 @@ describe('HistogramChart', () => {
|
|||
width: 0,
|
||||
height: 0,
|
||||
colorScale: () => 'blue',
|
||||
onZoom: () => {},
|
||||
colors: [],
|
||||
onSortChartBars: (a, b) => a.value - b.value,
|
||||
}
|
||||
|
||||
const wrapper = mount(<HistogramChart {...props} />)
|
||||
|
@ -50,8 +50,8 @@ describe('HistogramChart', () => {
|
|||
width: 600,
|
||||
height: 400,
|
||||
colorScale: () => 'blue',
|
||||
onZoom: () => {},
|
||||
colors: [],
|
||||
onSortChartBars: (a, b) => a.value - b.value,
|
||||
}
|
||||
|
||||
const wrapper = mount(<HistogramChart {...props} />)
|
||||
|
@ -70,8 +70,8 @@ describe('HistogramChart', () => {
|
|||
width: 600,
|
||||
height: 400,
|
||||
colorScale: () => 'blue',
|
||||
onZoom: () => {},
|
||||
colors: [],
|
||||
onSortChartBars: (a, b) => a.value - b.value,
|
||||
}
|
||||
|
||||
const wrapper = mount(<HistogramChart {...props} />)
|
||||
|
|
|
@ -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}
|
||||
>
|
||||
<HistogramChartSkeleton
|
||||
|
@ -141,7 +141,7 @@ exports[`HistogramChart displays a nothing if passed width and height of 0 1`] =
|
|||
data={Array []}
|
||||
dataStatus="Done"
|
||||
height={0}
|
||||
onZoom={[Function]}
|
||||
onSortChartBars={[Function]}
|
||||
width={0}
|
||||
/>
|
||||
`;
|
||||
|
@ -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}
|
||||
>
|
||||
<svg
|
||||
|
@ -341,6 +341,7 @@ exports[`HistogramChart displays the visualization with bars if nonempty data is
|
|||
}
|
||||
height={375}
|
||||
onHover={[Function]}
|
||||
onSortChartBars={[Function]}
|
||||
width={575}
|
||||
xScale={[Function]}
|
||||
yScale={[Function]}
|
||||
|
|
Loading…
Reference in New Issue