fix: add a crosshair of the same point in each chart when hover in a chart (#16)
Co-authored-by: yaojiping <yaojiping@infini.ltd>
This commit is contained in:
parent
356f710e4a
commit
8aa77ca98c
|
@ -239,7 +239,7 @@ export default ({
|
||||||
"request_cache_miss"
|
"request_cache_miss"
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]}
|
].filter((item) => !!item && !!item[1])}
|
||||||
/>
|
/>
|
||||||
</Tabs.TabPane>
|
</Tabs.TabPane>
|
||||||
<Tabs.TabPane
|
<Tabs.TabPane
|
||||||
|
@ -402,7 +402,7 @@ export default ({
|
||||||
"force_merge_threads"
|
"force_merge_threads"
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
].filter((item) => !!item)}
|
].filter((item) => !!item && !!item[1])}
|
||||||
/>
|
/>
|
||||||
</Tabs.TabPane>
|
</Tabs.TabPane>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
|
@ -201,7 +201,7 @@ export default ({
|
||||||
"request_cache_miss"
|
"request_cache_miss"
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]}
|
].filter((item) => !!item && !!item[1])}
|
||||||
/>
|
/>
|
||||||
</Tabs.TabPane>
|
</Tabs.TabPane>
|
||||||
<Tabs.TabPane
|
<Tabs.TabPane
|
||||||
|
@ -286,7 +286,7 @@ export default ({
|
||||||
"force_merge_threads"
|
"force_merge_threads"
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]}
|
].filter((item) => !!item && !!item[1])}
|
||||||
/>
|
/>
|
||||||
</Tabs.TabPane>
|
</Tabs.TabPane>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
|
@ -37,7 +37,9 @@ export default (props) => {
|
||||||
style,
|
style,
|
||||||
formatMetric,
|
formatMetric,
|
||||||
height = 200,
|
height = 200,
|
||||||
customRenderChart
|
customRenderChart,
|
||||||
|
instance,
|
||||||
|
pointerUpdate
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const [loading, setLoading] = useState(false)
|
const [loading, setLoading] = useState(false)
|
||||||
|
@ -119,14 +121,6 @@ export default (props) => {
|
||||||
};
|
};
|
||||||
}, [isInView]);
|
}, [isInView]);
|
||||||
|
|
||||||
const chartRef = useRef();
|
|
||||||
|
|
||||||
const pointerUpdate = (event) => {
|
|
||||||
if (chartRef.current) {
|
|
||||||
chartRef.current.dispatchExternalPointerEvent(event);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleChartBrush = ({ x }) => {
|
const handleChartBrush = ({ x }) => {
|
||||||
if (!x) {
|
if (!x) {
|
||||||
return;
|
return;
|
||||||
|
@ -168,7 +162,7 @@ export default (props) => {
|
||||||
<Chart
|
<Chart
|
||||||
size={[, height]}
|
size={[, height]}
|
||||||
className={styles.vizChartItem}
|
className={styles.vizChartItem}
|
||||||
ref={chartRef}
|
ref={instance}
|
||||||
>
|
>
|
||||||
<Settings
|
<Settings
|
||||||
pointerUpdateDebounce={0}
|
pointerUpdateDebounce={0}
|
||||||
|
|
|
@ -2,7 +2,7 @@ import styles from "./Metrics.scss";
|
||||||
import "./node_metric.scss";
|
import "./node_metric.scss";
|
||||||
import { calculateBounds } from "@/components/vendor/data/common/query/timefilter";
|
import { calculateBounds } from "@/components/vendor/data/common/query/timefilter";
|
||||||
import MetricChart from "./MetricChart";
|
import MetricChart from "./MetricChart";
|
||||||
import { useMemo } from "react";
|
import { createRef, useEffect, useMemo, useRef, useState } from "react";
|
||||||
import { formatMessage } from "umi/locale";
|
import { formatMessage } from "umi/locale";
|
||||||
import { formatTimeRange } from "@/lib/elasticsearch/util";
|
import { formatTimeRange } from "@/lib/elasticsearch/util";
|
||||||
|
|
||||||
|
@ -27,12 +27,34 @@ export default (props) => {
|
||||||
|
|
||||||
const extra = renderExtra ? renderExtra() : null;
|
const extra = renderExtra ? renderExtra() : null;
|
||||||
|
|
||||||
|
const [charts, setCharts] = useState([])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setCharts(() => {
|
||||||
|
const cs = {}
|
||||||
|
metrics.forEach((metricKey) => {
|
||||||
|
cs[metricKey] = createRef()
|
||||||
|
})
|
||||||
|
return cs
|
||||||
|
})
|
||||||
|
}, [JSON.stringify(metrics)])
|
||||||
|
|
||||||
|
const pointerUpdate = (event) => {
|
||||||
|
Object.keys(charts).forEach((key) => {
|
||||||
|
if (charts[key].current) {
|
||||||
|
charts[key].current.dispatchExternalPointerEvent(event);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div id="cluster-metric">
|
<div id="cluster-metric">
|
||||||
<div className={styles.metricList}>
|
<div className={styles.metricList}>
|
||||||
{metrics.map((metricKey, i) => (
|
{metrics.filter((item) => !!item).map((metricKey) => (
|
||||||
<MetricChart
|
<MetricChart
|
||||||
key={metricKey}
|
key={metricKey}
|
||||||
|
instance={charts[metricKey]}
|
||||||
|
pointerUpdate={pointerUpdate}
|
||||||
timezone={timezone}
|
timezone={timezone}
|
||||||
timeRange={timeRange}
|
timeRange={timeRange}
|
||||||
timeout={timeout}
|
timeout={timeout}
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { formatTimeRange } from "@/lib/elasticsearch/util";
|
||||||
import NodeSelect from "@/components/NodeSelect";
|
import NodeSelect from "@/components/NodeSelect";
|
||||||
import Anchor from "@/components/Anchor";
|
import Anchor from "@/components/Anchor";
|
||||||
import MetricChart from "./MetricChart";
|
import MetricChart from "./MetricChart";
|
||||||
import { useMemo } from "react";
|
import { createRef, useEffect, useMemo, useState } from "react";
|
||||||
|
|
||||||
export default (props) => {
|
export default (props) => {
|
||||||
|
|
||||||
|
@ -79,6 +79,30 @@ export default (props) => {
|
||||||
return Object.values(indices || []);
|
return Object.values(indices || []);
|
||||||
}, [indices]);
|
}, [indices]);
|
||||||
|
|
||||||
|
const [charts, setCharts] = useState([])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setCharts(() => {
|
||||||
|
const cs = {}
|
||||||
|
metrics.forEach((item) => {
|
||||||
|
if (item[1]?.length > 0) {
|
||||||
|
item[1].forEach((metricKey) => {
|
||||||
|
cs[metricKey] = createRef()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return cs
|
||||||
|
})
|
||||||
|
}, [JSON.stringify(metrics)])
|
||||||
|
|
||||||
|
const pointerUpdate = (event) => {
|
||||||
|
Object.keys(charts).forEach((key) => {
|
||||||
|
if (charts[key].current) {
|
||||||
|
charts[key].current.dispatchExternalPointerEvent(event);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div id="node-metric">
|
<div id="node-metric">
|
||||||
{showTop ? (
|
{showTop ? (
|
||||||
|
@ -109,7 +133,7 @@ export default (props) => {
|
||||||
|
|
||||||
<div className="px-box">
|
<div className="px-box">
|
||||||
<div className="px">
|
<div className="px">
|
||||||
{metrics.map((item, i) => {
|
{metrics.filter((item) => !!item && !!item[1]).map((item) => {
|
||||||
return (
|
return (
|
||||||
<div key={item[0]} style={{ margin: "8px 0" }}>
|
<div key={item[0]} style={{ margin: "8px 0" }}>
|
||||||
<MetricContainer
|
<MetricContainer
|
||||||
|
@ -122,6 +146,8 @@ export default (props) => {
|
||||||
item[1].map((metricKey) => (
|
item[1].map((metricKey) => (
|
||||||
<MetricChart
|
<MetricChart
|
||||||
key={metricKey}
|
key={metricKey}
|
||||||
|
instance={charts[metricKey]}
|
||||||
|
pointerUpdate={pointerUpdate}
|
||||||
timezone={timezone}
|
timezone={timezone}
|
||||||
timeRange={timeRange}
|
timeRange={timeRange}
|
||||||
handleTimeChange={handleTimeChange}
|
handleTimeChange={handleTimeChange}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { formatTimeRange } from "@/lib/elasticsearch/util";
|
||||||
import NodeSelect from "@/components/NodeSelect";
|
import NodeSelect from "@/components/NodeSelect";
|
||||||
import Anchor from "@/components/Anchor";
|
import Anchor from "@/components/Anchor";
|
||||||
import MetricChart from "./MetricChart";
|
import MetricChart from "./MetricChart";
|
||||||
import { useCallback, useMemo } from "react";
|
import { createRef, useCallback, useEffect, useMemo, useState } from "react";
|
||||||
|
|
||||||
export default (props) => {
|
export default (props) => {
|
||||||
|
|
||||||
|
@ -94,6 +94,30 @@ export default (props) => {
|
||||||
});
|
});
|
||||||
}, [nodes]);
|
}, [nodes]);
|
||||||
|
|
||||||
|
const [charts, setCharts] = useState([])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setCharts(() => {
|
||||||
|
const cs = {}
|
||||||
|
metrics.forEach((item) => {
|
||||||
|
if (item[1]?.length > 0) {
|
||||||
|
item[1].forEach((metricKey) => {
|
||||||
|
cs[metricKey] = createRef()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return cs
|
||||||
|
})
|
||||||
|
}, [JSON.stringify(metrics)])
|
||||||
|
|
||||||
|
const pointerUpdate = (event) => {
|
||||||
|
Object.keys(charts).forEach((key) => {
|
||||||
|
if (charts[key].current) {
|
||||||
|
charts[key].current.dispatchExternalPointerEvent(event);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div id="node-metric">
|
<div id="node-metric">
|
||||||
{showTop ? (
|
{showTop ? (
|
||||||
|
@ -132,7 +156,7 @@ export default (props) => {
|
||||||
|
|
||||||
<div className="px-box">
|
<div className="px-box">
|
||||||
<div className="px">
|
<div className="px">
|
||||||
{metrics.map((item, i) => {
|
{metrics.filter((item) => !!item && !!item[1]).map((item) => {
|
||||||
return (
|
return (
|
||||||
<div key={item[0]} style={{ margin: "8px 0" }}>
|
<div key={item[0]} style={{ margin: "8px 0" }}>
|
||||||
<MetricContainer
|
<MetricContainer
|
||||||
|
@ -145,6 +169,8 @@ export default (props) => {
|
||||||
item[1].map((metricKey) => (
|
item[1].map((metricKey) => (
|
||||||
<MetricChart
|
<MetricChart
|
||||||
key={metricKey}
|
key={metricKey}
|
||||||
|
instance={charts[metricKey]}
|
||||||
|
pointerUpdate={pointerUpdate}
|
||||||
timezone={timezone}
|
timezone={timezone}
|
||||||
timeRange={timeRange}
|
timeRange={timeRange}
|
||||||
handleTimeChange={handleTimeChange}
|
handleTimeChange={handleTimeChange}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { formatTimeRange } from "@/lib/elasticsearch/util";
|
||||||
import NodeSelect from "@/components/NodeSelect";
|
import NodeSelect from "@/components/NodeSelect";
|
||||||
import Anchor from "@/components/Anchor";
|
import Anchor from "@/components/Anchor";
|
||||||
import MetricChart from "./MetricChart";
|
import MetricChart from "./MetricChart";
|
||||||
import { useCallback, useMemo } from "react";
|
import { createRef, useCallback, useEffect, useMemo, useState } from "react";
|
||||||
|
|
||||||
export default (props) => {
|
export default (props) => {
|
||||||
|
|
||||||
|
@ -94,6 +94,30 @@ export default (props) => {
|
||||||
});
|
});
|
||||||
}, [nodes]);
|
}, [nodes]);
|
||||||
|
|
||||||
|
const [charts, setCharts] = useState([])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setCharts(() => {
|
||||||
|
const cs = {}
|
||||||
|
metrics.forEach((item) => {
|
||||||
|
if (item[1]?.length > 0) {
|
||||||
|
item[1].forEach((metricKey) => {
|
||||||
|
cs[metricKey] = createRef()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return cs
|
||||||
|
})
|
||||||
|
}, [JSON.stringify(metrics)])
|
||||||
|
|
||||||
|
const pointerUpdate = (event) => {
|
||||||
|
Object.keys(charts).forEach((key) => {
|
||||||
|
if (charts[key].current) {
|
||||||
|
charts[key].current.dispatchExternalPointerEvent(event);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div id="node-metric">
|
<div id="node-metric">
|
||||||
{showTop ? (
|
{showTop ? (
|
||||||
|
@ -132,7 +156,7 @@ export default (props) => {
|
||||||
|
|
||||||
<div className="px-box">
|
<div className="px-box">
|
||||||
<div className="px">
|
<div className="px">
|
||||||
{metrics.map((item, i) => {
|
{metrics.filter((item) => !!item && !!item[1]).map((item) => {
|
||||||
return (
|
return (
|
||||||
<div key={item[0]} style={{ margin: "8px 0" }}>
|
<div key={item[0]} style={{ margin: "8px 0" }}>
|
||||||
<MetricContainer
|
<MetricContainer
|
||||||
|
@ -145,6 +169,8 @@ export default (props) => {
|
||||||
item[1].map((metricKey) => (
|
item[1].map((metricKey) => (
|
||||||
<MetricChart
|
<MetricChart
|
||||||
key={metricKey}
|
key={metricKey}
|
||||||
|
instance={charts[metricKey]}
|
||||||
|
pointerUpdate={pointerUpdate}
|
||||||
timezone={timezone}
|
timezone={timezone}
|
||||||
timeRange={timeRange}
|
timeRange={timeRange}
|
||||||
handleTimeChange={handleTimeChange}
|
handleTimeChange={handleTimeChange}
|
||||||
|
|
Loading…
Reference in New Issue