Browse Source

[attu metric] data about node failed

Signed-off-by: min.tian <min.tian.cn@gmail.com>
min.tian 2 years ago
parent
commit
c31022f697

+ 4 - 2
client/package.json

@@ -14,6 +14,7 @@
     "@material-ui/pickers": "^3.3.10",
     "@material-ui/pickers": "^3.3.10",
     "@mui/x-data-grid": "^4.0.0",
     "@mui/x-data-grid": "^4.0.0",
     "axios": "^0.21.3",
     "axios": "^0.21.3",
+    "d3": "^7.8.2",
     "dayjs": "^1.10.5",
     "dayjs": "^1.10.5",
     "file-saver": "^2.0.5",
     "file-saver": "^2.0.5",
     "i18next": "^20.3.1",
     "i18next": "^20.3.1",
@@ -31,12 +32,11 @@
     "web-vitals": "^1.0.1"
     "web-vitals": "^1.0.1"
   },
   },
   "devDependencies": {
   "devDependencies": {
-    "@vitejs/plugin-react": "^2.2.0",
-    "@vitejs/plugin-react-refresh": "^1.3.6",
     "@testing-library/jest-dom": "^5.16.5",
     "@testing-library/jest-dom": "^5.16.5",
     "@testing-library/react": "12.1.2",
     "@testing-library/react": "12.1.2",
     "@testing-library/react-hooks": "^7.0.1",
     "@testing-library/react-hooks": "^7.0.1",
     "@testing-library/user-event": "^12.1.10",
     "@testing-library/user-event": "^12.1.10",
+    "@types/d3": "^7.4.0",
     "@types/file-saver": "^2.0.4",
     "@types/file-saver": "^2.0.4",
     "@types/loadable__component": "^5.13.4",
     "@types/loadable__component": "^5.13.4",
     "@types/node": "^12.0.0",
     "@types/node": "^12.0.0",
@@ -47,6 +47,8 @@
     "@types/react-router-dom": "^5.3.3",
     "@types/react-router-dom": "^5.3.3",
     "@types/react-syntax-highlighter": "^13.5.2",
     "@types/react-syntax-highlighter": "^13.5.2",
     "@types/webpack-env": "^1.16.3",
     "@types/webpack-env": "^1.16.3",
+    "@vitejs/plugin-react": "^2.2.0",
+    "@vitejs/plugin-react-refresh": "^1.3.6",
     "@vitest/coverage-c8": "^0.25.0",
     "@vitest/coverage-c8": "^0.25.0",
     "jsdom": "^20.0.2",
     "jsdom": "^20.0.2",
     "prettier": "2.3.2",
     "prettier": "2.3.2",

+ 2 - 2
client/src/http/Prometheus.ts

@@ -31,11 +31,11 @@ export class PrometheusHttp extends BaseModel {
   }: {
   }: {
     start: number;
     start: number;
     end: number;
     end: number;
-    step: string;
+    step: number;
   }) {
   }) {
     return super.search({
     return super.search({
       path: PrometheusHttp.GET_MILVUS_HEALTHY_DATA_URL,
       path: PrometheusHttp.GET_MILVUS_HEALTHY_DATA_URL,
-      params: { start, end, step },
+      params: { start: 1675997400000, end: 1675998480000, step: 180000 },
     });
     });
   }
   }
 }
 }

+ 5 - 0
client/src/pages/systemHealthy/HealthyIndexDetailView.tsx

@@ -0,0 +1,5 @@
+const ThresholdPanel = () => {
+  return <div></div>;
+};
+
+export default ThresholdPanel;

+ 5 - 0
client/src/pages/systemHealthy/HealthyIndexOverview.tsx

@@ -0,0 +1,5 @@
+const ThresholdPanel = () => {
+  return <div></div>;
+};
+
+export default ThresholdPanel;

+ 15 - 0
client/src/pages/systemHealthy/HealthyIndexRow.tsx

@@ -0,0 +1,15 @@
+import { EHealthyStatus } from './Types';
+
+const HealthyIndexRow = ({
+  statusList,
+  width,
+  height,
+}: {
+  statusList: EHealthyStatus[];
+  width: number;
+  height: number;
+}) => {
+  return <div></div>;
+};
+
+export default HealthyIndexRow;

+ 11 - 0
client/src/pages/systemHealthy/LineChartLarge.tsx

@@ -0,0 +1,11 @@
+const LineChartLarge = ({
+  data,
+  format = d => d,
+}: {
+  data: number[];
+  format?: (d: any) => string;
+}) => {
+  return <div></div>;
+};
+
+export default LineChartLarge;

+ 11 - 0
client/src/pages/systemHealthy/LineChartSmall.tsx

@@ -0,0 +1,11 @@
+const LineChartSmall = ({
+  data,
+  format = d => d,
+}: {
+  data: number[];
+  format?: (d: any) => string;
+}) => {
+  return <div></div>;
+};
+
+export default LineChartSmall;

+ 160 - 12
client/src/pages/systemHealthy/SystemHealthyView.tsx

@@ -1,50 +1,111 @@
+import { makeStyles, Theme } from '@material-ui/core';
 import { useEffect, useState } from 'react';
 import { useEffect, useState } from 'react';
 import { useNavigationHook } from '../../hooks/Navigation';
 import { useNavigationHook } from '../../hooks/Navigation';
 import { useInterval } from '../../hooks/SystemView';
 import { useInterval } from '../../hooks/SystemView';
 import { PrometheusHttp } from '../../http/Prometheus';
 import { PrometheusHttp } from '../../http/Prometheus';
 import { ALL_ROUTER_TYPES } from '../../router/Types';
 import { ALL_ROUTER_TYPES } from '../../router/Types';
+import {
+  EHealthyStatus,
+  ENodeService,
+  ENodeType,
+  INodeTreeStructure,
+  IPrometheusAllData,
+  IThreshold,
+  ITimeRangeOption,
+} from './Types';
+import clsx from 'clsx';
+import Topology from './Topology';
+import * as d3 from 'd3';
+// import data from "./data.json";
 
 
-interface ITimeRangeOption {
-  label: string;
-  value: number;
-  step: string;
-}
+const getStyles = makeStyles((theme: Theme) => ({
+  root: {
+    fontFamily: 'Roboto',
+    margin: '14px 40px',
+    position: 'relative',
+    height: 'fit-content',
+    display: 'flex',
+    flexDirection: 'column',
+    border: '1px solid red',
+  },
+  mainView: {
+    borderRadius: '8px',
+    boxShadow: '3px 3px 10px rgba(0, 0, 0, 0.05)',
+    display: 'grid',
+    gridTemplateColumns: '1fr auto',
+    marginTop: '14px',
+    height: '100%',
+    border: '1px solid green',
+  },
+  detailView: {
+    height: '100%',
+    width: '100%',
+    transition: 'all .25s',
+    position: 'absolute',
+    border: '1px solid purple',
+  },
+  showDetailView: {
+    top: 0,
+    minHeight: '100%',
+    height: 'fit-content',
+  },
+  hideDetailView: {
+    top: '2000px',
+    maxHeight: 0,
+  },
+}));
+
+const THIRD_PARTY_SERVICE_HEALTHY_THRESHOLD = 0.95;
+const getThirdPartyServiceHealthyStatus = (rate: number) =>
+  rate > THIRD_PARTY_SERVICE_HEALTHY_THRESHOLD
+    ? EHealthyStatus.healthy
+    : EHealthyStatus.failed;
+const rateList2healthyStatus = (rateList: number[]) =>
+  rateList.map((rate: number) => getThirdPartyServiceHealthyStatus(rate));
 
 
 const SystemHealthyView = () => {
 const SystemHealthyView = () => {
   useNavigationHook(ALL_ROUTER_TYPES.SYSTEM);
   useNavigationHook(ALL_ROUTER_TYPES.SYSTEM);
 
 
+  const classes = getStyles();
+
   const INTERVAL = 60000;
   const INTERVAL = 60000;
   const timeRangeOptions: ITimeRangeOption[] = [
   const timeRangeOptions: ITimeRangeOption[] = [
     {
     {
       label: '1h',
       label: '1h',
       value: 60 * 60 * 1000,
       value: 60 * 60 * 1000,
-      step: '3m',
+      step: 3 * 60 * 1000,
     },
     },
     {
     {
       label: '24h',
       label: '24h',
       value: 24 * 60 * 60 * 1000,
       value: 24 * 60 * 60 * 1000,
-      step: '60m',
+      step: 60 * 60 * 1000,
     },
     },
     {
     {
       label: '7d',
       label: '7d',
       value: 7 * 24 * 60 * 60 * 1000,
       value: 7 * 24 * 60 * 60 * 1000,
-      step: '8h',
+      step: 8 * 60 * 60 * 100,
     },
     },
   ];
   ];
   const [timeRange, setTimeRange] = useState<ITimeRangeOption>(
   const [timeRange, setTimeRange] = useState<ITimeRangeOption>(
     timeRangeOptions[0]
     timeRangeOptions[0]
   );
   );
-  const [nodes, setNodes] = useState<any>();
+  const [prometheusData, setPrometheusData] = useState<any>();
+  const [selectedNode, setSelectedNode] = useState<string>('');
+  const defaultThresholds = {
+    cpu: 1,
+    memory: 8,
+  };
+  const [threshold, setThreshold] = useState<IThreshold>(defaultThresholds);
 
 
   const updateData = async () => {
   const updateData = async () => {
     const curT = new Date().getTime();
     const curT = new Date().getTime();
-    const result: any = await PrometheusHttp.getHealthyData({
+    const result = await PrometheusHttp.getHealthyData({
       start: curT - timeRange.value,
       start: curT - timeRange.value,
       end: curT,
       end: curT,
       step: timeRange.step,
       step: timeRange.step,
     });
     });
     console.log(result);
     console.log(result);
-    setNodes(result.data);
+    setPrometheusData(result.data as IPrometheusAllData);
   };
   };
 
 
   useEffect(() => {
   useEffect(() => {
@@ -56,7 +117,94 @@ const SystemHealthyView = () => {
     updateData();
     updateData();
   }, INTERVAL);
   }, INTERVAL);
 
 
-  return <div></div>;
+  const reconNodeTree = (
+    prometheusData: IPrometheusAllData,
+    threshold: IThreshold
+  ) => {
+    const length = prometheusData.meta.length;
+
+    // third party
+    const metaNode: INodeTreeStructure = {
+      service: ENodeService.meta,
+      type: ENodeType.overview,
+      label: 'Meta',
+      healthyStatus: rateList2healthyStatus(prometheusData.meta),
+      children: [],
+    };
+    const msgstreamNode: INodeTreeStructure = {
+      service: ENodeService.msgstream,
+      type: ENodeType.overview,
+      label: 'MsgStream',
+      healthyStatus: rateList2healthyStatus(prometheusData.msgstream),
+      children: [],
+    };
+    const objstorageNode: INodeTreeStructure = {
+      service: ENodeService.objstorage,
+      type: ENodeType.overview,
+      label: 'ObjStorage',
+      healthyStatus: rateList2healthyStatus(prometheusData.msgstream),
+      children: [],
+    };
+
+    // internal
+    const rootNode = {};
+    const indexNodes: INodeTreeStructure[] = prometheusData.indexNodes.map(
+      node => {
+        const healthyStatus = d3.range(length).map((_, i: number) => {
+          const cpu = node.cpu[i];
+          const memory = node.memory[i];
+          return cpu >= threshold.cpu || memory >= threshold.memory
+            ? EHealthyStatus.warning
+            : EHealthyStatus.healthy;
+        });
+        return {
+          service: ENodeService.index,
+          type: node.type === 'coord' ? ENodeType.coord : ENodeType.node,
+          label: node.pod,
+          healthyStatus,
+          cpu: node.cpu,
+          memory: node.memory,
+          children: [],
+        };
+      }
+    );
+    const healthyStatus = d3
+      .range(length)
+      .map((_, i: number) =>
+        indexNodes.reduce(
+          (acc, cur) => acc && cur.healthyStatus[i] === EHealthyStatus.healthy,
+          true
+        )
+          ? EHealthyStatus.healthy
+          : EHealthyStatus.warning
+      );
+    const indexNode: INodeTreeStructure = {
+      service: ENodeService.index,
+      type: ENodeType.overview,
+      label: 'Index',
+      healthyStatus,
+      children: indexNodes,
+    };
+  };
+
+  return (
+    <div className={classes.root}>
+      <div className={classes.mainView}>
+        {/* <Topology
+          tree={tree}
+          selectedNode={selectedNode}
+          setSelectedNode={setSelectedNode}
+        ></Topology> */}
+        <div style={{ height: '200px', width: '300px' }}></div>
+      </div>
+      <div
+        className={clsx(
+          classes.detailView,
+          selectedNode ? classes.showDetailView : classes.hideDetailView
+        )}
+      ></div>
+    </div>
+  );
 };
 };
 
 
 export default SystemHealthyView;
 export default SystemHealthyView;

+ 14 - 0
client/src/pages/systemHealthy/ThresholdPanel.tsx

@@ -0,0 +1,14 @@
+import { Dispatch } from 'react';
+import { ITimeRangeOption } from './Types';
+
+const ThresholdPanel = ({
+  timeRange,
+  setTimeRange,
+}: {
+  timeRange: ITimeRangeOption;
+  setTimeRange: Dispatch<ITimeRangeOption>;
+}) => {
+  return <div></div>;
+};
+
+export default ThresholdPanel;

+ 16 - 0
client/src/pages/systemHealthy/Topology.tsx

@@ -0,0 +1,16 @@
+import { Dispatch } from 'react';
+import { INodeTreeStructure } from './Types';
+
+const Topology = ({
+  tree,
+  selectedNode,
+  setSelectedNode,
+}: {
+  tree: INodeTreeStructure;
+  selectedNode: string;
+  setSelectedNode: Dispatch<string>;
+}) => {
+  return <div></div>;
+};
+
+export default Topology;

+ 66 - 0
client/src/pages/systemHealthy/Types.ts

@@ -0,0 +1,66 @@
+export interface ITimeRangeOption {
+  label: string;
+  value: number;
+  step: number;
+}
+
+export enum ENodeType {
+  overview = 0,
+  coord,
+  node,
+}
+
+export enum ENodeService {
+  milvus = 0,
+  meta,
+  msgstream,
+  objstorage,
+  root,
+  query,
+  index,
+  node,
+}
+
+export interface INodeTreeStructure {
+  service: ENodeService;
+  type: ENodeType;
+  label: string;
+  healthyStatus: EHealthyStatus[];
+  cpu?: number[];
+  memory?: number[];
+  children: INodeTreeStructure[];
+}
+
+export enum EHealthyStatus {
+  healthy = 0,
+  warning,
+  failed,
+}
+
+export interface IPrometheusNode {
+  type: string;
+  pod: string;
+  cpu: number[];
+  memory: number[];
+}
+
+export interface IPrometheusAllData {
+  totalVectorsCount: number[];
+  searchVectorsCount: number[];
+  searchFailedVectorsCount?: number[];
+  sqLatency: number[];
+
+  meta: number[];
+  msgstream: number[];
+  objstorage: number[];
+
+  rootNodes: IPrometheusNode[];
+  queryNodes: IPrometheusNode[];
+  indexNodes: IPrometheusNode[];
+  dataNodes: IPrometheusNode[];
+}
+
+export interface IThreshold {
+  cpu: number;
+  memory: number;
+}

+ 193 - 0
client/src/pages/systemHealthy/data.json

@@ -0,0 +1,193 @@
+{
+  "totalVectorsCount": [
+    10100, 10100, 10100, 10100, 10100, 10100, 10100, 10100, 10100, 10100, 10100,
+    10100, 10100, 10100, 10100, 10100, 10100, 10100, 10100, 10100
+  ],
+  "searchVectorsCount": [
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+    34
+  ],
+  "sqLatency": [],
+  "meta": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
+  "msgstream": [
+    1, 1, 0.9998114274938714, 1.0001883593897156, 0.9998144712430427,
+    1.000185253797703, 0.9996274911529148, 1.0003825554705432, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1
+  ],
+  "objstorage": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
+  "rootNodes": [
+    {
+      "label": "coord",
+      "pod": "tianmin-milvus-rootcoord-66bb975f6d-jxx6s",
+      "cpu": [
+        3876.64, 3879.11, 3881.62, 3884.09, 3886.6, 3888.98, 3891.4, 3893.85,
+        3896.26, 3898.77, 3901.44, 3903.94, 3906.56, 3909.19, 3911.84, 3914.49,
+        3917.18, 3919.78, 3922.32, 3924.86, 3927.39
+      ],
+      "memory": [
+        256598016, 256598016, 256598016, 256598016, 256598016, 256598016,
+        256598016, 256598016, 256598016, 256598016, 256598016, 256598016,
+        256598016, 256598016, 256598016, 256598016, 256598016, 256598016,
+        256598016, 256598016, 256598016
+      ]
+    }
+  ],
+  "queryNodes": [
+    {
+      "label": "coord",
+      "pod": "tianmin-milvus-querycoord-d779dfdd4-njjp5",
+      "cpu": [
+        0.004666666666666212, 0.004444444444444192, 0.004333333333333181,
+        0.00438888888888995, 0.004166666666666667, 0.004444444444444192,
+        0.004555555555555202, 0.004444444444444192, 0.0042777777777776764,
+        0.0042777777777776764, 0.004111111111111162, 0.004000000000000152,
+        0.0042222222222221715, 0.0042222222222221715, 0.0042222222222221715,
+        0.004166666666666667, 0.0042777777777776764, 0.004444444444445455,
+        0.004666666666666212, 0.004555555555555202
+      ],
+      "memory": [
+        197791744, 198955008, 197935104, 195383296, 196513792, 199458816,
+        200470528, 199585792, 200290304, 196591616, 195936256, 196235264,
+        199966720, 200216576, 194682880, 196231168, 199692288, 196538368,
+        196132864, 198537216
+      ]
+    },
+    {
+      "label": "node",
+      "pod": "tianmin-milvus-querynode-68866999f4-t8wtz",
+      "cpu": [
+        0.007833333333335052, 0.007555555555553737, 0.007833333333335052,
+        0.007888888888889294, 0.007666666666664747, 0.007555555555556263,
+        0.007444444444445253, 0.0073333333333317164, 0.008277777777779091,
+        0.009222222222221414, 0.008444444444444343, 0.008722222222223132,
+        0.008999999999999394, 0.008722222222223132, 0.008833333333331615,
+        0.009166666666667172, 0.008944444444445152, 0.008611111111112122,
+        0.008722222222220605, 0.008277777777779091
+      ],
+      "memory": [
+        227799040, 227799040, 227799040, 227799040, 227799040, 227799040,
+        227799040, 227799040, 227799040, 227799040, 227799040, 227799040,
+        227799040, 227799040, 227799040, 227799040, 227799040, 227799040,
+        227799040, 227799040
+      ]
+    },
+    {
+      "label": "node",
+      "pod": "tianmin-milvus-querynode-68866999f4-ftmql",
+      "cpu": [
+        0.007888888888889294, 0.007666666666667273, 0.007333333333332979,
+        0.007499999999999495, 0.007333333333334243, 0.00788888888888803,
+        0.007722222222222778, 0.007499999999999495, 0.007166666666666465,
+        0.007055555555556718, 0.00699999999999995, 0.00711111111111096,
+        0.00744444444444399, 0.007055555555555455, 0.0072222222222219695,
+        0.007333333333334243, 0.007499999999999495, 0.007277777777777474,
+        0.007944444444444799, 0.00766666666666601
+      ],
+      "memory": [
+        240599040, 240599040, 240599040, 240599040, 240599040, 240599040,
+        240599040, 240599040, 240599040, 240599040, 240599040, 240599040,
+        240599040, 240599040, 240599040, 240599040, 240599040, 240599040,
+        240599040, 240599040
+      ]
+    }
+  ],
+  "indexNodes": [
+    {
+      "label": "coord",
+      "pod": "tianmin-milvus-indexcoord-864d49b47f-t7w4k",
+      "cpu": [
+        0.0009444444444445328, 0.0010555555555555429, 0.000888888888888712,
+        0.001000000000000038, 0.0009444444444445328, 0.001000000000000038,
+        0.0010555555555555429, 0.0010555555555555429, 0.0008888888888890278,
+        0.000999999999999722, 0.0009444444444445328, 0.001000000000000038,
+        0.0009444444444445328, 0.0010555555555555429, 0.0009444444444445328,
+        0.0010555555555555429, 0.0009444444444442171, 0.001000000000000038,
+        0.001000000000000038, 0.0010555555555555429
+      ],
+      "memory": [
+        179040256, 179040256, 179068928, 179068928, 179068928, 179326976,
+        179339264, 179339264, 179339264, 179339264, 179343360, 179343360,
+        179363840, 179372032, 179372032, 179372032, 179372032, 179372032,
+        179372032, 179372032
+      ]
+    },
+    {
+      "label": "node",
+      "pod": "tianmin-milvus-indexnode-6cdc5f745b-j5ttn",
+      "cpu": [
+        0.0007222222222221969, 0.0007222222222221969, 0.0007222222222221969,
+        0.0006666666666666919, 0.0007222222222221969, 0.0007222222222221969,
+        0.0006666666666666919, 0.0007222222222221969, 0.0007222222222223549,
+        0.000611111111111029, 0.0006666666666666919, 0.0007222222222221969,
+        0.0007222222222221969, 0.0006666666666666919, 0.0007222222222221969,
+        0.0006666666666666919, 0.0006666666666666919, 0.000777777777777702,
+        0.0007777777777778599, 0.0007222222222221969
+      ],
+      "memory": [
+        1076543488, 1076543488, 1076543488, 1075888128, 1075888128, 1075888128,
+        1075888128, 1075888128, 1075888128, 1075888128, 1075888128, 1075892224,
+        1075892224, 1075896320, 1075896320, 1075896320, 1076625408, 1076625408,
+        1076625408, 1076625408
+      ]
+    }
+  ],
+  "dataNodes": [
+    {
+      "label": "coord",
+      "pod": "tianmin-milvus-datacoord-bb57486b-w29cx",
+      "cpu": [
+        0.0036666666666671215, 0.0038333333333323734, 0.0037777777777781314,
+        0.0037777777777781314, 0.0036666666666658582, 0.004166666666666667,
+        0.0038333333333336367, 0.0037222222222226264, 0.0038888888888891416,
+        0.003722222222221363, 0.004000000000000152, 0.0035000000000006064,
+        0.0038333333333323734, 0.0038888888888891416, 0.0037222222222226264,
+        0.0037222222222226264, 0.003944444444443383, 0.0035555555555561113,
+        0.0038333333333336367, 0.003722222222221363
+      ],
+      "memory": [
+        206331904, 207470592, 207720448, 207720448, 208060416, 205582336,
+        202395648, 205864960, 206917632, 206917632, 205361152, 204087296,
+        203841536, 209223680, 210296832, 210321408, 210554880, 208400384,
+        208814080, 208814080
+      ]
+    },
+    {
+      "label": "node",
+      "pod": "tianmin-milvus-datanode-7b759b9697-snqqx",
+      "cpu": [
+        0.005777777777778839, 0.005999999999999596, 0.005888888888888586,
+        0.0057222222222220705, 0.005944444444445354, 0.006166666666666111,
+        0.005944444444444091, 0.005666666666666566, 0.005777777777777575,
+        0.005444444444444545, 0.00527777777777803, 0.00527777777777803,
+        0.00527777777777803, 0.00538888888888904, 0.005611111111111061,
+        0.005555555555555556, 0.005500000000000051, 0.0052777777777767675,
+        0.005555555555555556, 0.005333333333333535
+      ],
+      "memory": [
+        233603072, 233603072, 233603072, 233603072, 233603072, 233603072,
+        233603072, 233603072, 233603072, 233603072, 233603072, 233603072,
+        233603072, 233603072, 233603072, 233603072, 233603072, 233603072,
+        233603072, 233603072
+      ]
+    },
+    {
+      "label": "node",
+      "pod": "tianmin-milvus-datanode-7b759b9697-hzd9w",
+      "cpu": [
+        0.006111111111110606, 0.006000000000000859, 0.006166666666666111,
+        0.005888888888888586, 0.005888888888889849, 0.0062777777777771205,
+        0.006055555555555101, 0.005777777777778839, 0.005611111111111061,
+        0.005444444444444545, 0.005388888888887777, 0.00527777777777803,
+        0.005333333333333535, 0.0057222222222220705, 0.005666666666666566,
+        0.005666666666666566, 0.005555555555555556, 0.00527777777777803,
+        0.006277777777778384, 0.006333333333332626
+      ],
+      "memory": [
+        223911936, 223911936, 223911936, 223911936, 223911936, 223911936,
+        223911936, 223911936, 223911936, 223911936, 223911936, 223911936,
+        223911936, 223911936, 223911936, 223911936, 223911936, 223911936,
+        223911936, 223911936
+      ]
+    }
+  ]
+}

+ 487 - 1
client/yarn.lock

@@ -872,11 +872,226 @@
   resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.3.tgz#3c90752792660c4b562ad73b3fbd68bf3bc7ae07"
   resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.3.tgz#3c90752792660c4b562ad73b3fbd68bf3bc7ae07"
   integrity sha512-hC7OMnszpxhZPduX+m+nrx+uFoLkWOMiR4oa/AZF3MuSETYTZmFfJAHqZEM8MVlvfG7BEUcgvtwoCTxBp6hm3g==
   integrity sha512-hC7OMnszpxhZPduX+m+nrx+uFoLkWOMiR4oa/AZF3MuSETYTZmFfJAHqZEM8MVlvfG7BEUcgvtwoCTxBp6hm3g==
 
 
+"@types/d3-array@*":
+  version "3.0.4"
+  resolved "https://registry.npmmirror.com/@types/d3-array/-/d3-array-3.0.4.tgz#44eebe40be57476cad6a0cd6a85b0f57d54185a2"
+  integrity sha512-nwvEkG9vYOc0Ic7G7kwgviY4AQlTfYGIZ0fqB7CQHXGyYM6nO7kJh5EguSNA3jfh4rq7Sb7eMVq8isuvg2/miQ==
+
+"@types/d3-axis@*":
+  version "3.0.2"
+  resolved "https://registry.npmmirror.com/@types/d3-axis/-/d3-axis-3.0.2.tgz#96e11d51256baf5bdb2fa73a17d302993e79df07"
+  integrity sha512-uGC7DBh0TZrU/LY43Fd8Qr+2ja1FKmH07q2FoZFHo1eYl8aj87GhfVoY1saJVJiq24rp1+wpI6BvQJMKgQm8oA==
+  dependencies:
+    "@types/d3-selection" "*"
+
+"@types/d3-brush@*":
+  version "3.0.2"
+  resolved "https://registry.npmmirror.com/@types/d3-brush/-/d3-brush-3.0.2.tgz#a610aad5a1e76c375be63e11c5eee1ed9fd2fb40"
+  integrity sha512-2TEm8KzUG3N7z0TrSKPmbxByBx54M+S9lHoP2J55QuLU0VSQ9mE96EJSAOVNEqd1bbynMjeTS9VHmz8/bSw8rA==
+  dependencies:
+    "@types/d3-selection" "*"
+
+"@types/d3-chord@*":
+  version "3.0.2"
+  resolved "https://registry.npmmirror.com/@types/d3-chord/-/d3-chord-3.0.2.tgz#cf6f05ad2d8faaad524e9e6f454b4fd06b200930"
+  integrity sha512-abT/iLHD3sGZwqMTX1TYCMEulr+wBd0SzyOQnjYNLp7sngdOHYtNkMRI5v3w5thoN+BWtlHVDx2Osvq6fxhZWw==
+
+"@types/d3-color@*":
+  version "3.1.0"
+  resolved "https://registry.npmmirror.com/@types/d3-color/-/d3-color-3.1.0.tgz#6594da178ded6c7c3842f3cc0ac84b156f12f2d4"
+  integrity sha512-HKuicPHJuvPgCD+np6Se9MQvS6OCbJmOjGvylzMJRlDwUXjKTTXs6Pwgk79O09Vj/ho3u1ofXnhFOaEWWPrlwA==
+
+"@types/d3-contour@*":
+  version "3.0.2"
+  resolved "https://registry.npmmirror.com/@types/d3-contour/-/d3-contour-3.0.2.tgz#d8a0e4d12ec14f7d2bb6e59f3fbc1a527457d0b2"
+  integrity sha512-k6/bGDoAGJZnZWaKzeB+9glgXCYGvh6YlluxzBREiVo8f/X2vpTEdgPy9DN7Z2i42PZOZ4JDhVdlTSTSkLDPlQ==
+  dependencies:
+    "@types/d3-array" "*"
+    "@types/geojson" "*"
+
+"@types/d3-delaunay@*":
+  version "6.0.1"
+  resolved "https://registry.npmmirror.com/@types/d3-delaunay/-/d3-delaunay-6.0.1.tgz#006b7bd838baec1511270cb900bf4fc377bbbf41"
+  integrity sha512-tLxQ2sfT0p6sxdG75c6f/ekqxjyYR0+LwPrsO1mbC9YDBzPJhs2HbJJRrn8Ez1DBoHRo2yx7YEATI+8V1nGMnQ==
+
+"@types/d3-dispatch@*":
+  version "3.0.2"
+  resolved "https://registry.npmmirror.com/@types/d3-dispatch/-/d3-dispatch-3.0.2.tgz#b2fa80bab3bcead68680766e966f59cd6cb9a69f"
+  integrity sha512-rxN6sHUXEZYCKV05MEh4z4WpPSqIw+aP7n9ZN6WYAAvZoEAghEK1WeVZMZcHRBwyaKflU43PCUAJNjFxCzPDjg==
+
+"@types/d3-drag@*":
+  version "3.0.2"
+  resolved "https://registry.npmmirror.com/@types/d3-drag/-/d3-drag-3.0.2.tgz#5562da3e7b33d782c2c1f9e65c5e91bb01ee82cf"
+  integrity sha512-qmODKEDvyKWVHcWWCOVcuVcOwikLVsyc4q4EBJMREsoQnR2Qoc2cZQUyFUPgO9q4S3qdSqJKBsuefv+h0Qy+tw==
+  dependencies:
+    "@types/d3-selection" "*"
+
+"@types/d3-dsv@*":
+  version "3.0.1"
+  resolved "https://registry.npmmirror.com/@types/d3-dsv/-/d3-dsv-3.0.1.tgz#c51a3505cee42653454b74a00f8713dc3548c362"
+  integrity sha512-76pBHCMTvPLt44wFOieouXcGXWOF0AJCceUvaFkxSZEu4VDUdv93JfpMa6VGNFs01FHfuP4a5Ou68eRG1KBfTw==
+
+"@types/d3-ease@*":
+  version "3.0.0"
+  resolved "https://registry.npmmirror.com/@types/d3-ease/-/d3-ease-3.0.0.tgz#c29926f8b596f9dadaeca062a32a45365681eae0"
+  integrity sha512-aMo4eaAOijJjA6uU+GIeW018dvy9+oH5Y2VPPzjjfxevvGQ/oRDs+tfYC9b50Q4BygRR8yE2QCLsrT0WtAVseA==
+
+"@types/d3-fetch@*":
+  version "3.0.2"
+  resolved "https://registry.npmmirror.com/@types/d3-fetch/-/d3-fetch-3.0.2.tgz#fe1f335243e07c9bd520c9a71756fed8330c54b1"
+  integrity sha512-gllwYWozWfbep16N9fByNBDTkJW/SyhH6SGRlXloR7WdtAaBui4plTP+gbUgiEot7vGw/ZZop1yDZlgXXSuzjA==
+  dependencies:
+    "@types/d3-dsv" "*"
+
+"@types/d3-force@*":
+  version "3.0.4"
+  resolved "https://registry.npmmirror.com/@types/d3-force/-/d3-force-3.0.4.tgz#2d50bd2b695f709797e1745644f6bc123e6e5f5a"
+  integrity sha512-q7xbVLrWcXvSBBEoadowIUJ7sRpS1yvgMWnzHJggFy5cUZBq2HZL5k/pBSm0GdYWS1vs5/EDwMjSKF55PDY4Aw==
+
+"@types/d3-format@*":
+  version "3.0.1"
+  resolved "https://registry.npmmirror.com/@types/d3-format/-/d3-format-3.0.1.tgz#194f1317a499edd7e58766f96735bdc0216bb89d"
+  integrity sha512-5KY70ifCCzorkLuIkDe0Z9YTf9RR2CjBX1iaJG+rgM/cPP+sO+q9YdQ9WdhQcgPj1EQiJ2/0+yUkkziTG6Lubg==
+
+"@types/d3-geo@*":
+  version "3.0.3"
+  resolved "https://registry.npmmirror.com/@types/d3-geo/-/d3-geo-3.0.3.tgz#535e5f24be13722964c52354301be09b752f5d6e"
+  integrity sha512-bK9uZJS3vuDCNeeXQ4z3u0E7OeJZXjUgzFdSOtNtMCJCLvDtWDwfpRVWlyt3y8EvRzI0ccOu9xlMVirawolSCw==
+  dependencies:
+    "@types/geojson" "*"
+
+"@types/d3-hierarchy@*":
+  version "3.1.2"
+  resolved "https://registry.npmmirror.com/@types/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz#b3a446b5437faededb30ac32b7cc0486559ab1e2"
+  integrity sha512-9hjRTVoZjRFR6xo8igAJyNXQyPX6Aq++Nhb5ebrUF414dv4jr2MitM2fWiOY475wa3Za7TOS2Gh9fmqEhLTt0A==
+
+"@types/d3-interpolate@*":
+  version "3.0.1"
+  resolved "https://registry.npmmirror.com/@types/d3-interpolate/-/d3-interpolate-3.0.1.tgz#e7d17fa4a5830ad56fe22ce3b4fac8541a9572dc"
+  integrity sha512-jx5leotSeac3jr0RePOH1KdR9rISG91QIE4Q2PYTu4OymLTZfA3SrnURSLzKH48HmXVUru50b8nje4E79oQSQw==
+  dependencies:
+    "@types/d3-color" "*"
+
+"@types/d3-path@*":
+  version "3.0.0"
+  resolved "https://registry.npmmirror.com/@types/d3-path/-/d3-path-3.0.0.tgz#939e3a784ae4f80b1fde8098b91af1776ff1312b"
+  integrity sha512-0g/A+mZXgFkQxN3HniRDbXMN79K3CdTpLsevj+PXiTcb2hVyvkZUBg37StmgCQkaD84cUJ4uaDAWq7UJOQy2Tg==
+
+"@types/d3-polygon@*":
+  version "3.0.0"
+  resolved "https://registry.npmmirror.com/@types/d3-polygon/-/d3-polygon-3.0.0.tgz#5200a3fa793d7736fa104285fa19b0dbc2424b93"
+  integrity sha512-D49z4DyzTKXM0sGKVqiTDTYr+DHg/uxsiWDAkNrwXYuiZVd9o9wXZIo+YsHkifOiyBkmSWlEngHCQme54/hnHw==
+
+"@types/d3-quadtree@*":
+  version "3.0.2"
+  resolved "https://registry.npmmirror.com/@types/d3-quadtree/-/d3-quadtree-3.0.2.tgz#433112a178eb7df123aab2ce11c67f51cafe8ff5"
+  integrity sha512-QNcK8Jguvc8lU+4OfeNx+qnVy7c0VrDJ+CCVFS9srBo2GL9Y18CnIxBdTF3v38flrGy5s1YggcoAiu6s4fLQIw==
+
+"@types/d3-random@*":
+  version "3.0.1"
+  resolved "https://registry.npmmirror.com/@types/d3-random/-/d3-random-3.0.1.tgz#5c8d42b36cd4c80b92e5626a252f994ca6bfc953"
+  integrity sha512-IIE6YTekGczpLYo/HehAy3JGF1ty7+usI97LqraNa8IiDur+L44d0VOjAvFQWJVdZOJHukUJw+ZdZBlgeUsHOQ==
+
+"@types/d3-scale-chromatic@*":
+  version "3.0.0"
+  resolved "https://registry.npmmirror.com/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz#103124777e8cdec85b20b51fd3397c682ee1e954"
+  integrity sha512-dsoJGEIShosKVRBZB0Vo3C8nqSDqVGujJU6tPznsBJxNJNwMF8utmS83nvCBKQYPpjCzaaHcrf66iTRpZosLPw==
+
+"@types/d3-scale@*":
+  version "4.0.3"
+  resolved "https://registry.npmmirror.com/@types/d3-scale/-/d3-scale-4.0.3.tgz#7a5780e934e52b6f63ad9c24b105e33dd58102b5"
+  integrity sha512-PATBiMCpvHJSMtZAMEhc2WyL+hnzarKzI6wAHYjhsonjWJYGq5BXTzQjv4l8m2jO183/4wZ90rKvSeT7o72xNQ==
+  dependencies:
+    "@types/d3-time" "*"
+
+"@types/d3-selection@*":
+  version "3.0.4"
+  resolved "https://registry.npmmirror.com/@types/d3-selection/-/d3-selection-3.0.4.tgz#923d7f8985718116de56f55307d26e5f00728dc5"
+  integrity sha512-ZeykX7286BCyMg9sH5fIAORyCB6hcATPSRQpN47jwBA2bMbAT0s+EvtDP5r1FZYJ95R8QoEE1CKJX+n0/M5Vhg==
+
+"@types/d3-shape@*":
+  version "3.1.1"
+  resolved "https://registry.npmmirror.com/@types/d3-shape/-/d3-shape-3.1.1.tgz#15cc497751dac31192d7aef4e67a8d2c62354b95"
+  integrity sha512-6Uh86YFF7LGg4PQkuO2oG6EMBRLuW9cbavUW46zkIO5kuS2PfTqo2o9SkgtQzguBHbLgNnU90UNsITpsX1My+A==
+  dependencies:
+    "@types/d3-path" "*"
+
+"@types/d3-time-format@*":
+  version "4.0.0"
+  resolved "https://registry.npmmirror.com/@types/d3-time-format/-/d3-time-format-4.0.0.tgz#ee7b6e798f8deb2d9640675f8811d0253aaa1946"
+  integrity sha512-yjfBUe6DJBsDin2BMIulhSHmr5qNR5Pxs17+oW4DoVPyVIXZ+m6bs7j1UVKP08Emv6jRmYrYqxYzO63mQxy1rw==
+
+"@types/d3-time@*":
+  version "3.0.0"
+  resolved "https://registry.npmmirror.com/@types/d3-time/-/d3-time-3.0.0.tgz#e1ac0f3e9e195135361fa1a1d62f795d87e6e819"
+  integrity sha512-sZLCdHvBUcNby1cB6Fd3ZBrABbjz3v1Vm90nysCQ6Vt7vd6e/h9Lt7SiJUoEX0l4Dzc7P5llKyhqSi1ycSf1Hg==
+
+"@types/d3-timer@*":
+  version "3.0.0"
+  resolved "https://registry.npmmirror.com/@types/d3-timer/-/d3-timer-3.0.0.tgz#e2505f1c21ec08bda8915238e397fb71d2fc54ce"
+  integrity sha512-HNB/9GHqu7Fo8AQiugyJbv6ZxYz58wef0esl4Mv828w1ZKpAshw/uFWVDUcIB9KKFeFKoxS3cHY07FFgtTRZ1g==
+
+"@types/d3-transition@*":
+  version "3.0.3"
+  resolved "https://registry.npmmirror.com/@types/d3-transition/-/d3-transition-3.0.3.tgz#d4ac37d08703fb039c87f92851a598ba77400402"
+  integrity sha512-/S90Od8Id1wgQNvIA8iFv9jRhCiZcGhPd2qX0bKF/PS+y0W5CrXKgIiELd2CvG1mlQrWK/qlYh3VxicqG1ZvgA==
+  dependencies:
+    "@types/d3-selection" "*"
+
+"@types/d3-zoom@*":
+  version "3.0.2"
+  resolved "https://registry.npmmirror.com/@types/d3-zoom/-/d3-zoom-3.0.2.tgz#067aa6a6ecbc75a78b753cc6f7a7f9f7e4e7d117"
+  integrity sha512-t09DDJVBI6AkM7N8kuPsnq/3d/ehtRKBN1xSiYjjMCgbiw6HM6Ged5VhvswmhprfKyGvzeTEL/4WBaK9llWvlA==
+  dependencies:
+    "@types/d3-interpolate" "*"
+    "@types/d3-selection" "*"
+
+"@types/d3@^7.4.0":
+  version "7.4.0"
+  resolved "https://registry.npmmirror.com/@types/d3/-/d3-7.4.0.tgz#fc5cac5b1756fc592a3cf1f3dc881bf08225f515"
+  integrity sha512-jIfNVK0ZlxcuRDKtRS/SypEyOQ6UHaFQBKv032X45VvxSJ6Yi5G9behy9h6tNTHTDGh5Vq+KbmBjUWLgY4meCA==
+  dependencies:
+    "@types/d3-array" "*"
+    "@types/d3-axis" "*"
+    "@types/d3-brush" "*"
+    "@types/d3-chord" "*"
+    "@types/d3-color" "*"
+    "@types/d3-contour" "*"
+    "@types/d3-delaunay" "*"
+    "@types/d3-dispatch" "*"
+    "@types/d3-drag" "*"
+    "@types/d3-dsv" "*"
+    "@types/d3-ease" "*"
+    "@types/d3-fetch" "*"
+    "@types/d3-force" "*"
+    "@types/d3-format" "*"
+    "@types/d3-geo" "*"
+    "@types/d3-hierarchy" "*"
+    "@types/d3-interpolate" "*"
+    "@types/d3-path" "*"
+    "@types/d3-polygon" "*"
+    "@types/d3-quadtree" "*"
+    "@types/d3-random" "*"
+    "@types/d3-scale" "*"
+    "@types/d3-scale-chromatic" "*"
+    "@types/d3-selection" "*"
+    "@types/d3-shape" "*"
+    "@types/d3-time" "*"
+    "@types/d3-time-format" "*"
+    "@types/d3-timer" "*"
+    "@types/d3-transition" "*"
+    "@types/d3-zoom" "*"
+
 "@types/file-saver@^2.0.4":
 "@types/file-saver@^2.0.4":
   version "2.0.4"
   version "2.0.4"
   resolved "https://registry.yarnpkg.com/@types/file-saver/-/file-saver-2.0.4.tgz#aaf9b96296150d737b2fefa535ced05ed8013d84"
   resolved "https://registry.yarnpkg.com/@types/file-saver/-/file-saver-2.0.4.tgz#aaf9b96296150d737b2fefa535ced05ed8013d84"
   integrity sha512-sPZYQEIF/SOnLAvaz9lTuydniP+afBMtElRTdYkeV1QtEgvtJ7qolCPjly6O32QI8CbEmP5O/fztMXEDWfEcrg==
   integrity sha512-sPZYQEIF/SOnLAvaz9lTuydniP+afBMtElRTdYkeV1QtEgvtJ7qolCPjly6O32QI8CbEmP5O/fztMXEDWfEcrg==
 
 
+"@types/geojson@*":
+  version "7946.0.10"
+  resolved "https://registry.npmmirror.com/@types/geojson/-/geojson-7946.0.10.tgz#6dfbf5ea17142f7f9a043809f1cd4c448cb68249"
+  integrity sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA==
+
 "@types/hast@^2.0.0":
 "@types/hast@^2.0.0":
   version "2.3.4"
   version "2.3.4"
   resolved "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.4.tgz#8aa5ef92c117d20d974a82bdfb6a648b08c0bafc"
   resolved "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.4.tgz#8aa5ef92c117d20d974a82bdfb6a648b08c0bafc"
@@ -1410,6 +1625,11 @@ comma-separated-tokens@^1.0.0:
   resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz#632b80b6117867a158f1080ad498b2fbe7e3f5ea"
   resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz#632b80b6117867a158f1080ad498b2fbe7e3f5ea"
   integrity sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==
   integrity sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==
 
 
+commander@7:
+  version "7.2.0"
+  resolved "https://registry.npmmirror.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7"
+  integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==
+
 concat-map@0.0.1:
 concat-map@0.0.1:
   version "0.0.1"
   version "0.0.1"
   resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
   resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
@@ -1487,6 +1707,250 @@ csstype@^3.0.2:
   resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.9.tgz#6410af31b26bd0520933d02cbc64fce9ce3fbf0b"
   resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.9.tgz#6410af31b26bd0520933d02cbc64fce9ce3fbf0b"
   integrity sha512-rpw6JPxK6Rfg1zLOYCSwle2GFOOsnjmDYDaBwEcwoOg4qlsIVCN789VkBZDJAGi4T07gI4YSutR43t9Zz4Lzuw==
   integrity sha512-rpw6JPxK6Rfg1zLOYCSwle2GFOOsnjmDYDaBwEcwoOg4qlsIVCN789VkBZDJAGi4T07gI4YSutR43t9Zz4Lzuw==
 
 
+"d3-array@2 - 3", "d3-array@2.10.0 - 3", "d3-array@2.5.0 - 3", d3-array@3, d3-array@^3.2.0:
+  version "3.2.2"
+  resolved "https://registry.npmmirror.com/d3-array/-/d3-array-3.2.2.tgz#f8ac4705c5b06914a7e0025bbf8d5f1513f6a86e"
+  integrity sha512-yEEyEAbDrF8C6Ob2myOBLjwBLck1Z89jMGFee0oPsn95GqjerpaOA4ch+vc2l0FNFFwMD5N7OCSEN5eAlsUbgQ==
+  dependencies:
+    internmap "1 - 2"
+
+d3-axis@3:
+  version "3.0.0"
+  resolved "https://registry.npmmirror.com/d3-axis/-/d3-axis-3.0.0.tgz#c42a4a13e8131d637b745fc2973824cfeaf93322"
+  integrity sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==
+
+d3-brush@3:
+  version "3.0.0"
+  resolved "https://registry.npmmirror.com/d3-brush/-/d3-brush-3.0.0.tgz#6f767c4ed8dcb79de7ede3e1c0f89e63ef64d31c"
+  integrity sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==
+  dependencies:
+    d3-dispatch "1 - 3"
+    d3-drag "2 - 3"
+    d3-interpolate "1 - 3"
+    d3-selection "3"
+    d3-transition "3"
+
+d3-chord@3:
+  version "3.0.1"
+  resolved "https://registry.npmmirror.com/d3-chord/-/d3-chord-3.0.1.tgz#d156d61f485fce8327e6abf339cb41d8cbba6966"
+  integrity sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==
+  dependencies:
+    d3-path "1 - 3"
+
+"d3-color@1 - 3", d3-color@3:
+  version "3.1.0"
+  resolved "https://registry.npmmirror.com/d3-color/-/d3-color-3.1.0.tgz#395b2833dfac71507f12ac2f7af23bf819de24e2"
+  integrity sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==
+
+d3-contour@4:
+  version "4.0.2"
+  resolved "https://registry.npmmirror.com/d3-contour/-/d3-contour-4.0.2.tgz#bb92063bc8c5663acb2422f99c73cbb6c6ae3bcc"
+  integrity sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==
+  dependencies:
+    d3-array "^3.2.0"
+
+d3-delaunay@6:
+  version "6.0.2"
+  resolved "https://registry.npmmirror.com/d3-delaunay/-/d3-delaunay-6.0.2.tgz#7fd3717ad0eade2fc9939f4260acfb503f984e92"
+  integrity sha512-IMLNldruDQScrcfT+MWnazhHbDJhcRJyOEBAJfwQnHle1RPh6WDuLvxNArUju2VSMSUuKlY5BGHRJ2cYyoFLQQ==
+  dependencies:
+    delaunator "5"
+
+"d3-dispatch@1 - 3", d3-dispatch@3:
+  version "3.0.1"
+  resolved "https://registry.npmmirror.com/d3-dispatch/-/d3-dispatch-3.0.1.tgz#5fc75284e9c2375c36c839411a0cf550cbfc4d5e"
+  integrity sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==
+
+"d3-drag@2 - 3", d3-drag@3:
+  version "3.0.0"
+  resolved "https://registry.npmmirror.com/d3-drag/-/d3-drag-3.0.0.tgz#994aae9cd23c719f53b5e10e3a0a6108c69607ba"
+  integrity sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==
+  dependencies:
+    d3-dispatch "1 - 3"
+    d3-selection "3"
+
+"d3-dsv@1 - 3", d3-dsv@3:
+  version "3.0.1"
+  resolved "https://registry.npmmirror.com/d3-dsv/-/d3-dsv-3.0.1.tgz#c63af978f4d6a0d084a52a673922be2160789b73"
+  integrity sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==
+  dependencies:
+    commander "7"
+    iconv-lite "0.6"
+    rw "1"
+
+"d3-ease@1 - 3", d3-ease@3:
+  version "3.0.1"
+  resolved "https://registry.npmmirror.com/d3-ease/-/d3-ease-3.0.1.tgz#9658ac38a2140d59d346160f1f6c30fda0bd12f4"
+  integrity sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==
+
+d3-fetch@3:
+  version "3.0.1"
+  resolved "https://registry.npmmirror.com/d3-fetch/-/d3-fetch-3.0.1.tgz#83141bff9856a0edb5e38de89cdcfe63d0a60a22"
+  integrity sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==
+  dependencies:
+    d3-dsv "1 - 3"
+
+d3-force@3:
+  version "3.0.0"
+  resolved "https://registry.npmmirror.com/d3-force/-/d3-force-3.0.0.tgz#3e2ba1a61e70888fe3d9194e30d6d14eece155c4"
+  integrity sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==
+  dependencies:
+    d3-dispatch "1 - 3"
+    d3-quadtree "1 - 3"
+    d3-timer "1 - 3"
+
+"d3-format@1 - 3", d3-format@3:
+  version "3.1.0"
+  resolved "https://registry.npmmirror.com/d3-format/-/d3-format-3.1.0.tgz#9260e23a28ea5cb109e93b21a06e24e2ebd55641"
+  integrity sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==
+
+d3-geo@3:
+  version "3.1.0"
+  resolved "https://registry.npmmirror.com/d3-geo/-/d3-geo-3.1.0.tgz#74fd54e1f4cebd5185ac2039217a98d39b0a4c0e"
+  integrity sha512-JEo5HxXDdDYXCaWdwLRt79y7giK8SbhZJbFWXqbRTolCHFI5jRqteLzCsq51NKbUoX0PjBVSohxrx+NoOUujYA==
+  dependencies:
+    d3-array "2.5.0 - 3"
+
+d3-hierarchy@3:
+  version "3.1.2"
+  resolved "https://registry.npmmirror.com/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz#b01cd42c1eed3d46db77a5966cf726f8c09160c6"
+  integrity sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==
+
+"d3-interpolate@1 - 3", "d3-interpolate@1.2.0 - 3", d3-interpolate@3:
+  version "3.0.1"
+  resolved "https://registry.npmmirror.com/d3-interpolate/-/d3-interpolate-3.0.1.tgz#3c47aa5b32c5b3dfb56ef3fd4342078a632b400d"
+  integrity sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==
+  dependencies:
+    d3-color "1 - 3"
+
+"d3-path@1 - 3", d3-path@3, d3-path@^3.1.0:
+  version "3.1.0"
+  resolved "https://registry.npmmirror.com/d3-path/-/d3-path-3.1.0.tgz#22df939032fb5a71ae8b1800d61ddb7851c42526"
+  integrity sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==
+
+d3-polygon@3:
+  version "3.0.1"
+  resolved "https://registry.npmmirror.com/d3-polygon/-/d3-polygon-3.0.1.tgz#0b45d3dd1c48a29c8e057e6135693ec80bf16398"
+  integrity sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==
+
+"d3-quadtree@1 - 3", d3-quadtree@3:
+  version "3.0.1"
+  resolved "https://registry.npmmirror.com/d3-quadtree/-/d3-quadtree-3.0.1.tgz#6dca3e8be2b393c9a9d514dabbd80a92deef1a4f"
+  integrity sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==
+
+d3-random@3:
+  version "3.0.1"
+  resolved "https://registry.npmmirror.com/d3-random/-/d3-random-3.0.1.tgz#d4926378d333d9c0bfd1e6fa0194d30aebaa20f4"
+  integrity sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==
+
+d3-scale-chromatic@3:
+  version "3.0.0"
+  resolved "https://registry.npmmirror.com/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz#15b4ceb8ca2bb0dcb6d1a641ee03d59c3b62376a"
+  integrity sha512-Lx9thtxAKrO2Pq6OO2Ua474opeziKr279P/TKZsMAhYyNDD3EnCffdbgeSYN5O7m2ByQsxtuP2CSDczNUIZ22g==
+  dependencies:
+    d3-color "1 - 3"
+    d3-interpolate "1 - 3"
+
+d3-scale@4:
+  version "4.0.2"
+  resolved "https://registry.npmmirror.com/d3-scale/-/d3-scale-4.0.2.tgz#82b38e8e8ff7080764f8dcec77bd4be393689396"
+  integrity sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==
+  dependencies:
+    d3-array "2.10.0 - 3"
+    d3-format "1 - 3"
+    d3-interpolate "1.2.0 - 3"
+    d3-time "2.1.1 - 3"
+    d3-time-format "2 - 4"
+
+"d3-selection@2 - 3", d3-selection@3:
+  version "3.0.0"
+  resolved "https://registry.npmmirror.com/d3-selection/-/d3-selection-3.0.0.tgz#c25338207efa72cc5b9bd1458a1a41901f1e1b31"
+  integrity sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==
+
+d3-shape@3:
+  version "3.2.0"
+  resolved "https://registry.npmmirror.com/d3-shape/-/d3-shape-3.2.0.tgz#a1a839cbd9ba45f28674c69d7f855bcf91dfc6a5"
+  integrity sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==
+  dependencies:
+    d3-path "^3.1.0"
+
+"d3-time-format@2 - 4", d3-time-format@4:
+  version "4.1.0"
+  resolved "https://registry.npmmirror.com/d3-time-format/-/d3-time-format-4.1.0.tgz#7ab5257a5041d11ecb4fe70a5c7d16a195bb408a"
+  integrity sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==
+  dependencies:
+    d3-time "1 - 3"
+
+"d3-time@1 - 3", "d3-time@2.1.1 - 3", d3-time@3:
+  version "3.1.0"
+  resolved "https://registry.npmmirror.com/d3-time/-/d3-time-3.1.0.tgz#9310db56e992e3c0175e1ef385e545e48a9bb5c7"
+  integrity sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==
+  dependencies:
+    d3-array "2 - 3"
+
+"d3-timer@1 - 3", d3-timer@3:
+  version "3.0.1"
+  resolved "https://registry.npmmirror.com/d3-timer/-/d3-timer-3.0.1.tgz#6284d2a2708285b1abb7e201eda4380af35e63b0"
+  integrity sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==
+
+"d3-transition@2 - 3", d3-transition@3:
+  version "3.0.1"
+  resolved "https://registry.npmmirror.com/d3-transition/-/d3-transition-3.0.1.tgz#6869fdde1448868077fdd5989200cb61b2a1645f"
+  integrity sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==
+  dependencies:
+    d3-color "1 - 3"
+    d3-dispatch "1 - 3"
+    d3-ease "1 - 3"
+    d3-interpolate "1 - 3"
+    d3-timer "1 - 3"
+
+d3-zoom@3:
+  version "3.0.0"
+  resolved "https://registry.npmmirror.com/d3-zoom/-/d3-zoom-3.0.0.tgz#d13f4165c73217ffeaa54295cd6969b3e7aee8f3"
+  integrity sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==
+  dependencies:
+    d3-dispatch "1 - 3"
+    d3-drag "2 - 3"
+    d3-interpolate "1 - 3"
+    d3-selection "2 - 3"
+    d3-transition "2 - 3"
+
+d3@^7.8.2:
+  version "7.8.2"
+  resolved "https://registry.npmmirror.com/d3/-/d3-7.8.2.tgz#2bdb3c178d095ae03b107a18837ae049838e372d"
+  integrity sha512-WXty7qOGSHb7HR7CfOzwN1Gw04MUOzN8qh9ZUsvwycIMb4DYMpY9xczZ6jUorGtO6bR9BPMPaueIKwiDxu9uiQ==
+  dependencies:
+    d3-array "3"
+    d3-axis "3"
+    d3-brush "3"
+    d3-chord "3"
+    d3-color "3"
+    d3-contour "4"
+    d3-delaunay "6"
+    d3-dispatch "3"
+    d3-drag "3"
+    d3-dsv "3"
+    d3-ease "3"
+    d3-fetch "3"
+    d3-force "3"
+    d3-format "3"
+    d3-geo "3"
+    d3-hierarchy "3"
+    d3-interpolate "3"
+    d3-path "3"
+    d3-polygon "3"
+    d3-quadtree "3"
+    d3-random "3"
+    d3-scale "4"
+    d3-scale-chromatic "3"
+    d3-selection "3"
+    d3-shape "3"
+    d3-time "3"
+    d3-time-format "4"
+    d3-timer "3"
+    d3-transition "3"
+    d3-zoom "3"
+
 data-urls@^3.0.2:
 data-urls@^3.0.2:
   version "3.0.2"
   version "3.0.2"
   resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-3.0.2.tgz#9cf24a477ae22bcef5cd5f6f0bfbc1d2d3be9143"
   resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-3.0.2.tgz#9cf24a477ae22bcef5cd5f6f0bfbc1d2d3be9143"
@@ -1561,6 +2025,13 @@ define-properties@^1.1.3, define-properties@^1.1.4:
     has-property-descriptors "^1.0.0"
     has-property-descriptors "^1.0.0"
     object-keys "^1.1.1"
     object-keys "^1.1.1"
 
 
+delaunator@5:
+  version "5.0.0"
+  resolved "https://registry.npmmirror.com/delaunator/-/delaunator-5.0.0.tgz#60f052b28bd91c9b4566850ebf7756efe821d81b"
+  integrity sha512-AyLvtyJdbv/U1GkiS6gUUzclRoAY4Gs75qkMygJJhU75LW4DNuSF2RMzpxs9jw9Oz1BobHjTdkG3zdP55VxAqw==
+  dependencies:
+    robust-predicates "^3.0.0"
+
 delayed-stream@~1.0.0:
 delayed-stream@~1.0.0:
   version "1.0.0"
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
   resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
@@ -2111,7 +2582,7 @@ i18next@^20.3.1:
   dependencies:
   dependencies:
     "@babel/runtime" "^7.12.0"
     "@babel/runtime" "^7.12.0"
 
 
-iconv-lite@0.6.3:
+iconv-lite@0.6, iconv-lite@0.6.3:
   version "0.6.3"
   version "0.6.3"
   resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501"
   resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501"
   integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==
   integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==
@@ -2144,6 +2615,11 @@ inherits@2:
   resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
   resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
   integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
   integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
 
 
+"internmap@1 - 2":
+  version "2.0.3"
+  resolved "https://registry.npmmirror.com/internmap/-/internmap-2.0.3.tgz#6685f23755e43c524e251d29cbc97248e3061009"
+  integrity sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==
+
 is-alphabetical@^1.0.0:
 is-alphabetical@^1.0.0:
   version "1.0.4"
   version "1.0.4"
   resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-1.0.4.tgz#9e7d6b94916be22153745d184c298cbf986a686d"
   resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-1.0.4.tgz#9e7d6b94916be22153745d184c298cbf986a686d"
@@ -3062,6 +3538,11 @@ rimraf@^3.0.2:
   dependencies:
   dependencies:
     glob "^7.1.3"
     glob "^7.1.3"
 
 
+robust-predicates@^3.0.0:
+  version "3.0.1"
+  resolved "https://registry.npmmirror.com/robust-predicates/-/robust-predicates-3.0.1.tgz#ecde075044f7f30118682bd9fb3f123109577f9a"
+  integrity sha512-ndEIpszUHiG4HtDsQLeIuMvRsDnn8c8rYStabochtUeCvfuvNptb5TUbVD68LRAILPX7p9nqQGh4xJgn3EHS/g==
+
 rollup@^2.79.1:
 rollup@^2.79.1:
   version "2.79.1"
   version "2.79.1"
   resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.79.1.tgz#bedee8faef7c9f93a2647ac0108748f497f081c7"
   resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.79.1.tgz#bedee8faef7c9f93a2647ac0108748f497f081c7"
@@ -3069,6 +3550,11 @@ rollup@^2.79.1:
   optionalDependencies:
   optionalDependencies:
     fsevents "~2.3.2"
     fsevents "~2.3.2"
 
 
+rw@1:
+  version "1.3.3"
+  resolved "https://registry.npmmirror.com/rw/-/rw-1.3.3.tgz#3f862dfa91ab766b14885ef4d01124bfda074fb4"
+  integrity sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==
+
 safe-buffer@~5.1.1:
 safe-buffer@~5.1.1:
   version "5.1.2"
   version "5.1.2"
   resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
   resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"

+ 77 - 39
server/src/prometheus/prometheus.service.ts

@@ -1,8 +1,7 @@
 import axios from 'axios';
 import axios from 'axios';
-import { threadId } from 'worker_threads';
 
 
 interface IPrometheusNode {
 interface IPrometheusNode {
-  label: string;
+  type: string;
   pod: string;
   pod: string;
   cpu: number[];
   cpu: number[];
   memory: number[];
   memory: number[];
@@ -11,7 +10,7 @@ interface IPrometheusNode {
 interface IPrometheusAllData {
 interface IPrometheusAllData {
   totalVectorsCount: number[];
   totalVectorsCount: number[];
   searchVectorsCount: number[];
   searchVectorsCount: number[];
-  searchFailedVectorsCount: number[];
+  searchFailedVectorsCount?: number[];
   sqLatency: number[];
   sqLatency: number[];
 
 
   meta: number[];
   meta: number[];
@@ -81,21 +80,22 @@ export class PrometheusService {
   async checkPrometheus(prometheusAddress: string) {
   async checkPrometheus(prometheusAddress: string) {
     const result = await axios
     const result = await axios
       .get(`http://${prometheusAddress}/-/ready`)
       .get(`http://${prometheusAddress}/-/ready`)
-      .then(res => res.status)
+      .then(res => res?.status === 200)
       .catch(err => {
       .catch(err => {
-        console.log(err);
+        // console.log(err);
+        return false;
       });
       });
-    return result === 200;
+    return result;
   }
   }
 
 
-  async queryRange(expr: string, start: number, end: number, step: string) {
+  async queryRange(expr: string, start: number, end: number, step: number) {
     const url =
     const url =
       PrometheusService.url +
       PrometheusService.url +
       '/api/v1/query_range?query=' +
       '/api/v1/query_range?query=' +
       expr +
       expr +
       `&start=${new Date(+start).toISOString()}` +
       `&start=${new Date(+start).toISOString()}` +
       `&end=${new Date(+end).toISOString()}` +
       `&end=${new Date(+end).toISOString()}` +
-      `&step=${step}`;
+      `&step=${step / 1000}s`;
     console.log(url);
     console.log(url);
     const result = await axios
     const result = await axios
       .get(url)
       .get(url)
@@ -107,17 +107,34 @@ export class PrometheusService {
     return result;
     return result;
   }
   }
 
 
-  async getSearchVectorsCount(start: number, end: number, step: string) {
-    const expr = `${searchVectorsCountMetric}${PrometheusService.selector}`;
+  async getVectorsCount(
+    metric: string,
+    start: number,
+    end: number,
+    step: number
+  ) {
+    const expr = `${metric}${PrometheusService.selector}`;
     const result = await this.queryRange(expr, start, end, step);
     const result = await this.queryRange(expr, start, end, step);
-    return result.data.result[0].values.map((d: any) => +d[1]).slice(1);
-  }
+    const data = result.data.result;
+    const length = Math.floor((end - start) / step) + 1;
 
 
-  async getInsertVectorsCount(start: number, end: number, step: string) {
-    const expr = `${totalVectorsCountMetric}${PrometheusService.selector}`;
-    const result = await this.queryRange(expr, start, end, step);
-    return result.data.result[0].values.map((d: any) => +d[1]).slice(1);
+    if (data.length === 0) return Array(length).fill(0);
+
+    const res = result.data.result[0].values.map((d: any) => +d[1]).slice(1);
+
+    let leftLossCount, rightLossCount;
+    leftLossCount = Math.floor((data[0].values[0][0] * 1000 - start) / step);
+    res.unshift(...Array(leftLossCount).fill(-1));
+    rightLossCount = Math.floor(
+      (end - data[0].values[data[0].values.length - 1][0] * 1000) / step
+    );
+    res.push(...Array(rightLossCount).fill(-1));
+    return res;
   }
   }
+  getSearchVectorsCount = (start: number, end: number, step: number) =>
+    this.getVectorsCount(searchVectorsCountMetric, start, end, step);
+  getInsertVectorsCount = (start: number, end: number, step: number) =>
+    this.getVectorsCount(totalVectorsCountMetric, start, end, step);
 
 
   getSQLatency() {
   getSQLatency() {
     return;
     return;
@@ -127,7 +144,7 @@ export class PrometheusService {
     metricName: string,
     metricName: string,
     start: number,
     start: number,
     end: number,
     end: number,
-    step: string
+    step: number
   ) {
   ) {
     const expr = `sum by (status) (${metricName}${PrometheusService.selector})`;
     const expr = `sum by (status) (${metricName}${PrometheusService.selector})`;
     const result = await this.queryRange(expr, start, end, step);
     const result = await this.queryRange(expr, start, end, step);
@@ -148,13 +165,13 @@ export class PrometheusService {
     );
     );
   }
   }
 
 
-  async getInternalNodesCPUData(start: number, end: number, step: string) {
+  async getInternalNodesCPUData(start: number, end: number, step: number) {
     const expr = `${cpuMetric}${PrometheusService.selector}`;
     const expr = `${cpuMetric}${PrometheusService.selector}`;
     const result = await this.queryRange(expr, start, end, step);
     const result = await this.queryRange(expr, start, end, step);
     return result.data.result;
     return result.data.result;
   }
   }
 
 
-  async getInternalNodesMemoryData(start: number, end: number, step: string) {
+  async getInternalNodesMemoryData(start: number, end: number, step: number) {
     const expr = `${memoryMetric}${PrometheusService.selector}`;
     const expr = `${memoryMetric}${PrometheusService.selector}`;
     const result = await this.queryRange(expr, start, end, step);
     const result = await this.queryRange(expr, start, end, step);
     return result.data.result;
     return result.data.result;
@@ -163,43 +180,64 @@ export class PrometheusService {
   reconstructNodeData(
   reconstructNodeData(
     cpuNodesData: any,
     cpuNodesData: any,
     memoryNodesData: any,
     memoryNodesData: any,
-    label: string
+    type: string,
+    start: number,
+    end: number,
+    step: number
   ): IPrometheusNode[] {
   ): IPrometheusNode[] {
     const cpuNodes = cpuNodesData.filter(
     const cpuNodes = cpuNodesData.filter(
-      (d: any) => d.metric.container.indexOf(label) >= 0
+      (d: any) => d.metric.container.indexOf(type) >= 0
     );
     );
     const memoryNodes = memoryNodesData.filter(
     const memoryNodes = memoryNodesData.filter(
-      (d: any) => d.metric.container.indexOf(label) >= 0
+      (d: any) => d.metric.container.indexOf(type) >= 0
     );
     );
     const nodesData = cpuNodes.map((d: any) => {
     const nodesData = cpuNodes.map((d: any) => {
-      const label = d.metric.container.indexOf('coord') >= 0 ? 'coord' : 'node';
+      const type = d.metric.container.indexOf('coord') >= 0 ? 'coord' : 'node';
       const pod = d.metric.pod;
       const pod = d.metric.pod;
       const cpuProcessTotal = d.values.map((v: any) => +v[1]);
       const cpuProcessTotal = d.values.map((v: any) => +v[1]);
-      const step =
-        (d.values[d.values.length - 1][0] - d.values[0][0]) /
-        (d.values.length - 1);
       const cpu = cpuProcessTotal
       const cpu = cpuProcessTotal
         .map((v: number, i: number) => (i > 0 ? v - cpuProcessTotal[i - 1] : 0))
         .map((v: number, i: number) => (i > 0 ? v - cpuProcessTotal[i - 1] : 0))
         .slice(1)
         .slice(1)
-        .map((v: number) => v / step);
+        .map((v: number) => v / (step / 1000));
 
 
-      const memory = memoryNodes
-        .find((data: any) => data.metric.pod === pod)
-        .values.map((v: any) => +v[1])
-        .slice(1);
-      return { label, pod, cpu, memory } as IPrometheusNode;
+      let leftLossCount, rightLossCount;
+      leftLossCount = Math.floor((d.values[0][0] * 1000 - start) / step);
+      cpu.unshift(...Array(leftLossCount).fill(-1));
+      rightLossCount = Math.floor(
+        (end - d.values[d.values.length - 1][0] * 1000) / step
+      );
+      cpu.push(...Array(rightLossCount).fill(-1));
+
+      const node = memoryNodes.find((data: any) => data.metric.pod === pod);
+      const memory = node.values.map((v: any) => +v[1]).slice(1);
+
+      leftLossCount = Math.floor((node.values[0][0] * 1000 - start) / step);
+      memory.unshift(...Array(leftLossCount).fill(-1));
+      rightLossCount = Math.floor(
+        (end - node.values[node.values.length - 1][0] * 1000) / step
+      );
+      memory.push(...Array(rightLossCount).fill(-1));
+      return { type, pod, cpu, memory } as IPrometheusNode;
     });
     });
 
 
     return nodesData;
     return nodesData;
   }
   }
 
 
-  async getInternalNodesData(start: number, end: number, step: string) {
+  async getInternalNodesData(start: number, end: number, step: number) {
     const cpuNodes = await this.getInternalNodesCPUData(start, end, step);
     const cpuNodes = await this.getInternalNodesCPUData(start, end, step);
     const memoryNodes = await this.getInternalNodesMemoryData(start, end, step);
     const memoryNodes = await this.getInternalNodesMemoryData(start, end, step);
 
 
-    const queryNodes = this.reconstructNodeData(cpuNodes, memoryNodes, 'query');
-    const indexNodes = this.reconstructNodeData(cpuNodes, memoryNodes, 'index');
-    const dataNodes = this.reconstructNodeData(cpuNodes, memoryNodes, 'data');
+    const [queryNodes, indexNodes, dataNodes] = ['query', 'index', 'data'].map(
+      (metric: string) =>
+        this.reconstructNodeData(
+          cpuNodes,
+          memoryNodes,
+          metric,
+          start,
+          end,
+          step
+        )
+    );
     return { queryNodes, indexNodes, dataNodes };
     return { queryNodes, indexNodes, dataNodes };
   }
   }
 
 
@@ -210,7 +248,7 @@ export class PrometheusService {
   }: {
   }: {
     start: number;
     start: number;
     end: number;
     end: number;
-    step: string;
+    step: number;
   }) {
   }) {
     const meta = await this.getThirdPartyServiceHealthStatus(
     const meta = await this.getThirdPartyServiceHealthStatus(
       metaMetric,
       metaMetric,
@@ -247,7 +285,7 @@ export class PrometheusService {
 
 
     const rootNodes: IPrometheusNode[] = [
     const rootNodes: IPrometheusNode[] = [
       {
       {
-        label: 'coord',
+        type: 'coord',
         pod: cpuNodes.find((node: any) => node.metric.container === 'rootcoord')
         pod: cpuNodes.find((node: any) => node.metric.container === 'rootcoord')
           .metric.pod,
           .metric.pod,
         cpu: cpuNodes
         cpu: cpuNodes
@@ -274,6 +312,6 @@ export class PrometheusService {
       queryNodes,
       queryNodes,
       indexNodes,
       indexNodes,
       dataNodes,
       dataNodes,
-    };
+    } as IPrometheusAllData;
   }
   }
 }
 }