Skip to content
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

make tooltip show all series #14914

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import PropTypes from 'prop-types';
import React, { Component } from 'react';
import moment from 'moment';
import reactcss from 'reactcss';
import { findIndex } from 'lodash';
import FlotChart from './flot_chart';
import Annotation from './annotation';

Expand Down Expand Up @@ -61,23 +62,28 @@ class TimeseriesChart extends Component {
}

handleMouseOver(e, pos, item, plot) {

if (typeof this.state.mouseHoverTimer === 'number') {
window.clearTimeout(this.state.mouseHoverTimer);
}

if (item) {
const offset = plot.offset();
const width = plot.width();
const height = plot.height();
const plotOffset = plot.getPlotOffset();
const point = plot.pointOffset({ x: item.datapoint[0], y: item.datapoint[1] });
const mouseX = Math.max(0, Math.min(pos.pageX - offset.left, width));
const mouseY = Math.max(0, Math.min(pos.pageY - offset.top, height));
const [left, right ] = this.calculateLeftRight(item, plot);
const top = point.top;
this.setState({
showTooltip: true,
item,
left,
right,
top: top + 10,
bottom: plotOffset.bottom
mouseX,
mouseY,
width,
leftOffset: plotOffset.left,
rightOffset: plotOffset.right
});
}
}
Expand All @@ -102,18 +108,38 @@ class TimeseriesChart extends Component {
}

render() {
const { item, right, top, left } = this.state;
const { item, right, left, mouseX, mouseY, width, leftOffset, rightOffset } = this.state;
const { series } = this.props;
let tooltip;
let timestamp;
let dataPoints = [];

if (item) {
timestamp = item.datapoint[0];
dataPoints = series.reduce((points, series) => {
const index = findIndex(series.data, (d => d[0] === timestamp));
if (index > -1) {
const datapoint = series.data[index];
if (datapoint) {
const point = {
series,
datapoint,
};
points = [...points, point];
}
}
return points;
}, []);
}

const styles = reactcss({
showTooltip: {
tooltipContainer: {
pointerEvents: 'none',
position: 'absolute',
top: top - 28,
left,
right,
top: mouseY - (dataPoints.length * 17 + 10) / 2,
left: left ? mouseX + leftOffset : null,
right: right ? width - mouseX + rightOffset : null,
zIndex: 100,
display: 'flex',
alignItems: 'center',
Expand All @@ -137,17 +163,22 @@ class TimeseriesChart extends Component {
date: {
color: this.props.reversed ? 'rgba(0,0,0,0.7)' : 'rgba(255,255,255,0.7)',
fontSize: '12px',
lineHeight: '12px'
lineHeight: '12px',
marginTop: 2
},
items: {
display: 'flex',
alignItems: 'center'
alignItems: 'center',
height: '17px'
},
text: {
whiteSpace: 'nowrap',
fontSize: '12px',
lineHeight: '12px',
marginRight: 5
marginRight: 5,
maxWidth: '300px',
overflow: 'hidden',
textOverflow: 'ellipsis'
},
icon: {
marginRight: 5
Expand All @@ -156,7 +187,7 @@ class TimeseriesChart extends Component {
fontSize: '12px',
flexShrink: 0,
lineHeight: '12px',
marginLeft: 5
marginLeft: 'auto'
}
},
hideTooltip: {
Expand All @@ -168,21 +199,28 @@ class TimeseriesChart extends Component {
});

if (item) {
const metric = series.find(r => r.id === item.series.id);
const formatter = metric && metric.tickFormatter || this.props.tickFormatter || ((v) => v);
const value = item.datapoint[2] ? item.datapoint[1] - item.datapoint[2] : item.datapoint[1];
const rows = dataPoints.map(point => {
const metric = series.find(r => r.id === point.series.id);
const formatter = metric && metric.tickFormatter || this.props.tickFormatter || ((v) => v);
const value = point.datapoint[2] ? point.datapoint[1] - point.datapoint[2] : point.datapoint[1];

return (
<div key={point.series.id} style={styles.items}>
<div style={styles.icon}>
<i className="fa fa-circle" style={{ color: point.series.color }}/>
</div>
<div style={styles.text}>{point.series.label}</div>
<div style={styles.value}>{formatter(value)}</div>
</div>
);
}, this);

tooltip = (
<div style={styles.tooltipContainer}>
<i className="fa fa-caret-left" style={styles.leftCaret} />
<div style={styles.tooltip}>
<div style={styles.items}>
<div style={styles.icon}>
<i className="fa fa-circle" style={{ color: item.series.color }} />
</div>
<div style={styles.text}>{ item.series.label }</div>
<div style={styles.value}>{ formatter(value) }</div>
</div>
<div style={styles.date}>{ moment(item.datapoint[0]).format(this.props.dateFormat) }</div>
{rows}
<div style={styles.date}>{ moment(timestamp).format(this.props.dateFormat) }</div>
</div>
<i className="fa fa-caret-right" style={styles.rightCaret} />
</div>
Expand Down
20 changes: 8 additions & 12 deletions src/ui/public/flot-charts/jquery.flot.js
Original file line number Diff line number Diff line change
Expand Up @@ -2010,7 +2010,7 @@ Licensed under the MIT license.
ctx.lineTo(xrange.to + subPixel, yrange.to);
} else {
ctx.moveTo(xrange.from, yrange.to + subPixel);
ctx.lineTo(xrange.to, yrange.to + subPixel);
ctx.lineTo(xrange.to, yrange.to + subPixel);
}
ctx.stroke();
} else {
Expand Down Expand Up @@ -2525,9 +2525,9 @@ Licensed under the MIT license.
radius = series.points.radius,
symbol = series.points.symbol;

// If the user sets the line width to 0, we change it to a very
// If the user sets the line width to 0, we change it to a very
// small value. A line width of 0 seems to force the default of 1.
// Doing the conditional here allows the shadow setting to still be
// Doing the conditional here allows the shadow setting to still be
// optional even with a lineWidth of 0.

if( lw == 0 )
Expand Down Expand Up @@ -2854,22 +2854,18 @@ Licensed under the MIT license.

if (s.lines.show || s.points.show) {
for (j = 0; j < points.length; j += ps) {
var x = points[j], y = points[j + 1];
var x = points[j];
if (x == null)
continue;

// calculate the "distance" from the the datapoint
var dist = Math.abs(x - mx);

// For points and lines, the cursor must be within a
// certain distance to the data point
if (x - mx > maxx || x - mx < -maxx ||
y - my > maxy || y - my < -maxy)
if (dist > maxx)
continue;

// We have to calculate distances in pixels, not in
// data units, because the scales of the axes may be different
var dx = Math.abs(axisx.p2c(x) - mouseX),
dy = Math.abs(axisy.p2c(y) - mouseY),
dist = dx * dx + dy * dy; // we save the sqrt

// use <= to ensure last point takes precedence
// (last generally means on top of)
if (dist < smallestDistance) {
Expand Down
1 change: 0 additions & 1 deletion src/ui/public/visualize/visualize.less
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ visualization {
flex-direction: column;
height: auto;
width: 100%;
overflow: auto;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably be checked with kibana vis team.
When overflow: auto, if the tooltip is high, it crosses the panel dimensions and gets cut.
Without overflow, the tooltip simply goes beyond the panel (Which is fine I guess).
I didn't find any other issues with it

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's probably best to leave this change out. EUI has a new tooltip component which should be (if not already) an easy fit into TSVB.

@simianhacker @mattapperson does TSVB use EUI tooltip yet, or is it in the near future?

position: relative;
padding: 8px 8px 8px 8px;

Expand Down