blob: df43c18ee6125fbac111581f78e9ca043067ade3 [file] [log] [blame]
// Copyright (C) 2019 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use size file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import m from 'mithril';
import {Duration} from '../base/time';
import {SqlValue} from '../trace_processor/query_result';
import {Box} from '../widgets/box';
import {Stack, StackAuto, StackFixed} from '../widgets/stack';
import {BarChartData, ColumnDef, Sorting} from './aggregation';
import {ColumnDefinition, DataGridDataSource} from './widgets/data_grid/common';
import {DataGrid, renderCell} from './widgets/data_grid/data_grid';
export interface AggregationPanelAttrs {
readonly dataSource: DataGridDataSource;
readonly sorting: Sorting;
readonly columns: ReadonlyArray<ColumnDef>;
readonly barChartData?: ReadonlyArray<BarChartData>;
}
export class AggregationPanel
implements m.ClassComponent<AggregationPanelAttrs>
{
view({attrs}: m.CVnode<AggregationPanelAttrs>) {
const {dataSource, sorting, columns, barChartData} = attrs;
return m(Stack, {fillHeight: true}, [
barChartData && m(StackFixed, m(Box, this.renderBarChart(barChartData))),
m(StackAuto, this.renderTable(dataSource, sorting, columns)),
]);
}
private renderTable(
dataSource: DataGridDataSource,
sorting: Sorting,
columns: ReadonlyArray<ColumnDef>,
) {
const columnsById = new Map(columns.map((c) => [c.columnId, c]));
return m(DataGrid, {
fillHeight: true,
showResetButton: false,
columns: columns.map((c): ColumnDefinition => {
return {
name: c.columnId,
title: c.title,
aggregation: c.sum ? 'SUM' : undefined,
};
}),
data: dataSource,
initialSorting: sorting,
cellRenderer: (value: SqlValue, columnName: string) => {
const formatHint = columnsById.get(columnName)?.formatHint;
return this.renderCell(value, columnName, formatHint);
},
});
}
private renderBarChart(data: ReadonlyArray<BarChartData>) {
const summedValues = data.reduce((sum, item) => sum + item.value, 0);
return m(
'.pf-aggregation-panel__bar-chart',
data.map((d) => {
const width = (d.value / summedValues) * 100;
return m(
'.pf-aggregation-panel__bar-chart-bar',
{
style: {
background: d.color.base.cssString,
color: d.color.textBase.cssString,
borderColor: d.color.variant.cssString,
width: `${width}%`,
},
},
d.title,
);
}),
);
}
private renderCell(value: SqlValue, colName: string, formatHint?: string) {
if (formatHint === 'DURATION_NS' && typeof value === 'bigint') {
return m('span.pf-data-grid__cell--number', Duration.humanise(value));
} else if (formatHint === 'PERCENT') {
return m('span.pf-data-grid__cell--number', `${value}%`);
} else {
return renderCell(value, colName);
}
}
}