mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
* Allow resizing charts via keyboard * Use React updater function * Allow sorting of series via keyboard
This commit is contained in:
parent
37682b7074
commit
a1313e223a
10 changed files with 108 additions and 20 deletions
|
@ -0,0 +1,13 @@
|
|||
import { keyCodes } from 'ui_framework/services';
|
||||
|
||||
export function createUpDownHandler(callback) {
|
||||
return (ev) => {
|
||||
if (ev.keyCode === keyCodes.UP) {
|
||||
ev.preventDefault();
|
||||
callback('up');
|
||||
} else if (ev.keyCode === keyCodes.DOWN) {
|
||||
ev.preventDefault();
|
||||
callback('down');
|
||||
}
|
||||
};
|
||||
}
|
|
@ -65,6 +65,7 @@ class Series extends Component {
|
|||
onDelete: this.props.onDelete,
|
||||
onMouseDown: this.props.onMouseDown,
|
||||
onTouchStart: this.props.onTouchStart,
|
||||
onShouldSortItem: this.props.onShouldSortItem,
|
||||
onSortableItemMount: this.props.onSortableItemMount,
|
||||
onSortableItemReadyToMove: this.props.onSortableItemReadyToMove,
|
||||
model: this.props.model,
|
||||
|
@ -98,6 +99,7 @@ Series.propTypes = {
|
|||
onClone: PropTypes.func,
|
||||
onDelete: PropTypes.func,
|
||||
onMouseDown: PropTypes.func,
|
||||
onShouldSortItem: PropTypes.func.isRequired,
|
||||
onSortableItemMount: PropTypes.func,
|
||||
onSortableItemReadyToMove: PropTypes.func,
|
||||
onTouchStart: PropTypes.func,
|
||||
|
|
|
@ -15,6 +15,7 @@ class SeriesEditor extends Component {
|
|||
constructor(props) {
|
||||
super(props);
|
||||
this.renderRow = this.renderRow.bind(this);
|
||||
this.sortSeries = this.sortSeries.bind(this);
|
||||
}
|
||||
|
||||
handleClone(series) {
|
||||
|
@ -22,7 +23,21 @@ class SeriesEditor extends Component {
|
|||
handleAdd.call(null, this.props, () => newSeries);
|
||||
}
|
||||
|
||||
renderRow(row) {
|
||||
sortSeries(index, direction, allSeries) {
|
||||
const newIndex = index + (direction === 'up' ? -1 : 1);
|
||||
if (newIndex < 0 || newIndex >= allSeries.length) {
|
||||
// Don't do anything when series is already at the edge
|
||||
return;
|
||||
}
|
||||
|
||||
const newSeries = allSeries.slice(0);
|
||||
const changeWithElement = allSeries[newIndex];
|
||||
newSeries[newIndex] = allSeries[index];
|
||||
newSeries[index] = changeWithElement;
|
||||
this.props.onChange({ series: newSeries });
|
||||
}
|
||||
|
||||
renderRow(row, index, allSeries) {
|
||||
const { props } = this;
|
||||
const { fields, model, name, limit, colorPicker } = props;
|
||||
return (
|
||||
|
@ -36,6 +51,7 @@ class SeriesEditor extends Component {
|
|||
onChange={handleChange.bind(null, props)}
|
||||
onClone={() => this.handleClone(row)}
|
||||
onDelete={handleDelete.bind(null, props, row)}
|
||||
onShouldSortItem={(direction) => this.sortSeries(index, direction, allSeries)}
|
||||
model={row}
|
||||
panel={model}
|
||||
sortData={row.id}
|
||||
|
|
|
@ -1,20 +1,24 @@
|
|||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import { findDOMNode } from 'react-dom';
|
||||
import { keyCodes } from 'ui_framework/services';
|
||||
import Visualization from './visualization';
|
||||
import Toggle from 'react-toggle';
|
||||
import 'react-toggle/style.css';
|
||||
|
||||
const MIN_CHART_HEIGHT = 250;
|
||||
|
||||
class VisEditorVisualization extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
height: 250,
|
||||
height: MIN_CHART_HEIGHT,
|
||||
dragging: false
|
||||
};
|
||||
|
||||
this.handleMouseUp = this.handleMouseUp.bind(this);
|
||||
this.handleMouseDown = this.handleMouseDown.bind(this);
|
||||
this.onSizeHandleKeyDown = this.onSizeHandleKeyDown.bind(this);
|
||||
}
|
||||
|
||||
handleMouseDown() {
|
||||
|
@ -28,10 +32,9 @@ class VisEditorVisualization extends Component {
|
|||
componentWillMount() {
|
||||
this.handleMouseMove = (event) => {
|
||||
if (this.state.dragging) {
|
||||
const height = this.state.height + event.movementY;
|
||||
if (height > 250) {
|
||||
this.setState({ height });
|
||||
}
|
||||
this.setState((prevState) => ({
|
||||
height: Math.max(MIN_CHART_HEIGHT, prevState.height + event.movementY)
|
||||
}));
|
||||
}
|
||||
};
|
||||
window.addEventListener('mousemove', this.handleMouseMove);
|
||||
|
@ -48,6 +51,25 @@ class VisEditorVisualization extends Component {
|
|||
el.setAttribute('render-counter', 'disabled');
|
||||
}
|
||||
|
||||
/**
|
||||
* Resize the chart height when pressing up/down while the drag handle
|
||||
* for resizing has the focus.
|
||||
* We use 15px steps to do the scaling and make sure the chart has at least its
|
||||
* defined minimum width (MIN_CHART_HEIGHT).
|
||||
*/
|
||||
onSizeHandleKeyDown(ev) {
|
||||
const { keyCode } = ev;
|
||||
if (keyCode === keyCodes.UP || keyCode === keyCodes.DOWN) {
|
||||
ev.preventDefault();
|
||||
this.setState((prevState) => {
|
||||
const newHeight = prevState.height + (keyCode === keyCodes.UP ? -15 : 15);
|
||||
return {
|
||||
height: Math.max(MIN_CHART_HEIGHT, newHeight)
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { dirty, autoApply } = this.props;
|
||||
const style = { height: this.state.height };
|
||||
|
@ -117,14 +139,15 @@ class VisEditorVisualization extends Component {
|
|||
</div>
|
||||
<div className="vis-editor-hide-for-reporting">
|
||||
{applyButton}
|
||||
<div
|
||||
aria-hidden="true"
|
||||
<button
|
||||
className="vis_editor__visualization-draghandle"
|
||||
onMouseDown={this.handleMouseDown}
|
||||
onMouseUp={this.handleMouseUp}
|
||||
onKeyDown={this.onSizeHandleKeyDown}
|
||||
aria-label="Press up/down to adjust the chart size"
|
||||
>
|
||||
<i className="fa fa-ellipsis-h" />
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -8,6 +8,7 @@ import Split from '../../split';
|
|||
import Tooltip from '../../tooltip';
|
||||
import createAggRowRender from '../../lib/create_agg_row_render';
|
||||
import createTextHandler from '../../lib/create_text_handler';
|
||||
import { createUpDownHandler } from '../../lib/sort_keyhandler';
|
||||
|
||||
function GaugeSeries(props) {
|
||||
const {
|
||||
|
@ -111,9 +112,13 @@ function GaugeSeries(props) {
|
|||
if (!props.disableDelete) {
|
||||
dragHandle = (
|
||||
<Tooltip text="Sort">
|
||||
<div className="vis_editor__sort thor__button-outlined-default sm">
|
||||
<button
|
||||
className="vis_editor__sort thor__button-outlined-default sm"
|
||||
aria-label="Sort series by pressing up/down"
|
||||
onKeyDown={createUpDownHandler(props.onShouldSortItem)}
|
||||
>
|
||||
<i className="fa fa-sort" />
|
||||
</div>
|
||||
</button>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import Split from '../../split';
|
|||
import Tooltip from '../../tooltip';
|
||||
import createAggRowRender from '../../lib/create_agg_row_render';
|
||||
import createTextHandler from '../../lib/create_text_handler';
|
||||
import { createUpDownHandler } from '../../lib/sort_keyhandler';
|
||||
|
||||
function MetricSeries(props) {
|
||||
const {
|
||||
|
@ -114,9 +115,13 @@ function MetricSeries(props) {
|
|||
if (!props.disableDelete) {
|
||||
dragHandle = (
|
||||
<Tooltip text="Sort">
|
||||
<div className="vis_editor__sort thor__button-outlined-default sm">
|
||||
<button
|
||||
className="vis_editor__sort thor__button-outlined-default sm"
|
||||
aria-label="Sort series by pressing up/down"
|
||||
onKeyDown={createUpDownHandler(props.onShouldSortItem)}
|
||||
>
|
||||
<i className="fa fa-sort" />
|
||||
</div>
|
||||
</button>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import Sortable from 'react-anything-sortable';
|
|||
import Tooltip from '../../tooltip';
|
||||
import createTextHandler from '../../lib/create_text_handler';
|
||||
import createAggRowRender from '../../lib/create_agg_row_render';
|
||||
import { createUpDownHandler } from '../../lib/sort_keyhandler';
|
||||
|
||||
function TopNSeries(props) {
|
||||
const {
|
||||
|
@ -84,9 +85,13 @@ function TopNSeries(props) {
|
|||
if (!props.disableDelete) {
|
||||
dragHandle = (
|
||||
<Tooltip text="Sort">
|
||||
<div className="vis_editor__sort thor__button-outlined-default sm">
|
||||
<button
|
||||
className="vis_editor__sort thor__button-outlined-default sm"
|
||||
aria-label="Sort series by pressing up/down"
|
||||
onKeyDown={createUpDownHandler(props.onShouldSortItem)}
|
||||
>
|
||||
<i className="fa fa-sort" />
|
||||
</div>
|
||||
</button>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
@ -155,4 +160,3 @@ TopNSeries.propTypes = {
|
|||
};
|
||||
|
||||
export default TopNSeries;
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ import Tooltip from '../../tooltip';
|
|||
import Split from '../../split';
|
||||
import createAggRowRender from '../../lib/create_agg_row_render';
|
||||
import createTextHandler from '../../lib/create_text_handler';
|
||||
import { createUpDownHandler } from '../../lib/sort_keyhandler';
|
||||
|
||||
function TimeseriesSeries(props) {
|
||||
const {
|
||||
|
@ -111,9 +112,13 @@ function TimeseriesSeries(props) {
|
|||
if (!props.disableDelete) {
|
||||
dragHandle = (
|
||||
<Tooltip text="Sort">
|
||||
<div className="vis_editor__sort thor__button-outlined-default sm">
|
||||
<button
|
||||
className="vis_editor__sort thor__button-outlined-default sm"
|
||||
aria-label="Sort series by pressing up/down"
|
||||
onKeyDown={createUpDownHandler(props.onShouldSortItem)}
|
||||
>
|
||||
<i className="fa fa-sort" />
|
||||
</div>
|
||||
</button>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
@ -175,6 +180,7 @@ TimeseriesSeries.propTypes = {
|
|||
onClone: PropTypes.func,
|
||||
onDelete: PropTypes.func,
|
||||
onMouseDown: PropTypes.func,
|
||||
onShouldSortItem: PropTypes.func.isRequired,
|
||||
onSortableItemMount: PropTypes.func,
|
||||
onSortableItemReadyToMove: PropTypes.func,
|
||||
onTouchStart: PropTypes.func,
|
||||
|
|
|
@ -8,6 +8,7 @@ import Split from '../../split';
|
|||
import Tooltip from '../../tooltip';
|
||||
import createTextHandler from '../../lib/create_text_handler';
|
||||
import createAggRowRender from '../../lib/create_agg_row_render';
|
||||
import { createUpDownHandler } from '../../lib/sort_keyhandler';
|
||||
|
||||
function TopNSeries(props) {
|
||||
const {
|
||||
|
@ -109,9 +110,13 @@ function TopNSeries(props) {
|
|||
if (!props.disableDelete) {
|
||||
dragHandle = (
|
||||
<Tooltip text="Sort">
|
||||
<div className="vis_editor__sort thor__button-outlined-default sm">
|
||||
<button
|
||||
className="vis_editor__sort thor__button-outlined-default sm"
|
||||
aria-label="Sort series by pressing up/down"
|
||||
onKeyDown={createUpDownHandler(props.onShouldSortItem)}
|
||||
>
|
||||
<i className="fa fa-sort" />
|
||||
</div>
|
||||
</button>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -298,9 +298,18 @@
|
|||
text-align: center;
|
||||
color: @grayLight;
|
||||
cursor: row-resize;
|
||||
width: 100%;
|
||||
display: block;
|
||||
appearance: none;
|
||||
background: none;
|
||||
border: none;
|
||||
&:hover {
|
||||
color: @gray;
|
||||
}
|
||||
&:focus {
|
||||
color: @esBlue;
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
.vis_editor__visualization-title {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue