problem timeline: show event info

This commit is contained in:
Alexander Zobnin
2018-12-16 13:10:48 +03:00
parent 883bae85b1
commit 260564884c
2 changed files with 78 additions and 15 deletions

View File

@@ -1,4 +1,5 @@
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import moment from 'moment';
import { GFTimeRange, ZBXEvent } from 'panel-triggers/types'; import { GFTimeRange, ZBXEvent } from 'panel-triggers/types';
const DEFAULT_OK_COLOR = 'rgb(56, 189, 113)'; const DEFAULT_OK_COLOR = 'rgb(56, 189, 113)';
@@ -14,6 +15,8 @@ export interface ProblemTimelineProps {
interface ProblemTimelineState { interface ProblemTimelineState {
width: number; width: number;
highlightedEvent?: ZBXEvent | null;
showEventInfo?: boolean;
} }
export default class ProblemTimeline extends PureComponent<ProblemTimelineProps, ProblemTimelineState> { export default class ProblemTimeline extends PureComponent<ProblemTimelineProps, ProblemTimelineState> {
@@ -38,6 +41,14 @@ export default class ProblemTimeline extends PureComponent<ProblemTimelineProps,
this.setState({ width }); this.setState({ width });
} }
showEventInfo = (event: ZBXEvent) => {
this.setState({ highlightedEvent: event, showEventInfo: true });
}
hideEventInfo = () => {
this.setState({ showEventInfo: false });
}
render() { render() {
if (!this.rootRef) { if (!this.rootRef) {
return <div className="event-timeline" ref={this.setRootRef} />; return <div className="event-timeline" ref={this.setRootRef} />;
@@ -100,10 +111,11 @@ export default class ProblemTimeline extends PureComponent<ProblemTimelineProps,
return ( return (
<div className="event-timeline" ref={this.setRootRef}> <div className="event-timeline" ref={this.setRootRef}>
<div className="timeline-info-container"> <TimelineInfoContainer className="timeline-info-container"
<span>Info:</span> event={this.state.highlightedEvent}
</div> show={this.state.showEventInfo}
<svg className="event-timeline-canvas" viewBox={`0 0 ${width} 40`}> />
<svg className="event-timeline-canvas" viewBox={`0 0 ${width + 20} 40`}>
<defs> <defs>
<filter id="dropShadow" x="-50%" y="-50%" width="200%" height="200%"> <filter id="dropShadow" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur in="SourceAlpha" stdDeviation="2" /> <feGaussianBlur in="SourceAlpha" stdDeviation="2" />
@@ -136,6 +148,8 @@ export default class ProblemTimeline extends PureComponent<ProblemTimelineProps,
width={width} width={width}
okColor={okColor} okColor={okColor}
problemColor={problemColor} problemColor={problemColor}
onPointHighlight={this.showEventInfo}
onPointUnHighlight={this.hideEventInfo}
/> />
</g> </g>
</g> </g>
@@ -145,6 +159,36 @@ export default class ProblemTimeline extends PureComponent<ProblemTimelineProps,
} }
} }
interface TimelineInfoContainerProps {
event?: ZBXEvent | null;
show?: boolean;
className?: string;
}
class TimelineInfoContainer extends PureComponent<TimelineInfoContainerProps> {
render() {
const { show, className } = this.props;
const event = this.props.event;
let infoItems;
if (event) {
console.log(event);
const ts = moment(Number(event.clock) * 1000);
const tsFormatted = ts.format('HH:mm:ss');
infoItems = [
<span className="event-timestamp">{tsFormatted}</span>
];
}
const containerStyle: React.CSSProperties = {
opacity: show ? 1 : 0,
};
return (
<div className={className} style={containerStyle}>
{infoItems}
</div>
);
}
}
function TimelineRegion(props) { function TimelineRegion(props) {
return ( return (
<rect></rect> <rect></rect>
@@ -157,6 +201,8 @@ interface TimelinePointsProps {
width: number; width: number;
okColor: string; okColor: string;
problemColor: string; problemColor: string;
onPointHighlight?: (event: ZBXEvent) => void;
onPointUnHighlight?: () => void;
} }
interface TimelinePointsState { interface TimelinePointsState {
@@ -170,19 +216,26 @@ class TimelinePoints extends PureComponent<TimelinePointsProps, TimelinePointsSt
} }
bringToFront = index => { bringToFront = index => {
const length = this.props.events.length; const { events } = this.props;
const order = this.props.events.map((v, i) => i); const length = events.length;
const order = events.map((v, i) => i);
order.splice(index, 1); order.splice(index, 1);
order.push(index); order.push(index);
this.setState({ order }); this.setState({ order });
} }
highlightPoint = index => () => { highlightPoint = index => () => {
if (this.props.onPointHighlight) {
this.props.onPointHighlight(this.props.events[index]);
}
this.bringToFront(index); this.bringToFront(index);
} }
unHighlightPoint = index => () => { unHighlightPoint = index => () => {
if (this.props.onPointUnHighlight) {
this.props.onPointUnHighlight();
}
const order = this.props.events.map((v, i) => i); const order = this.props.events.map((v, i) => i);
this.setState({ order }); this.setState({ order });
} }
@@ -203,8 +256,8 @@ class TimelinePoints extends PureComponent<TimelinePointsProps, TimelinePointsSt
x={posLeft} x={posLeft}
r={10} r={10}
color={eventColor} color={eventColor}
onHighlightPoint={this.highlightPoint(index)} onPointHighlight={this.highlightPoint(index)}
onUnHighlightPoint={this.unHighlightPoint(index)} onPointUnHighlight={this.unHighlightPoint(index)}
/> />
); );
}); });
@@ -220,8 +273,8 @@ interface TimelinePointProps {
r: number; r: number;
color: string; color: string;
className?: string; className?: string;
onHighlightPoint?: () => void; onPointHighlight?: () => void;
onUnHighlightPoint?: () => void; onPointUnHighlight?: () => void;
} }
interface TimelinePointState { interface TimelinePointState {
@@ -235,15 +288,15 @@ class TimelinePoint extends PureComponent<TimelinePointProps, TimelinePointState
} }
handleMouseOver = () => { handleMouseOver = () => {
if (this.props.onHighlightPoint) { if (this.props.onPointHighlight) {
this.props.onHighlightPoint(); this.props.onPointHighlight();
} }
this.setState({ highlighted: true }); this.setState({ highlighted: true });
} }
handleMouseLeave = () => { handleMouseLeave = () => {
if (this.props.onUnHighlightPoint) { if (this.props.onPointUnHighlight) {
this.props.onUnHighlightPoint(); this.props.onPointUnHighlight();
} }
this.setState({ highlighted: false }); this.setState({ highlighted: false });
} }

View File

@@ -340,17 +340,27 @@
.event-timeline { .event-timeline {
display: flex; display: flex;
position: relative; position: relative;
margin: 1.6rem 0; margin-bottom: 1.6rem;
padding-top: 0.4rem;
// margin-top: auto; // margin-top: auto;
.timeline-info-container { .timeline-info-container {
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
transition: all 0.2s ease-out;
// border: 1px solid $text-color-muted;
// border-radius: 2px;
.event-timestamp {
font-weight: 500;
color: $text-color-muted;
}
} }
svg.event-timeline-canvas { svg.event-timeline-canvas {
height: 40px; height: 40px;
margin-top: 1.6rem;
g.event-timeline-group { g.event-timeline-group {
height: 40px; height: 40px;