From 56410384b2eadba3c481c8ddde94bac94926cc78 Mon Sep 17 00:00:00 2001
From: csirius <85753828+csirius@users.noreply.github.com>
Date: Fri, 24 Sep 2021 12:34:19 -0400
Subject: [PATCH] feat: add popover for bar chart item hover state
Signed-off-by: csirius <85753828+csirius@users.noreply.github.com>
---
.../Entities/EntityExecutionsBarChart.tsx | 40 +++++++++--
src/components/common/BarChart.tsx | 70 +++++++++++++++++--
2 files changed, 97 insertions(+), 13 deletions(-)
diff --git a/src/components/Entities/EntityExecutionsBarChart.tsx b/src/components/Entities/EntityExecutionsBarChart.tsx
index 2825cd6e7..b43103059 100644
--- a/src/components/Entities/EntityExecutionsBarChart.tsx
+++ b/src/components/Entities/EntityExecutionsBarChart.tsx
@@ -1,21 +1,23 @@
+import * as React from 'react';
import Typography from '@material-ui/core/Typography';
import { makeStyles, Theme } from '@material-ui/core/styles';
+import { formatDateUTC, millisecondsToHMS } from 'common/formatters';
+import { timestampToDate } from 'common/utils';
+import { BarChart } from 'components/common/BarChart';
import { WaitForData } from 'components/common/WaitForData';
import { useWorkflowExecutionFiltersState } from 'components/Executions/filters/useExecutionFiltersState';
import { useWorkflowExecutions } from 'components/hooks/useWorkflowExecutions';
import { SortDirection } from 'models/AdminEntity/types';
import { ResourceIdentifier } from 'models/Common/types';
-import { Execution } from 'models/Execution/types';
+import { Execution, WorkflowExecutionIdentifier } from 'models/Execution/types';
import { executionSortFields } from 'models/Execution/constants';
-import * as React from 'react';
+import { Routes } from 'routes/routes';
+import { history } from 'routes/history';
import { executionFilterGenerator } from './generators';
-import { BarChart } from 'components/common/BarChart';
import {
getWorkflowExecutionPhaseConstants,
getWorkflowExecutionTimingMS
} from '../Executions/utils';
-import { formatDateUTC } from 'common/formatters';
-import { timestampToDate } from 'common/utils';
const useStyles = makeStyles((theme: Theme) => ({
header: {
@@ -34,10 +36,26 @@ export interface EntityExecutionsBarChartProps {
const getExecutionTimeData = (exectuions: Execution[], fillSize = 100) => {
const newExecutions = exectuions.map(execution => {
+ const duration = getWorkflowExecutionTimingMS(execution)?.duration || 1;
return {
- value: getWorkflowExecutionTimingMS(execution)?.duration || 1,
+ value: duration,
color: getWorkflowExecutionPhaseConstants(execution.closure.phase)
- .badgeColor
+ .badgeColor,
+ metadata: execution.id,
+ tooltip: (
+
+
+ Execution Id: {execution.id.name}
+
+ Running time: {millisecondsToHMS(duration)}
+
+ Started at:{' '}
+ {formatDateUTC(
+ timestampToDate(execution.closure.startedAt!)
+ )}
+
+
+ )
};
});
if (newExecutions.length >= fillSize) {
@@ -88,6 +106,13 @@ export const EntityExecutionsBarChart: React.FC =
}
);
+ const handleClickItem = React.useCallback(item => {
+ if (item.metadata) {
+ // const executionId = item.metadata as WorkflowExecutionIdentifier;
+ // history.push(Routes.ExecutionDetails.makeUrl(executionId));
+ }
+ }, []);
+
/** Don't render component until finish fetching user profile */
if (filtersState.filters[4].status !== 'LOADED') {
return null;
@@ -102,6 +127,7 @@ export const EntityExecutionsBarChart: React.FC =
diff --git a/src/components/common/BarChart.tsx b/src/components/common/BarChart.tsx
index 5a068f5ed..73b4abc55 100644
--- a/src/components/common/BarChart.tsx
+++ b/src/components/common/BarChart.tsx
@@ -2,6 +2,7 @@ import * as React from 'react';
import { makeStyles, Theme } from '@material-ui/core/styles';
import { smallFontSize } from 'components/Theme/constants';
import { COLOR_SPECTRUM } from 'components/Theme/colorSpectrum';
+import { Tooltip, Zoom } from '@material-ui/core';
const useStyles = makeStyles((theme: Theme) => ({
container: {
@@ -43,11 +44,18 @@ const useStyles = makeStyles((theme: Theme) => ({
interface BarChartData {
value: number;
color: string;
+ metadata?: any;
+ tooltip?: string;
+}
+
+interface BarChartItemProps extends BarChartData {
+ onClick?: () => void;
}
interface BarChartProps {
data: BarChartData[];
startDate?: string;
+ onClickItem?: (item: any) => void;
}
/**
@@ -56,15 +64,50 @@ interface BarChartProps {
* @param color
* @constructor
*/
-const BarChartItem: React.FC = ({ value, color }) => {
+const BarChartItem: React.FC = ({
+ value,
+ color,
+ tooltip,
+ onClick
+}) => {
const styles = useStyles();
+ const [position, setPosition] = React.useState({ x: 0, y: 0 });
+
+ const content = (
+
+ );
return (
-
+ {tooltip ? (
+
setPosition({ x: e.pageX, y: e.pageY })}
+ PopperProps={{
+ anchorEl: {
+ clientHeight: 0,
+ clientWidth: 0,
+ getBoundingClientRect: () => ({
+ top: position.y,
+ left: position.x,
+ right: position.x,
+ bottom: position.y,
+ width: 0,
+ height: 0
+ })
+ }
+ }}
+ >
+ {content}
+
+ ) : (
+ content
+ )}
);
};
@@ -75,13 +118,26 @@ const BarChartItem: React.FC = ({ value, color }) => {
* @param startDate
* @constructor
*/
-export const BarChart: React.FC = ({ data, startDate }) => {
+export const BarChart: React.FC = ({
+ data,
+ startDate,
+ onClickItem
+}) => {
const styles = useStyles();
const maxHeight = React.useMemo(() => {
return Math.max(...data.map(x => Math.log2(x.value)));
}, [data]);
+ const handleClickItem = React.useCallback(
+ item => () => {
+ if (onClickItem) {
+ onClickItem(item);
+ }
+ },
+ [onClickItem]
+ );
+
return (
@@ -93,6 +149,8 @@ export const BarChart: React.FC = ({ data, startDate }) => {
))}