-
Notifications
You must be signed in to change notification settings - Fork 8.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Time Series Metric Visualizations #9725
Changes from all commits
f9d527e
c5e936f
0d0f4c6
2fb42d0
63a736a
6ede79b
1cb2860
4efe0ec
33f4d53
51ff9f8
2ba0463
09b6ada
985ec1c
bd87e89
5ce7d85
0b72290
a6e91ba
5ee12ac
ee52e34
16b7469
1e64c7c
b4ce642
b5ff6c6
6641c8e
b7822ec
74dc57f
95e58b0
5d2bf42
f1ff198
23821b5
efd39d9
23f6bc7
940a096
1d0f9aa
a2add21
c1af796
bd05f9b
47969cd
426b275
b1d1adb
a991c38
551eba6
3960535
ed1550c
4111b38
ff5c79d
61ac01a
76ff363
95235d6
525c59a
94cc787
347493f
abf0f14
bc2aadc
6d5bb61
60a3fd0
5fbd364
9d558e3
e7deeba
1c3a3ea
cf4d4cf
c859926
50ff3e8
19cae0f
2e4f8bc
9a392d3
bc1e53d
ea15490
c9e3bcb
5483ed1
8eff937
277b2c9
ba55260
b437f72
d8fd02f
ab40b04
c1f76b9
af2fdb8
6a8ae4c
ac3796c
1e39f32
38cd134
9eaa455
e375c8f
84e8445
a610601
f81191d
041c7a1
6eb03d4
d6ed86f
a099f3a
f031893
fdd4357
cf7a3f9
9849833
ddf863e
e413425
8321f8c
c1f3649
bae79c1
8e0b003
cd7d9a0
61af862
399cdaf
9aab685
61c5a6c
43a3551
ea0d37f
6037c13
93bfc89
4631611
4151596
a32fa6e
6038305
2c5e356
ddd90db
c47a407
a2aef22
140093c
6bbe6ef
dcb44fe
e65528c
766005d
e497a36
4eba511
92765f7
1629ed3
ebfad5c
0d69732
111128b
7b930cf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import fieldsRoutes from './server/routes/fields'; | ||
import visDataRoutes from './server/routes/vis'; | ||
|
||
export default function (kibana) { | ||
return new kibana.Plugin({ | ||
require: ['kibana','elasticsearch'], | ||
|
||
uiExports: { | ||
visTypes: [ | ||
'plugins/metrics/kbn_vis_types' | ||
] | ||
}, | ||
|
||
config(Joi) { | ||
return Joi.object({ | ||
enabled: Joi.boolean().default(true), | ||
chartResolution: Joi.number().default(150), | ||
minimumBucketSize: Joi.number().default(10) | ||
}).default(); | ||
}, | ||
|
||
|
||
init(server, options) { | ||
const { status } = server.plugins.elasticsearch; | ||
fieldsRoutes(server); | ||
visDataRoutes(server); | ||
} | ||
|
||
|
||
}); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"author": "Chris Cowan<[email protected]>", | ||
"name": "metrics", | ||
"version": "kibana" | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
// import React from 'react'; | ||
// import { expect } from 'chai'; | ||
// import { shallow } from 'enzyme'; | ||
// import sinon from 'sinon'; | ||
// import AddDeleteButtons from '../add_delete_buttons'; | ||
// import Tooltip from '../tooltip'; | ||
|
||
// describe('<AddDeleteButtons />', () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Both giving LGTMs and merging while tests are commented out? -1 from me. I'm hoping there is an issue created already to fix this? If we can't get tests to run we have to either fix them or delete them. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (Oh, saw the comment in the backport. I still think this should have been fixed first though. Broken windows and all that.) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree with your sentiment but we (team) wanted to get this commit in this week so it would be available via snapshots for Elastic{ON} and allow more time for people to use it before 5.4 ships. Luckily this is "soft"ware and we can work towards getting Enzyme working again. It broke when the Babel upgrade occurred; had this been merged before that upgrade it would hve been addressed by that team. The issue I have with keeping PR's like this separate for too long is you keep having to chase master as they change things; the PR keeps getting bigger and never seems to finish. With this merged we can now focus on creating smaller more manageable PR's to fix anything that needs addressed between now and code freeze. |
||
|
||
// it('calls onAdd={handleAdd}', () => { | ||
// const handleAdd = sinon.spy(); | ||
// const wrapper = shallow( | ||
// <AddDeleteButtons onAdd={handleAdd} /> | ||
// ); | ||
// wrapper.find('a').at(0).simulate('click'); | ||
// expect(handleAdd.calledOnce).to.equal(true); | ||
// }); | ||
|
||
// it('calls onDelete={handleDelete}', () => { | ||
// const handleDelete = sinon.spy(); | ||
// const wrapper = shallow( | ||
// <AddDeleteButtons onDelete={handleDelete} /> | ||
// ); | ||
// wrapper.find('a').at(1).simulate('click'); | ||
// expect(handleDelete.calledOnce).to.equal(true); | ||
// }); | ||
|
||
// it('calls onClone={handleClone}', () => { | ||
// const handleClone = sinon.spy(); | ||
// const wrapper = shallow( | ||
// <AddDeleteButtons onClone={handleClone} /> | ||
// ); | ||
// wrapper.find('a').at(0).simulate('click'); | ||
// expect(handleClone.calledOnce).to.equal(true); | ||
// }); | ||
|
||
// it('disableDelete={true}', () => { | ||
// const wrapper = shallow( | ||
// <AddDeleteButtons disableDelete={true} /> | ||
// ); | ||
// expect(wrapper.find({ text: 'Delete' })).to.have.length(0); | ||
// }); | ||
|
||
// it('disableAdd={true}', () => { | ||
// const wrapper = shallow( | ||
// <AddDeleteButtons disableAdd={true} /> | ||
// ); | ||
// expect(wrapper.find({ text: 'Add' })).to.have.length(0); | ||
// }); | ||
|
||
// it('should not display clone by default', () => { | ||
// const wrapper = shallow( | ||
// <AddDeleteButtons /> | ||
// ); | ||
// expect(wrapper.find({ text: 'Clone' })).to.have.length(0); | ||
// }); | ||
|
||
// it('should not display clone when disableAdd={true}', () => { | ||
// const fn = sinon.spy(); | ||
// const wrapper = shallow( | ||
// <AddDeleteButtons onClone={fn} disableAdd={true} /> | ||
// ); | ||
// expect(wrapper.find({ text: 'Clone' })).to.have.length(0); | ||
// }); | ||
|
||
// }); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// import React from 'react'; | ||
// import { expect } from 'chai'; | ||
// import { shallow } from 'enzyme'; | ||
// import sinon from 'sinon'; | ||
// import YesNo from '../yes_no'; | ||
|
||
// describe('<YesNo />', () => { | ||
|
||
// it('call onChange={handleChange} on yes', () => { | ||
// const handleChange = sinon.spy(); | ||
// const wrapper = shallow( | ||
// <YesNo name="test" onChange={handleChange} /> | ||
// ); | ||
// wrapper.find('input').first().simulate('change'); | ||
// expect(handleChange.calledOnce).to.equal(true); | ||
// expect(handleChange.firstCall.args[0]).to.eql({ | ||
// test: 1 | ||
// }); | ||
// }); | ||
|
||
// it('call onChange={handleChange} on no', () => { | ||
// const handleChange = sinon.spy(); | ||
// const wrapper = shallow( | ||
// <YesNo name="test" onChange={handleChange} /> | ||
// ); | ||
// wrapper.find('input').last().simulate('change'); | ||
// expect(handleChange.calledOnce).to.equal(true); | ||
// expect(handleChange.firstCall.args[0]).to.eql({ | ||
// test: 0 | ||
// }); | ||
// }); | ||
|
||
// }); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import React, { Component, PropTypes } from 'react'; | ||
import Tooltip from './tooltip'; | ||
|
||
function AddDeleteButtons(props) { | ||
const createDelete = () => { | ||
if (props.disableDelete) { | ||
return null; | ||
} | ||
return ( | ||
<Tooltip text="Delete"> | ||
<a className="thor__button-outlined-danger sm" onClick={ props.onDelete }> | ||
<i className="fa fa-trash-o"></i> | ||
</a> | ||
</Tooltip> | ||
); | ||
}; | ||
const createAdd = () => { | ||
if (props.disableAdd) { | ||
return null; | ||
} | ||
return ( | ||
<Tooltip text="Add"> | ||
<a className="thor__button-outlined-default sm" onClick={ props.onAdd }> | ||
<i className="fa fa-plus"></i> | ||
</a> | ||
</Tooltip> | ||
); | ||
}; | ||
const deleteBtn = createDelete(); | ||
const addBtn = createAdd(); | ||
let clone; | ||
if (props.onClone && !props.disableAdd) { | ||
clone = ( | ||
<Tooltip text="Clone"> | ||
<a className="thor__button-outlined-default sm" onClick={ props.onClone }> | ||
<i className="fa fa-files-o"></i> | ||
</a> | ||
</Tooltip> | ||
); | ||
} | ||
return ( | ||
<div className="add_delete__buttons"> | ||
{ clone } | ||
{ addBtn } | ||
{ deleteBtn } | ||
</div> | ||
); | ||
} | ||
|
||
AddDeleteButtons.propTypes = { | ||
disableAdd: PropTypes.bool, | ||
disableDelete: PropTypes.bool, | ||
onClone: PropTypes.func, | ||
onAdd: PropTypes.func, | ||
onDelete: PropTypes.func | ||
}; | ||
|
||
export default AddDeleteButtons; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import React, { PropTypes } from 'react'; | ||
import StdAgg from './std_agg'; | ||
import aggToComponent from '../lib/agg_to_component'; | ||
import { sortable } from 'react-anything-sortable'; | ||
|
||
function Agg(props) { | ||
const { model } = props; | ||
let Component = aggToComponent[model.type]; | ||
if (!Component) { | ||
Component = StdAgg; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not sure what this is. Component is not used? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's used on line 19 |
||
} | ||
const style = Object.assign({ cursor: 'default' }, props.style); | ||
return ( | ||
<div | ||
className={props.className} | ||
style={style} | ||
onMouseDown={props.onMouseDown} | ||
onTouchStart={props.onTouchStart}> | ||
<Component | ||
fields={props.fields} | ||
disableDelete={props.disableDelete} | ||
model={props.model} | ||
onAdd={props.onAdd} | ||
onChange={props.onChange} | ||
onDelete={props.onDelete} | ||
panel={props.panel} | ||
series={props.series} | ||
siblings={props.siblings}/> | ||
</div> | ||
); | ||
|
||
} | ||
|
||
Agg.propTypes = { | ||
disableDelete: PropTypes.bool, | ||
fields: PropTypes.object, | ||
model: PropTypes.object, | ||
onAdd: PropTypes.func, | ||
onChange: PropTypes.func, | ||
onDelete: PropTypes.func, | ||
onMouseDown: PropTypes.func, | ||
onSortableItemMount: PropTypes.func, | ||
onSortableItemReadyToMove: PropTypes.func, | ||
onTouchStart: PropTypes.func, | ||
panel: PropTypes.object, | ||
series: PropTypes.object, | ||
siblings: PropTypes.array, | ||
sortData: PropTypes.string, | ||
}; | ||
|
||
export default sortable(Agg); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import React, { PropTypes } from 'react'; | ||
import _ from 'lodash'; | ||
import AddDeleteButtons from '../add_delete_buttons'; | ||
import Tooltip from '../tooltip'; | ||
|
||
function AggRow(props) { | ||
let iconClassName = 'fa fa-eye-slash'; | ||
let iconRowClassName = 'vis_editor__agg_row-icon'; | ||
const last = _.last(props.siblings); | ||
if (last.id === props.model.id) { | ||
iconClassName = 'fa fa-eye'; | ||
iconRowClassName += ' last'; | ||
} | ||
|
||
let dragHandle; | ||
if (!props.disableDelete) { | ||
dragHandle = ( | ||
<div> | ||
<Tooltip text="Sort"> | ||
<div className="vis_editor__agg_sort thor__button-outlined-default sm"> | ||
<i className="fa fa-sort"></i> | ||
</div> | ||
</Tooltip> | ||
</div> | ||
); | ||
} | ||
|
||
return ( | ||
<div className="vis_editor__agg_row"> | ||
<div className="vis_editor__agg_row-item"> | ||
<div className={iconRowClassName}> | ||
<i className={iconClassName}></i> | ||
</div> | ||
{props.children} | ||
{ dragHandle } | ||
<AddDeleteButtons | ||
onAdd={props.onAdd} | ||
onDelete={props.onDelete} | ||
disableDelete={props.disableDelete}/> | ||
</div> | ||
</div> | ||
); | ||
} | ||
|
||
AggRow.propTypes = { | ||
disableDelete: PropTypes.bool, | ||
model: PropTypes.object, | ||
onAdd: PropTypes.func, | ||
onDelete: PropTypes.func, | ||
siblings: PropTypes.array, | ||
}; | ||
|
||
export default AggRow; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change to Time Series Visual Builder (?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Name has to match the plugin path.