Skip to content

Commit

Permalink
[TSVB] Introducing Timerange Data Mode for Metric Style Visualizations
Browse files Browse the repository at this point in the history
- Adds timerange data mode for table, guage, metric and top n
- Changes query for metric style vis to only query last 5 buckets unless
there is a sibling agg
- Request and response are now included in api response
- Fixed table header EUI upgrade
- Fixed wrapping for top n
- Fixing tests
- Fixes elastic#14681 - Change the behavior of drop last bucket to drop partial bucket
- Move index pattern out of panel options; adding info component
- Removing panel property from AggSelect
- Defaulting to EUI standards for code style
- Updating modal to EUI writing guidlines
- Renaming functions to be more clear
- Adding date math since yarn was complaining
- Fixin the logic for truncated timerange
- Fixing outdated tests
- Adjusting tests to new feature
- Updating to latest EUI
  • Loading branch information
simianhacker committed Apr 12, 2018
1 parent 35e01f2 commit 069332c
Show file tree
Hide file tree
Showing 58 changed files with 889 additions and 314 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
"url": "https:/elastic/kibana.git"
},
"dependencies": {
"@elastic/datemath": "4.0.2",
"@elastic/eui": "v0.0.38",
"@elastic/filesaver": "1.1.2",
"@elastic/numeral": "2.3.2",
Expand Down
5 changes: 5 additions & 0 deletions src/core_plugins/metrics/common/metric_types.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const metricTypes = ['gauge', 'table', 'metric', 'top_n'];

export function isMetric(panelType) {
return metricTypes.includes(panelType);
}
13 changes: 12 additions & 1 deletion src/core_plugins/metrics/public/components/aggs/agg_select.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import Select from 'react-select';
import { isMetric } from '../../../common/metric_types';

const metricAggs = [
{ label: 'Average', value: 'avg' },
Expand Down Expand Up @@ -136,7 +137,7 @@ function filterByPanelType(panelType) {
}

function AggSelect(props) {
const { siblings, panelType } = props;
const { siblings, panelType, timerangeMode } = props;

let enablePipelines = siblings.some(
s => !!metricAggs.find(m => m.value === s.type)
Expand All @@ -146,6 +147,15 @@ function AggSelect(props) {
let options;
if (panelType === 'metrics') {
options = metricAggs;
} else if (isMetric(panelType) && timerangeMode === 'all') {
options = [
{ label: 'Metric Aggregations', value: null, heading: true, disabled: true },
...metricAggs,
{ label: 'Parent Pipeline Aggregations', value: null, pipeline: true, heading: true, disabled: true },
...pipelineAggs.filter(filterByPanelType(panelType))
.filter(agg => agg.value === 'calculation')
.map(agg => ({ ...agg, disabled: !enablePipelines })),
];
} else {
options = [
{
Expand Down Expand Up @@ -209,6 +219,7 @@ AggSelect.propTypes = {
panelType: PropTypes.string,
siblings: PropTypes.array,
value: PropTypes.string,
timerangeMode: PropTypes.oneOf(['all', 'last']),
};

export default AggSelect;
16 changes: 9 additions & 7 deletions src/core_plugins/metrics/public/components/aggs/calculation.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@ import Vars from './vars';
import { htmlIdGenerator } from '@elastic/eui';

class CalculationAgg extends Component {

componentWillMount() {
if (!this.props.model.variables) {
this.props.onChange(_.assign({}, this.props.model, {
variables: [{ id: uuid.v1() }]
}));
this.props.onChange(
_.assign({}, this.props.model, {
variables: [{ id: uuid.v1() }],
})
);
}
}

Expand Down Expand Up @@ -47,6 +48,7 @@ class CalculationAgg extends Component {
<div className="vis_editor__label">Aggregation</div>
<AggSelect
panelType={this.props.panel.type}
timerangeMode={this.props.panel.timerange_mode}
siblings={this.props.siblings}
value={model.type}
onChange={handleSelectChange('type')}
Expand All @@ -63,8 +65,9 @@ class CalculationAgg extends Component {
<div className="vis_editor__row_item">
<label className="vis_editor__label" htmlFor={htmlId('painless')}>
Painless Script - Variables are keys on the <code>params</code>
object, i.e. <code>params.&lt;name&gt;</code>.
To access the bucket interval (in milliseconds) use <code>params._interval</code>.
object, i.e. <code>params.&lt;name&gt;</code>. To access the
bucket interval (in milliseconds) use{' '}
<code>params._interval</code>.
</label>
<input
id={htmlId('painless')}
Expand All @@ -79,7 +82,6 @@ class CalculationAgg extends Component {
</AggRow>
);
}

}

CalculationAgg.propTypes = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ function CumlativeSumAgg(props) {
<div className="vis_editor__row_item">
<div className="vis_editor__label">Aggregation</div>
<AggSelect
timerangeMode={props.panel.timerange_mode}
panelType={props.panel.type}
siblings={props.siblings}
value={model.type}
Expand All @@ -38,7 +39,6 @@ function CumlativeSumAgg(props) {
</div>
</AggRow>
);

}

CumlativeSumAgg.propTypes = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export const DerivativeAgg = props => {
<div className="vis_editor__label">Aggregation</div>
<AggSelect
panelType={props.panel.type}
timerangeMode={props.panel.timerange_mode}
siblings={props.siblings}
value={model.type}
onChange={handleSelectChange('type')}
Expand Down
24 changes: 14 additions & 10 deletions src/core_plugins/metrics/public/components/aggs/filter_ratio.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,19 @@ import createTextHandler from '../lib/create_text_handler';
import { htmlIdGenerator } from '@elastic/eui';

export const FilterRatioAgg = props => {
const {
series,
fields,
panel
} = props;
const { series, fields, panel } = props;

const handleChange = createChangeHandler(props.onChange, props.model);
const handleSelectChange = createSelectHandler(handleChange);
const handleTextChange = createTextHandler(handleChange);
const indexPattern = series.override_index_pattern && series.series_index_pattern || panel.index_pattern;
const indexPattern =
(series.override_index_pattern && series.series_index_pattern) ||
panel.index_pattern;

const defaults = {
numerator: '*',
denominator: '*',
metric_agg: 'count'
metric_agg: 'count',
};

const model = { ...defaults, ...props.model };
Expand All @@ -44,6 +42,7 @@ export const FilterRatioAgg = props => {
<div className="vis_editor__row_item">
<div className="vis_editor__label">Aggregation</div>
<AggSelect
timerangeMode={props.panel.timerange_mode}
panelType={props.panel.type}
siblings={props.siblings}
value={model.type}
Expand All @@ -63,7 +62,10 @@ export const FilterRatioAgg = props => {
/>
</div>
<div className="vis_editor__row_item">
<label className="vis_editor__label" htmlFor={htmlId('denominator')}>
<label
className="vis_editor__label"
htmlFor={htmlId('denominator')}
>
Denominator
</label>
<input
Expand All @@ -81,11 +83,12 @@ export const FilterRatioAgg = props => {
<AggSelect
siblings={props.siblings}
panelType="metrics"
timerangeMode={props.panel.timerange_mode}
value={model.metric_agg}
onChange={handleSelectChange('metric_agg')}
/>
</div>
{ model.metric_agg !== 'count' ? (
{model.metric_agg !== 'count' ? (
<div className="vis_editor__row_item">
<label className="vis_editor__label" htmlFor={htmlId('aggField')}>
Field
Expand All @@ -99,7 +102,8 @@ export const FilterRatioAgg = props => {
value={model.field}
onChange={handleSelectChange('field')}
/>
</div>) : null }
</div>
) : null}
</div>
</div>
</AggRow>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export const MovingAverageAgg = props => {
<div className="vis_editor__row_item">
<div className="vis_editor__label">Aggregation</div>
<AggSelect
panel={props.panel}
panelType={props.panel.type}
siblings={props.siblings}
value={model.type}
Expand Down
137 changes: 13 additions & 124 deletions src/core_plugins/metrics/public/components/aggs/percentile.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,134 +4,21 @@ import _ from 'lodash';
import AggSelect from './agg_select';
import FieldSelect from './field_select';
import AggRow from './agg_row';
import * as collectionActions from '../lib/collection_actions';
import AddDeleteButtons from '../add_delete_buttons';
import Select from 'react-select';
import uuid from 'uuid';
import createChangeHandler from '../lib/create_change_handler';
import createSelectHandler from '../lib/create_select_handler';
import { htmlIdGenerator } from '@elastic/eui';
const newPercentile = (opts) => {
return _.assign({ id: uuid.v1(), mode: 'line', shade: 0.2 }, opts);
};

class Percentiles extends Component {

constructor(props) {
super(props);
this.renderRow = this.renderRow.bind(this);
}
import { Percentiles } from './percentiles';
import { createNewPercentile } from '../lib/create_new_percentile';

handleTextChange(item, name) {
return (e) => {
const handleChange = collectionActions.handleChange.bind(null, this.props);
const part = {};
part[name] = _.get(e, 'value', _.get(e, 'target.value'));
handleChange(_.assign({}, item, part));
};
}

renderRow(row, i, items) {
const defaults = { value: '', percentile: '', shade: '' };
const model = { ...defaults, ...row };
const handleAdd = collectionActions.handleAdd.bind(null, this.props, newPercentile);
const handleDelete = collectionActions.handleDelete.bind(null, this.props, model);
const modeOptions = [
{ label: 'Line', value: 'line' },
{ label: 'Band', value: 'band' }
];
const optionsStyle = {};
if (model.mode === 'line') {
optionsStyle.display = 'none';
}
const htmlId = htmlIdGenerator(model.id);
return (
<div className="vis_editor__percentiles-row" key={model.id}>
<div className="vis_editor__percentiles-content">
<input
aria-label="Percentile"
placeholder="Percentile"
className="vis_editor__input-grows"
type="number"
step="1"
onChange={this.handleTextChange(model, 'value')}
value={model.value}
/>
<label className="vis_editor__label" htmlFor={htmlId('mode')}>Mode</label>
<div className="vis_editor__row_item">
<Select
inputProps={{ id: htmlId('mode') }}
clearable={false}
onChange={this.handleTextChange(model, 'mode')}
options={modeOptions}
value={model.mode}
/>
</div>
<label style={optionsStyle} className="vis_editor__label" htmlFor={htmlId('fillTo')}>
Fill To
</label>
<input
id={htmlId('fillTo')}
style={optionsStyle}
className="vis_editor__input-grows"
type="number"
step="1"
onChange={this.handleTextChange(model, 'percentile')}
value={model.percentile}
/>
<label style={optionsStyle} className="vis_editor__label" htmlFor={htmlId('shade')}>
Shade (0 to 1)
</label>
<input
id={htmlId('shade')}
style={optionsStyle}
className="vis_editor__input-grows"
type="number"
step="0.1"
onChange={this.handleTextChange(model, 'shade')}
value={model.shade}
/>
</div>
<AddDeleteButtons
onAdd={handleAdd}
onDelete={handleDelete}
disableDelete={items.length < 2}
/>
</div>
);
}

render() {
const { model, name } = this.props;
if (!model[name]) return (<div/>);

const rows = model[name].map(this.renderRow);
return (
<div className="vis_editor__percentiles">
{ rows }
</div>
);
}
}

Percentiles.defaultProps = {
name: 'percentile'
};

Percentiles.propTypes = {
name: PropTypes.string,
model: PropTypes.object,
onChange: PropTypes.func
};


class PercentileAgg extends Component { // eslint-disable-line react/no-multi-comp
class PercentileAgg extends Component {
// eslint-disable-line react/no-multi-comp

componentWillMount() {
if (!this.props.model.percentiles) {
this.props.onChange(_.assign({}, this.props.model, {
percentiles: [newPercentile({ value: 50 })]
}));
this.props.onChange(
_.assign({}, this.props.model, {
percentiles: [createNewPercentile({ value: 50 })],
})
);
}
}

Expand All @@ -140,7 +27,9 @@ class PercentileAgg extends Component { // eslint-disable-line react/no-multi-co

const handleChange = createChangeHandler(this.props.onChange, model);
const handleSelectChange = createSelectHandler(handleChange);
const indexPattern = series.override_index_pattern && series.series_index_pattern || panel.index_pattern;
const indexPattern =
(series.override_index_pattern && series.series_index_pattern) ||
panel.index_pattern;

return (
<AggRow
Expand All @@ -156,6 +45,7 @@ class PercentileAgg extends Component { // eslint-disable-line react/no-multi-co
<div className="vis_editor__label">Aggregation</div>
<AggSelect
panelType={this.props.panel.type}
timerangeMode={this.props.panel.timerangeMode}
siblings={this.props.siblings}
value={model.type}
onChange={handleSelectChange('type')}
Expand All @@ -182,7 +72,6 @@ class PercentileAgg extends Component { // eslint-disable-line react/no-multi-co
</AggRow>
);
}

}

PercentileAgg.propTypes = {
Expand Down
Loading

0 comments on commit 069332c

Please sign in to comment.