kibana/x-pack/plugins/lens/public/metric_visualization/expression.tsx
2020-09-29 19:00:29 +02:00

135 lines
3.5 KiB
TypeScript

/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import './expression.scss';
import React from 'react';
import ReactDOM from 'react-dom';
import {
ExpressionFunctionDefinition,
ExpressionRenderDefinition,
IInterpreterRenderHandlers,
} from '../../../../../src/plugins/expressions/public';
import { MetricConfig } from './types';
import { FormatFactory, LensMultiTable } from '../types';
import { AutoScale } from './auto_scale';
import { VisualizationContainer } from '../visualization_container';
export interface MetricChartProps {
data: LensMultiTable;
args: MetricConfig;
}
export interface MetricRender {
type: 'render';
as: 'lens_metric_chart_renderer';
value: MetricChartProps;
}
export const metricChart: ExpressionFunctionDefinition<
'lens_metric_chart',
LensMultiTable,
Omit<MetricConfig, 'layerId'>,
MetricRender
> = {
name: 'lens_metric_chart',
type: 'render',
help: 'A metric chart',
args: {
title: {
types: ['string'],
help: 'The chart title.',
},
accessor: {
types: ['string'],
help: 'The column whose value is being displayed',
},
mode: {
types: ['string'],
options: ['reduced', 'full'],
default: 'full',
help:
'The display mode of the chart - reduced will only show the metric itself without min size',
},
},
inputTypes: ['lens_multitable'],
fn(data, args) {
return {
type: 'render',
as: 'lens_metric_chart_renderer',
value: {
data,
args,
},
} as MetricRender;
},
};
export const getMetricChartRenderer = (
formatFactory: Promise<FormatFactory>
): ExpressionRenderDefinition<MetricChartProps> => ({
name: 'lens_metric_chart_renderer',
displayName: 'Metric chart',
help: 'Metric chart renderer',
validate: () => undefined,
reuseDomNode: true,
render: async (
domNode: Element,
config: MetricChartProps,
handlers: IInterpreterRenderHandlers
) => {
const resolvedFormatFactory = await formatFactory;
ReactDOM.render(
<MetricChart {...config} formatFactory={resolvedFormatFactory} />,
domNode,
() => {
handlers.done();
}
);
handlers.onDestroy(() => ReactDOM.unmountComponentAtNode(domNode));
},
});
export function MetricChart({
data,
args,
formatFactory,
}: MetricChartProps & { formatFactory: FormatFactory }) {
const { title, accessor, mode } = args;
let value = '-';
const firstTable = Object.values(data.tables)[0];
if (!accessor) {
return (
<VisualizationContainer reportTitle={title} className="lnsMetricExpression__container" />
);
}
if (firstTable) {
const column = firstTable.columns[0];
const row = firstTable.rows[0];
if (row[accessor]) {
value =
column && column.formatHint
? formatFactory(column.formatHint).convert(row[accessor])
: Number(Number(row[accessor]).toFixed(3)).toString();
}
}
return (
<VisualizationContainer reportTitle={title} className="lnsMetricExpression__container">
<AutoScale>
<div data-test-subj="lns_metric_value" style={{ fontSize: '60pt', fontWeight: 600 }}>
{value}
</div>
{mode === 'full' && (
<div data-test-subj="lns_metric_title" style={{ fontSize: '24pt' }}>
{title}
</div>
)}
</AutoScale>
</VisualizationContainer>
);
}