problem timeline: show event info
This commit is contained in:
@@ -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 });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user