diff --git a/ui-new/packages/tidb-dashboard-for-dbaas/package.json b/ui-new/packages/tidb-dashboard-for-dbaas/package.json
index 794e039ee3..efcf453458 100644
--- a/ui-new/packages/tidb-dashboard-for-dbaas/package.json
+++ b/ui-new/packages/tidb-dashboard-for-dbaas/package.json
@@ -1,6 +1,6 @@
{
"name": "@pingcap/tidb-dashboard-for-dbaas",
- "version": "0.0.9",
+ "version": "0.0.11-beta",
"main": "dist/main.js",
"module": "dist/main.js",
"files": [
diff --git a/ui-new/packages/tidb-dashboard-for-dbaas/public/test-iframe/parent.html b/ui-new/packages/tidb-dashboard-for-dbaas/public/test-iframe/parent.html
index e0878b1f94..a555b5ba68 100644
--- a/ui-new/packages/tidb-dashboard-for-dbaas/public/test-iframe/parent.html
+++ b/ui-new/packages/tidb-dashboard-for-dbaas/public/test-iframe/parent.html
@@ -47,6 +47,7 @@
SlowQuery
KeyViz
TopSQL
+ Metrics
}
+ if (locHashPrefix === 'overview') {
+ return
+ }
+
return
No Matched Route!
}
diff --git a/ui-new/packages/tidb-dashboard-for-dbaas/src/apps/Overview/context.ts b/ui-new/packages/tidb-dashboard-for-dbaas/src/apps/Overview/context.ts
new file mode 100644
index 0000000000..bd2daf0d73
--- /dev/null
+++ b/ui-new/packages/tidb-dashboard-for-dbaas/src/apps/Overview/context.ts
@@ -0,0 +1,58 @@
+import {
+ IOverviewDataSource,
+ IOverviewContext,
+ ReqConfig
+} from '@pingcap/tidb-dashboard-lib'
+
+import client from '~/client'
+
+class DataSource implements IOverviewDataSource {
+ getTiDBTopology(options?: ReqConfig) {
+ return client.getInstance().getTiDBTopology(options)
+ }
+
+ getStoreTopology(options?: ReqConfig) {
+ return client.getInstance().getStoreTopology(options)
+ }
+
+ getPDTopology(options?: ReqConfig) {
+ return client.getInstance().getPDTopology(options)
+ }
+
+ metricsQueryGet(
+ endTimeSec?: number,
+ query?: string,
+ startTimeSec?: number,
+ stepSec?: number,
+ options?: ReqConfig
+ ) {
+ return client.getInstance().metricsQueryGet(
+ {
+ endTimeSec,
+ query,
+ startTimeSec,
+ stepSec
+ },
+ options
+ )
+ }
+
+ getGrafanaTopology(options?: ReqConfig) {
+ return client.getInstance().getGrafanaTopology(options)
+ }
+
+ getAlertManagerTopology(options?: ReqConfig) {
+ return client.getInstance().getAlertManagerTopology(options)
+ }
+
+ getAlertManagerCounts(address: string, options?: ReqConfig) {
+ return client.getInstance().getAlertManagerCounts({ address }, options)
+ }
+}
+
+const ds = new DataSource()
+
+export const ctx: () => IOverviewContext = () => ({
+ ds,
+ cfg: { apiPathBase: client.getBasePath() }
+})
diff --git a/ui-new/packages/tidb-dashboard-for-dbaas/src/apps/Overview/index.tsx b/ui-new/packages/tidb-dashboard-for-dbaas/src/apps/Overview/index.tsx
new file mode 100644
index 0000000000..3c47f15cb2
--- /dev/null
+++ b/ui-new/packages/tidb-dashboard-for-dbaas/src/apps/Overview/index.tsx
@@ -0,0 +1,11 @@
+import React from 'react'
+import { OverviewApp, OverviewProvider } from '@pingcap/tidb-dashboard-lib'
+import { ctx } from './context'
+
+export default function () {
+ return (
+
+
+
+ )
+}
diff --git a/ui-new/packages/tidb-dashboard-lib/src/apps/Overview/components/Instances.tsx b/ui-new/packages/tidb-dashboard-lib/src/apps/Overview/components/Instances.tsx
index f4d3d1cbda..2ea28fccb5 100644
--- a/ui-new/packages/tidb-dashboard-lib/src/apps/Overview/components/Instances.tsx
+++ b/ui-new/packages/tidb-dashboard-lib/src/apps/Overview/components/Instances.tsx
@@ -100,7 +100,7 @@ export default function Nodes() {
}
- noMarginLeft
+ noMarginRight
>
diff --git a/ui-new/packages/tidb-dashboard-lib/src/apps/Overview/components/Metrics.tsx b/ui-new/packages/tidb-dashboard-lib/src/apps/Overview/components/Metrics.tsx
index 34c9c92b95..1d5e301f8d 100644
--- a/ui-new/packages/tidb-dashboard-lib/src/apps/Overview/components/Metrics.tsx
+++ b/ui-new/packages/tidb-dashboard-lib/src/apps/Overview/components/Metrics.tsx
@@ -1,4 +1,4 @@
-import { Space, Typography } from 'antd'
+import { Space, Typography, Row, Col, Collapse, Button } from 'antd'
import React, { useContext, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import {
@@ -10,16 +10,22 @@ import {
TimeRangeSelector,
Toolbar
} from '@lib/components'
+import { Link } from 'react-router-dom'
import { Range } from '@elastic/charts/dist/utils/domain'
import { Stack } from 'office-ui-fabric-react'
import { useTimeRangeValue } from '@lib/components/TimeRangeSelector/hook'
-import { LoadingOutlined } from '@ant-design/icons'
+import { LoadingOutlined, ArrowLeftOutlined } from '@ant-design/icons'
import { some } from 'lodash'
import { ReqConfig } from '@lib/types'
import { MetricsQueryResponse } from '@lib/client'
import { AxiosPromise } from 'axios'
import { OverviewContext } from '../context'
+import { PointerEvent } from '@elastic/charts'
+import { ChartContext } from '@lib/components/MetricChart/ChartContext'
+import { useEventEmitter } from 'ahooks'
+import { MetricsItems } from './MetricsItems'
+
interface IChartProps {
range: Range
onRangeChange?: (newRange: Range) => void
@@ -33,144 +39,32 @@ interface IChartProps {
) => AxiosPromise
}
-function QPS(props: IChartProps) {
- const { t } = useTranslation()
- return (
-
-
- {t('overview.metrics.total_requests')}
-
-
-
- )
-}
-
-function Latency(props: IChartProps) {
- const { t } = useTranslation()
- return (
-
-
- {t('overview.metrics.latency')}
-
-
-
- )
-}
-
-function CPU(props: IChartProps) {
+const MetricsWrapper = ({ metricsItem, props }) => {
const { t } = useTranslation()
- return (
-
- {t('overview.metrics.cpu')}
-
-
- )
-}
-function Memory(props: IChartProps) {
- const { t } = useTranslation()
return (
-
-
- {t('overview.metrics.memory')}
+
+
+ {t(`overview.metrics.${metricsItem.title}`)}
)
}
-function IO(props: IChartProps) {
- const { t } = useTranslation()
- return (
-
- {t('overview.metrics.io')}
-
-
- )
-}
-
-export default function Metrics() {
+export default function Metrics(props) {
const ctx = useContext(OverviewContext)
const [timeRange, setTimeRange] = useState(DEFAULT_TIME_RANGE)
const [chartRange, setChartRange] = useTimeRangeValue(timeRange, setTimeRange)
const [isLoading, setIsLoading] = useState>({})
+ const { showAllPanels: showAllPerformanceMetics } = props
+ const { t } = useTranslation()
const isSomeLoading = useMemo(() => {
return some(Object.values(isLoading))
@@ -186,11 +80,18 @@ export default function Metrics() {
}
}
+ console.log('hello from Metrics ')
+
return (
<>
+ {showAllPerformanceMetics && (
+
+ {t('overview.back')}
+
+ )}
{isSomeLoading && }
+
+ {!showAllPerformanceMetics && (
+
+
+
+ )}
+
-
-
-
-
-
-
-
+ ()}>
+
+
+ {MetricsItems.map((item, idx) => (
+ <>
+ {((idx > 1 && showAllPerformanceMetics) || idx < 2) && (
+
+
+
+ {item.metrics.map((m) => (
+
+
+
+ ))}
+
+
+
+ )}
+ >
+ ))}
+
+
+
>
)
}
diff --git a/ui-new/packages/tidb-dashboard-lib/src/apps/Overview/components/MetricsItems.tsx b/ui-new/packages/tidb-dashboard-lib/src/apps/Overview/components/MetricsItems.tsx
new file mode 100644
index 0000000000..f242bb4d32
--- /dev/null
+++ b/ui-new/packages/tidb-dashboard-lib/src/apps/Overview/components/MetricsItems.tsx
@@ -0,0 +1,398 @@
+const MetricsItems = [
+ {
+ category: 'Application Connection',
+ metrics: [
+ {
+ title: 'connection_count',
+ queries: [
+ {
+ query: 'sum(tidb_server_connections)',
+ name: 'total'
+ },
+ {
+ query: 'sum(tidb_server_tokens)',
+ name: 'active connections'
+ }
+ ],
+ unit: null,
+ type: 'line'
+ },
+ {
+ title: 'disconnection',
+ queries: [
+ {
+ query: 'sum(tidb_server_disconnection_total) by (instance, result)',
+ name: '{instance}-{result}'
+ }
+ ],
+ unit: null,
+ type: 'line'
+ },
+ {
+ title: 'connection_idle_duration',
+ queries: [
+ {
+ query: `(sum(rate(tidb_server_conn_idle_duration_seconds_sum{in_txn='1'}[$__rate_interval])) / sum(rate(tidb_server_conn_idle_duration_seconds_count{in_txn='1'}[$__rate_interval])))`,
+ name: 'avg-in-txn'
+ },
+ {
+ query: `(sum(rate(tidb_server_conn_idle_duration_seconds_sum{in_txn='0'}[$__rate_interval])) / sum(rate(tidb_server_conn_idle_duration_seconds_count{in_txn='0'}[$__rate_interval])))`,
+ name: 'avg-not-in-txn'
+ }
+ ],
+ unit: 's',
+ type: 'line'
+ }
+ ]
+ },
+ {
+ category: 'Database Time',
+ metrics: [
+ {
+ title: 'database_time',
+ queries: [
+ {
+ query: `sum(rate(tidb_server_handle_query_duration_seconds_sum{sql_type!="internal"}[$__rate_interval]))`,
+ name: 'database time'
+ }
+ ],
+ unit: 's',
+ type: 'line'
+ },
+ {
+ title: 'database_time_by_sql_type',
+ queries: [
+ {
+ query: `sum(rate(tidb_server_handle_query_duration_seconds_sum{sql_type!="internal"}[$__rate_interval])) by (sql_type)`,
+ name: '{sql_type}'
+ }
+ ],
+ unit: 's',
+ type: 'line'
+ },
+ {
+ title: 'database_time_by_steps_of_sql_processig',
+ queries: [
+ {
+ query: `sum(rate(tidb_session_parse_duration_seconds_sum{sql_type="general"}[$__rate_interval]))`,
+ name: 'parse'
+ },
+ {
+ query: `sum(rate(tidb_session_compile_duration_seconds_sum{sql_type="general"}[$__rate_interval]))`,
+ name: 'compile'
+ },
+ {
+ query: `sum(rate(tidb_session_execute_duration_seconds_sum{sql_type="general"}[$__rate_interval]))`,
+ name: 'execute'
+ },
+ {
+ query: `sum(rate(tidb_server_get_token_duration_seconds_sum{sql_type="general"}[$__rate_interval]))/1000000`,
+ name: 'get token'
+ }
+ ],
+ unit: 's',
+ type: 'line'
+ }
+ ]
+ },
+ {
+ category: 'SQL Count',
+ metrics: [
+ {
+ title: 'sql_count_qps',
+ queries: [
+ {
+ query: 'sum(rate(tidb_executor_statement_total[$__rate_interval]))',
+ name: 'total'
+ },
+ {
+ query:
+ 'sum(rate(tidb_executor_statement_total[$__rate_interval])) by (type)',
+ name: '{type}'
+ }
+ ],
+ unit: 'qps',
+ type: 'line'
+ },
+ {
+ title: 'failed_queries',
+ queries: [
+ {
+ query:
+ 'increase(tidb_server_execute_error_total[$__rate_interval])',
+ name: '{type} @ {instance}'
+ }
+ ],
+ unit: null,
+ type: 'line'
+ },
+ {
+ title: 'cps',
+ queries: [
+ {
+ query:
+ 'sum(rate(tidb_server_query_total[$__rate_interval])) by (result)',
+ name: 'query {type}'
+ }
+ ],
+ unit: null,
+ type: 'line'
+ }
+ ]
+ },
+ {
+ category: 'Core Feature Usage',
+ metrics: [
+ {
+ title: 'ops',
+ queries: [
+ {
+ query:
+ 'sum(rate(tidb_server_plan_cache_total[$__rate_interval])) by (type)',
+ name: 'avg'
+ }
+ ],
+ unit: null,
+ type: 'line'
+ }
+ ]
+ },
+ {
+ category: 'Latency break down',
+ metrics: [
+ {
+ title: 'query',
+ queries: [
+ {
+ query:
+ 'sum(rate(tidb_server_handle_query_duration_seconds_sum{sql_type!="internal"}[$__rate_interval])) / sum(rate(tidb_server_handle_query_duration_seconds_count{sql_type!="internal"}[$__rate_interval]))',
+ name: 'avg'
+ },
+ {
+ query:
+ 'histogram_quantile(0.99, sum(rate(tidb_server_handle_query_duration_seconds_bucket{sql_type!="internal"}[$__rate_interval])) by (le))',
+ name: '99'
+ },
+ {
+ query:
+ 'sum(rate(tidb_server_handle_query_duration_seconds_sum{sql_type!="internal"}[$__rate_interval])) by (sql_type) / sum(rate(tidb_server_handle_query_duration_seconds_count{sql_type!="internal"}[$__rate_interval])) by (sql_type)',
+ name: 'avg-{sql_type}'
+ },
+ {
+ query:
+ 'histogram_quantile(0.99, sum(rate(tidb_server_handle_query_duration_seconds_bucket{sql_type!="internal"}[$__rate_interval])) by (le,sql_type))',
+ name: '99-{{sql_type}}'
+ }
+ ],
+ unit: 's',
+ type: 'line'
+ },
+ {
+ title: 'get_token',
+ queries: [
+ {
+ query:
+ 'sum(rate(tidb_server_get_token_duration_seconds_sum{sql_type="general"}[$__rate_interval])) / sum(rate(tidb_server_get_token_duration_seconds_count{sql_type="general"}[$__rate_interval]))',
+ name: 'avg'
+ },
+ {
+ query:
+ 'histogram_quantile(0.99, sum(rate(tidb_server_get_token_duration_seconds_bucket[$__rate_interval])) by (le))',
+ name: '99'
+ }
+ ],
+ unit: 's',
+ type: 'line'
+ },
+ {
+ title: 'parse',
+ queries: [
+ {
+ query:
+ '(sum(rate(tidb_session_parse_duration_seconds_sum{sql_type="general"}[$__rate_interval])) / sum(rate(tidb_session_parse_duration_seconds_count{sql_type="general"}[$__rate_interval])))',
+ name: 'avg'
+ },
+ {
+ query:
+ 'histogram_quantile(0.99, sum(rate(tidb_session_parse_duration_seconds_bucket{sql_type="general"}[$__rate_interval])) by (le))',
+ name: '99%'
+ }
+ ],
+ unit: 's',
+ type: 'line'
+ },
+ {
+ title: 'compile',
+ queries: [
+ {
+ query:
+ '(sum(rate(tidb_session_compile_duration_seconds_sum{sql_type="general"}[$__rate_interval])) / sum(rate(tidb_session_compile_duration_seconds_count{sql_type="general"}[$__rate_interval])))',
+ name: 'avg'
+ },
+ {
+ query:
+ 'histogram_quantile(0.99, sum(rate(tidb_session_compile_duration_seconds_bucket{sql_type="general"}[$__rate_interval])) by (le))',
+ name: '99%'
+ }
+ ],
+ unit: 's',
+ type: 'line'
+ },
+ {
+ title: 'execution',
+ queries: [
+ {
+ query:
+ '(sum(rate(tidb_session_execute_duration_seconds_sum{sql_type="general"}[$__rate_interval])) / sum(rate(tidb_session_execute_duration_seconds_count{sql_type="general"}[$__rate_interval])))',
+ name: 'avg'
+ },
+ {
+ query:
+ 'histogram_quantile(0.99, sum(rate(tidb_session_execute_duration_seconds_bucket{sql_type="general"}[$__rate_interval])) by (le))',
+ name: '99%'
+ }
+ ],
+ unit: 's',
+ type: 'line'
+ }
+ ]
+ },
+ {
+ category: 'Transaction',
+ metrics: [
+ {
+ title: 'tps',
+ queries: [
+ {
+ query:
+ 'sum(rate(tidb_session_transaction_duration_seconds_count[$__rate_interval])) by (type, txn_mode)',
+ name: '{type}-{txn_mode}'
+ }
+ ],
+ unit: 's',
+ type: 'line'
+ },
+ {
+ id: 'average_duration',
+ title: 'transaction_average_duration',
+ queries: [
+ {
+ query:
+ 'sum(rate(tidb_session_transaction_duration_seconds_sum[$__rate_interval])) by (txn_mode)/ sum(rate(tidb_session_transaction_duration_seconds_count[$__rate_interval])) by (txn_mode)',
+ name: 'avg'
+ },
+ {
+ query:
+ 'histogram_quantile(0.99, sum(rate(tidb_session_transaction_duration_seconds_bucket[$__rate_interval])) by (le, txn_mode))',
+ name: '99-{txn_mode}'
+ }
+ ],
+ unit: 's',
+ type: 'line'
+ }
+ ]
+ },
+ {
+ category: 'Server',
+ metrics: [
+ {
+ title: 'tidb_uptime',
+ queries: [
+ {
+ query: '(time() - process_start_time_seconds{job="tidb"})',
+ name: '{instance}'
+ }
+ ],
+ unit: 's',
+ type: 'line'
+ },
+ {
+ title: 'tidb_cpu_usage',
+ queries: [
+ {
+ query:
+ 'rate(process_cpu_seconds_total{job="tidb"}[$__rate_interval])',
+ name: '{instance}'
+ }
+ ],
+ unit: 'percent',
+ type: 'line'
+ },
+ {
+ title: 'tidb_memory_usage',
+ queries: [
+ {
+ query: 'process_resident_memory_bytes{job="tidb"}',
+ name: '{instance}'
+ }
+ ],
+ unit: 'decbytes',
+ type: 'line'
+ },
+ {
+ title: 'tikv_uptime',
+ queries: [
+ {
+ query: '(time() - process_start_time_seconds{job="tikv"})',
+ name: '{instance}'
+ }
+ ],
+ unit: 's',
+ type: 'line'
+ },
+ {
+ title: 'tikv_cpu_usage',
+ queries: [
+ {
+ query:
+ 'sum(rate(tikv_thread_cpu_seconds_total[$__rate_interval])) by (instance)',
+ name: '{instance}'
+ }
+ ],
+ unit: 'percent',
+ type: 'line'
+ },
+ {
+ title: 'tikv_memory_usage',
+ queries: [
+ {
+ query: 'process_resident_memory_bytes{job=~".*tikv"}',
+ name: '{instance}'
+ }
+ ],
+ unit: 'decbytes',
+ type: 'line'
+ },
+ {
+ title: 'tikv_io_mbps',
+ queries: [
+ {
+ query:
+ 'sum(rate(tikv_engine_flow_bytes{db="raft", type="wal_file_bytes"}[$__rate_interval])) by (instance) + sum(rate(raft_engine_write_size_sum[$__rate_interval])) by (instance)',
+ name: '{instance}-write'
+ },
+ {
+ query:
+ 'sum(rate(tikv_engine_flow_bytes{db="kv", type=~"bytes_read|iter_bytes_read"}[$__rate_interval])) by (instance)',
+ name: '{instance}-read'
+ }
+ ],
+ unit: 'decbytes',
+ type: 'line'
+ },
+ {
+ title: 'tikv_storage_usage',
+ queries: [
+ {
+ query: 'sum(tikv_store_size_bytes{type="used"}) by (instance)',
+ name: '{instance}'
+ }
+ ],
+ unit: 'decbytes',
+ type: 'line'
+ }
+ ]
+ }
+]
+
+export { MetricsItems }
diff --git a/ui-new/packages/tidb-dashboard-lib/src/apps/Overview/components/MonitorAlert.tsx b/ui-new/packages/tidb-dashboard-lib/src/apps/Overview/components/MonitorAlert.tsx
index 37e8f7492b..d5f58876e3 100644
--- a/ui-new/packages/tidb-dashboard-lib/src/apps/Overview/components/MonitorAlert.tsx
+++ b/ui-new/packages/tidb-dashboard-lib/src/apps/Overview/components/MonitorAlert.tsx
@@ -39,7 +39,7 @@ export default function MonitorAlert() {
}, [amData, ctx])
return (
-
+
- {t('overview.monitor_alert.view_monitor')}
+ {t('overview.monitor_alert.view_grafana_monitor')}
diff --git a/ui-new/packages/tidb-dashboard-lib/src/apps/Overview/index.tsx b/ui-new/packages/tidb-dashboard-lib/src/apps/Overview/index.tsx
index d4667c243b..68a4b60f6a 100644
--- a/ui-new/packages/tidb-dashboard-lib/src/apps/Overview/index.tsx
+++ b/ui-new/packages/tidb-dashboard-lib/src/apps/Overview/index.tsx
@@ -1,40 +1,22 @@
import React, { useContext } from 'react'
-import { Col, Row } from 'antd'
import { HashRouter as Router, Routes, Route } from 'react-router-dom'
import { Root } from '@lib/components'
import { addTranslations } from '@lib/utils/i18n'
-import MonitorAlert from './components/MonitorAlert'
-import Instances from './components/Instances'
-import Metrics from './components/Metrics'
-
import translations from './translations'
import { OverviewContext } from './context'
import { useLocationChange } from '@lib/hooks/useLocationChange'
+import { List, Detail } from './pages'
addTranslations(translations)
-function Overview() {
- return (
-
-
-
-
-
-
-
-
-
- )
-}
-
function AppRoutes() {
useLocationChange()
-
return (
- } />
+ } />
+ } />
)
}
diff --git a/ui-new/packages/tidb-dashboard-lib/src/apps/Overview/pages/Detail/index.tsx b/ui-new/packages/tidb-dashboard-lib/src/apps/Overview/pages/Detail/index.tsx
new file mode 100644
index 0000000000..8880696a4d
--- /dev/null
+++ b/ui-new/packages/tidb-dashboard-lib/src/apps/Overview/pages/Detail/index.tsx
@@ -0,0 +1,6 @@
+import React from 'react'
+import Metrics from '../../components/Metrics'
+
+export default function Detail() {
+ return
+}
diff --git a/ui-new/packages/tidb-dashboard-lib/src/apps/Overview/pages/List/index.tsx b/ui-new/packages/tidb-dashboard-lib/src/apps/Overview/pages/List/index.tsx
new file mode 100644
index 0000000000..0492ef84b6
--- /dev/null
+++ b/ui-new/packages/tidb-dashboard-lib/src/apps/Overview/pages/List/index.tsx
@@ -0,0 +1,19 @@
+import { Col, Row } from 'antd'
+import React from 'react'
+import MonitorAlert from '../../components/MonitorAlert'
+import Instances from '../../components/Instances'
+import Metrics from '../../components/Metrics'
+
+export default function List() {
+ return (
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/ui-new/packages/tidb-dashboard-lib/src/apps/Overview/pages/index.tsx b/ui-new/packages/tidb-dashboard-lib/src/apps/Overview/pages/index.tsx
new file mode 100644
index 0000000000..641e4de57a
--- /dev/null
+++ b/ui-new/packages/tidb-dashboard-lib/src/apps/Overview/pages/index.tsx
@@ -0,0 +1,4 @@
+import List from './List'
+import Detail from './Detail'
+
+export { List, Detail }
diff --git a/ui-new/packages/tidb-dashboard-lib/src/apps/Overview/translations/en.yaml b/ui-new/packages/tidb-dashboard-lib/src/apps/Overview/translations/en.yaml
index 1f7f2301c9..6df39820c7 100644
--- a/ui-new/packages/tidb-dashboard-lib/src/apps/Overview/translations/en.yaml
+++ b/ui-new/packages/tidb-dashboard-lib/src/apps/Overview/translations/en.yaml
@@ -1,5 +1,7 @@
overview:
nav_title: Overview
+ back: Back
+ view_more_metrics: View More Metrics
top_statements:
title: Time Consuming SQL Statements
recent_slow_query:
@@ -8,15 +10,35 @@ overview:
title: Alive Instances
monitor_alert:
title: Monitor & Alert
- view_monitor: View Metrics
+ view_grafana_monitor: View Grafana Metrics
view_monitor_warn: Metrics unavailable
view_alerts: 'View {{alertCount}} Alerts'
view_zero_alerts: 'View Alerts'
view_alerts_warn: Alert unavailable
run_diagnose: Run Diagnostics
metrics:
- total_requests: QPS
- latency: Latency
- cpu: CPU Utilization
- memory: Memory Utilization
- io: IO Utilization
+ connection_count: Connection Count
+ disconnection: Disconnection
+ connection_idle_duration: Average Idle Connection Duration
+ database_time: Database Time
+ database_time_by_sql_type: Database Time by SQL Types
+ database_time_by_steps_of_sql_processig: Database Time by Steps of SQL Processing
+ sql_count_qps: Query Per Second
+ failed_queries: Failed Queries
+ cps: Command Per Second
+ ops: Queries Using Plan Cache OPS
+ query: Query Duration
+ get_token: Get Token Duration
+ parse: Parse Duration
+ compile: Compile Duration
+ execution: Execution Duraion
+ tps: Transaction Per Second
+ transaction_average_duration: Transaction Duration
+ tidb_uptime: TiDB Uptime
+ tidb_cpu_usage: TiDB CPU Usage
+ tidb_memory_usage: TiDB Memory Usage
+ tikv_uptime: TiKV Uptime
+ tikv_cpu_usage: TiKV CPU Usage
+ tikv_memory_usage: TiKV Memory Usage
+ tikv_io_mbps: TiKV IO MBps
+ tikv_storage_usage: TiKV Storage Usage
diff --git a/ui-new/packages/tidb-dashboard-lib/src/apps/Overview/translations/zh.yaml b/ui-new/packages/tidb-dashboard-lib/src/apps/Overview/translations/zh.yaml
index 156eb794c7..0c89de7f30 100644
--- a/ui-new/packages/tidb-dashboard-lib/src/apps/Overview/translations/zh.yaml
+++ b/ui-new/packages/tidb-dashboard-lib/src/apps/Overview/translations/zh.yaml
@@ -1,5 +1,7 @@
overview:
nav_title: 概况
+ back: 返回
+ view_more_metrics: 查看更多指标
top_statements:
title: 最耗时的 SQL 语句
recent_slow_query:
@@ -8,15 +10,35 @@ overview:
title: 在线实例
monitor_alert:
title: 监控和告警
- view_monitor: 查看监控
+ view_grafana_monitor: 查看监控
view_monitor_warn: 监控不可用
view_alerts: '查看 {{alertCount}} 条告警'
view_zero_alerts: 查看告警
view_alerts_warn: 告警不可用
run_diagnose: 运行诊断
metrics:
- total_requests: QPS
- latency: 延迟
- cpu: CPU 使用率
- memory: 内存使用率
- io: IO 使用率
+ connection_count: Connection Count
+ disconnection: Disconnection
+ connection_idle_duration: Average Idle Connection Duration
+ database_time: Database Time
+ database_time_by_sql_type: Database Time by SQL Types
+ database_time_by_steps_of_sql_processig: Database Time by Steps of SQL Processing
+ sql_count_qps: Query Per Second
+ failed_queries: Failed Queries
+ cps: Command Per Second
+ ops: Queries Using Plan Cache OPS
+ query: Query Duration
+ get_token: Get Token Duration
+ parse: Parse Duration
+ compile: Compile Duration
+ execution: Execution Duraion
+ tps: Transaction Per Second
+ transaction_average_duration: Transaction Duration
+ tidb_uptime: TiDB Uptime
+ tidb_cpu_usage: TiDB CPU Usage
+ tidb_memory_usage: TiDB Memory Usage
+ tikv_uptime: TiKV Uptime
+ tikv_cpu_usage: TiKV CPU Usage
+ tikv_memory_usage: TiKV Memory Usage
+ tikv_io_mbps: TiKV IO MBps
+ tikv_storage_usage: TiKV Storage Usage
diff --git a/ui-new/packages/tidb-dashboard-lib/src/components/MetricChart/ChartContext.tsx b/ui-new/packages/tidb-dashboard-lib/src/components/MetricChart/ChartContext.tsx
new file mode 100644
index 0000000000..b8f42f478d
--- /dev/null
+++ b/ui-new/packages/tidb-dashboard-lib/src/components/MetricChart/ChartContext.tsx
@@ -0,0 +1,7 @@
+import React from 'react'
+import { PointerEvent } from '@elastic/charts'
+import { EventEmitter } from 'ahooks/lib/useEventEmitter'
+
+export const ChartContext = React.createContext>(
+ null as any
+)
diff --git a/ui-new/packages/tidb-dashboard-lib/src/components/MetricChart/index.tsx b/ui-new/packages/tidb-dashboard-lib/src/components/MetricChart/index.tsx
index b10a185423..3ae6fab332 100644
--- a/ui-new/packages/tidb-dashboard-lib/src/components/MetricChart/index.tsx
+++ b/ui-new/packages/tidb-dashboard-lib/src/components/MetricChart/index.tsx
@@ -1,4 +1,10 @@
-import React, { useCallback, useMemo, useRef, useState } from 'react'
+import React, {
+ useCallback,
+ useContext,
+ useMemo,
+ useRef,
+ useState
+} from 'react'
import { Space } from 'antd'
import _ from 'lodash'
import format from 'string-template'
@@ -17,7 +23,8 @@ import {
LineSeries,
Position,
ScaleType,
- Settings
+ Settings,
+ PointerEvent
} from '@elastic/charts'
import { GraphType, QueryData, renderQueryData } from './seriesRenderer'
import {
@@ -36,6 +43,7 @@ import {
} from '@lib/utils/prometheus'
import { AxiosPromise } from 'axios'
import { ReqConfig } from '@lib/types'
+import { ChartContext } from './ChartContext'
export type { GraphType }
@@ -87,7 +95,7 @@ export interface IMetricChartProps {
yDomain?: DomainRange
queries: IQueryOption[]
- unit: string
+ unit?: string
type: GraphType
height?: number
@@ -121,11 +129,14 @@ export default function MetricChart({
onLoadingStateChange,
getMetrics
}: IMetricChartProps) {
+ const chartRef = useRef(null)
const chartContainerRef = useRef(null)
const [chartHandle] = useChartHandle(chartContainerRef, 150)
const [isLoading, setLoading] = useState(false)
const [data, setData] = useState(null)
const [error, setError] = useState(null)
+ const ee = useContext(ChartContext)
+ ee.useSubscription((e) => chartRef.current?.dispatchExternalPointerEvent(e))
useChange(() => {
onLoadingStateChange?.(isLoading)
@@ -254,12 +265,13 @@ export default function MetricChart({
)
} else {
inner = (
-
+
ee.emit(e)}
/>
getValueFormat(unit)(v, 2)}
+ tickFormat={(v) =>
+ unit ? getValueFormat(unit)(v, 2) : Number(v).toFixed(0)
+ }
ticks={5}
domain={yDomain}
/>
diff --git a/ui/lib/apps/Overview/components/Instances.tsx b/ui/lib/apps/Overview/components/Instances.tsx
index 8748b396af..679461efa3 100644
--- a/ui/lib/apps/Overview/components/Instances.tsx
+++ b/ui/lib/apps/Overview/components/Instances.tsx
@@ -90,7 +90,7 @@ export default function Nodes() {
}
- noMarginLeft
+ noMarginRight
>
diff --git a/ui/lib/apps/Overview/components/Metrics.tsx b/ui/lib/apps/Overview/components/Metrics.tsx
index e0f30921e2..eb3f5b8a42 100644
--- a/ui/lib/apps/Overview/components/Metrics.tsx
+++ b/ui/lib/apps/Overview/components/Metrics.tsx
@@ -1,4 +1,4 @@
-import { Space, Typography } from 'antd'
+import { Space, Typography, Row, Col, Collapse, Button } from 'antd'
import React, { useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import {
@@ -10,27 +10,169 @@ import {
TimeRangeSelector,
Toolbar,
} from '@lib/components'
+import { Link } from 'react-router-dom'
import { Range } from '@elastic/charts/dist/utils/domain'
import { Stack } from 'office-ui-fabric-react'
import { useTimeRangeValue } from '@lib/components/TimeRangeSelector/hook'
-import { LoadingOutlined } from '@ant-design/icons'
+import { LoadingOutlined, ArrowLeftOutlined } from '@ant-design/icons'
import { some } from 'lodash'
+import { PointerEvent } from '@elastic/charts'
+
+import { ChartContext } from '../../../components/MetricChart/ChartContext'
+import { useEventEmitter } from 'ahooks'
+
interface IChartProps {
range: Range
onRangeChange?: (newRange: Range) => void
onLoadingStateChange?: (isLoading: boolean) => void
}
+function Connection(props: IChartProps) {
+ const { t } = useTranslation()
+ return (
+
+
+ {t(`overview.metrics.connection.total`)}
+
+
+
+ )
+}
+
+function Disconnection(props: IChartProps) {
+ const { t } = useTranslation()
+ return (
+
+
+ {t(`overview.metrics.connection.disconnection`)}
+
+
+
+ )
+}
+
+function ConnectionIdleDuration(props: IChartProps) {
+ const { t } = useTranslation()
+ return (
+
+
+ {t('overview.metrics.connection.idle')}
+
+
+
+ )
+}
+
+function DatabaseTime(props: IChartProps) {
+ const { t } = useTranslation()
+ return (
+
+
+ {t('overview.metrics.database_time.by_sql_type')}
+
+
+
+ )
+}
+
+function DatabaseTimeByPhrase(props: IChartProps) {
+ const { t } = useTranslation()
+ return (
+
+
+ {t('overview.metrics.database_time.by_steps_of_sql_processig')}
+
+
+
+ )
+}
+
function QPS(props: IChartProps) {
const { t } = useTranslation()
return (
-
-
- {t('overview.metrics.total_requests')}
+
+
+ {t('overview.metrics.sql_count.qps')}
+
+ )
+}
+
+function FailedQuery(props: IChartProps) {
+ const { t } = useTranslation()
+ return (
+
+
+ {t('overview.metrics.sql_count.failed_queries')}
+
+
+
+ )
+}
+
+function CPS(props: IChartProps) {
+ const { t } = useTranslation()
+ return (
+
+
+ {t('overview.metrics.sql_count.cps')}
+
+
+
+ )
+}
+
+function OPS(props: IChartProps) {
+ const { t } = useTranslation()
+ return (
+
+
+ {t('overview.metrics.core_feature_usag.ops')}
+
+
@@ -48,26 +256,115 @@ function QPS(props: IChartProps) {
function Latency(props: IChartProps) {
const { t } = useTranslation()
return (
-
-
- {t('overview.metrics.latency')}
+
+
+ {t('overview.metrics.latency.query')}
+
+
+
+ )
+}
+
+function GetTokenDuration(props: IChartProps) {
+ const { t } = useTranslation()
+ return (
+
+
+ {t('overview.metrics.latency.get_token')}
+
+
+
+ )
+}
+
+function ParseDuration(props: IChartProps) {
+ const { t } = useTranslation()
+ return (
+
+
+ {t('overview.metrics.latency.parse')}
+
+ )
+}
+
+function CompileDuration(props: IChartProps) {
+ const { t } = useTranslation()
+ return (
+
+
+ {t('overview.metrics.latency.compile')}
+
+
- {t('overview.metrics.cpu')}
+
+
+ {t('overview.metrics.latency.execution')}
+
+
+ )
+}
+
+function Transaction(props: IChartProps) {
+ const { t } = useTranslation()
+ return (
+
+
+ {t('overview.metrics.transaction.tps')}
+
+
+
+ )
+}
+
+function TransactionDuration(props: IChartProps) {
+ const { t } = useTranslation()
+ return (
+
+
+ {t('overview.metrics.transaction.average_duration')}
+
+
+
+ )
+}
+
+function TiDBUptime(props: IChartProps) {
+ const { t } = useTranslation()
+ return (
+
+
+ {t('overview.metrics.server.tidb_uptime')}
+
+
@@ -100,30 +476,22 @@ function CPU(props: IChartProps) {
)
}
-function Memory(props: IChartProps) {
+// TiDB CPU Usage
+function TiDBCPUUsage(props: IChartProps) {
const { t } = useTranslation()
return (
-
-
- {t('overview.metrics.memory')}
+
+
+ {t('overview.metrics.server.tidb_cpu_usage')}
+
+ {t('overview.metrics.server.tidb_memory_usage')}
+
+
+
+ )
+}
+
+function TiKVUptime(props: IChartProps) {
+ const { t } = useTranslation()
+ return (
+
+
+ {t('overview.metrics.server.tikv_uptime')}
+
+
+
+ )
+}
+
+// TiKV CPU Usage
+function TiKVCPUUsage(props: IChartProps) {
const { t } = useTranslation()
return (
-
- {t('overview.metrics.io')}
+
+
+ {t('overview.metrics.server.tikv_cpu_usage')}
+
+
+ {t('overview.metrics.server.tikv_memory_usage')}
+
+
+
+ )
+}
+
+function TiKVIO(props: IChartProps) {
+ const { t } = useTranslation()
+ return (
+
+
+ {t('overview.metrics.server.tikv_io_mbps')}
+
+
+
+ )
+}
+
+// TODO: check size unit
+function TiKVStorageUsage(props: IChartProps) {
+ const { t } = useTranslation()
+ return (
+
+
+ {t('overview.metrics.server.tikv_storage_usage')}
+
+
+
+ )
+}
+
+export default function Metrics(props) {
const [timeRange, setTimeRange] = useState(DEFAULT_TIME_RANGE)
const [chartRange, setChartRange] = useTimeRangeValue(timeRange, setTimeRange)
const [isLoading, setIsLoading] = useState>({})
+ const [pointerEvent, setPointerEvent] = useState()
+ const { allTypes: showAllPerformanceMetics } = props
+ const { t } = useTranslation()
const isSomeLoading = useMemo(() => {
return some(Object.values(isLoading))
@@ -177,6 +669,11 @@ export default function Metrics() {
+ {showAllPerformanceMetics && (
+
+ {t('overview.back')}
+
+ )}
{isSomeLoading && }
+
+ {!showAllPerformanceMetics && (
+
+
+
+ )}
+
-
-
-
-
-
-
-
+
+ ()}>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {showAllPerformanceMetics && (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ )}
+
+
+
>
)
}
diff --git a/ui/lib/apps/Overview/components/MonitorAlert.tsx b/ui/lib/apps/Overview/components/MonitorAlert.tsx
index fdb6160d91..3a757ba902 100644
--- a/ui/lib/apps/Overview/components/MonitorAlert.tsx
+++ b/ui/lib/apps/Overview/components/MonitorAlert.tsx
@@ -33,7 +33,7 @@ export default function MonitorAlert() {
}, [amData])
return (
-
+
- {t('overview.monitor_alert.view_monitor')}
+ {t('overview.monitor_alert.view_grafana_monitor')}
diff --git a/ui/lib/apps/Overview/index.tsx b/ui/lib/apps/Overview/index.tsx
index 201e1ff37f..3a80116d72 100644
--- a/ui/lib/apps/Overview/index.tsx
+++ b/ui/lib/apps/Overview/index.tsx
@@ -1,24 +1,17 @@
-import { Col, Row } from 'antd'
import React from 'react'
-import { HashRouter as Router } from 'react-router-dom'
+import { HashRouter as Router, Route, Routes } from 'react-router-dom'
import { Root } from '@lib/components'
-import MonitorAlert from './components/MonitorAlert'
-import Instances from './components/Instances'
-import Metrics from './components/Metrics'
+
+import { List, Detail } from './pages'
export default function App() {
return (
-
-
-
-
-
-
-
-
-
+
+ } />
+ } />
+
)
diff --git a/ui/lib/apps/Overview/pages/Detail/index.tsx b/ui/lib/apps/Overview/pages/Detail/index.tsx
new file mode 100644
index 0000000000..aefd05cd1f
--- /dev/null
+++ b/ui/lib/apps/Overview/pages/Detail/index.tsx
@@ -0,0 +1,6 @@
+import React from 'react'
+import Metrics from '../../components/Metrics'
+
+export default function Detail() {
+ return
+}
diff --git a/ui/lib/apps/Overview/pages/List/index.tsx b/ui/lib/apps/Overview/pages/List/index.tsx
new file mode 100644
index 0000000000..0492ef84b6
--- /dev/null
+++ b/ui/lib/apps/Overview/pages/List/index.tsx
@@ -0,0 +1,19 @@
+import { Col, Row } from 'antd'
+import React from 'react'
+import MonitorAlert from '../../components/MonitorAlert'
+import Instances from '../../components/Instances'
+import Metrics from '../../components/Metrics'
+
+export default function List() {
+ return (
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/ui/lib/apps/Overview/pages/index.tsx b/ui/lib/apps/Overview/pages/index.tsx
new file mode 100644
index 0000000000..641e4de57a
--- /dev/null
+++ b/ui/lib/apps/Overview/pages/index.tsx
@@ -0,0 +1,4 @@
+import List from './List'
+import Detail from './Detail'
+
+export { List, Detail }
diff --git a/ui/lib/apps/Overview/translations/en.yaml b/ui/lib/apps/Overview/translations/en.yaml
index 1f7f2301c9..458629d45e 100644
--- a/ui/lib/apps/Overview/translations/en.yaml
+++ b/ui/lib/apps/Overview/translations/en.yaml
@@ -1,5 +1,7 @@
overview:
nav_title: Overview
+ back: Back
+ view_more_metrics: View More Metrics
top_statements:
title: Time Consuming SQL Statements
recent_slow_query:
@@ -8,15 +10,44 @@ overview:
title: Alive Instances
monitor_alert:
title: Monitor & Alert
- view_monitor: View Metrics
+ view_grafana_monitor: View Grafana Metrics
view_monitor_warn: Metrics unavailable
view_alerts: 'View {{alertCount}} Alerts'
view_zero_alerts: 'View Alerts'
view_alerts_warn: Alert unavailable
run_diagnose: Run Diagnostics
metrics:
- total_requests: QPS
- latency: Latency
- cpu: CPU Utilization
- memory: Memory Utilization
- io: IO Utilization
+ connection:
+ total: Total Connection
+ active: Active Connection
+ disconnection: Disconnection
+ idle: Average Idle Connection Duration
+ database_time:
+ total: Database Time
+ by_sql_type: Database Time by SQL Types
+ by_steps_of_sql_processig: Database Time by Steps of SQL Processing
+ sql_count:
+ qps: Query Per Second
+ failed_queries: Failed Queries
+ cps: Command Per Second
+ core_feature_usag:
+ ops: Queries Using Plan Cache OPS
+ latency:
+ query: Query Duration
+ get_token: Get Token Duration
+ parse: Parse Duration
+ compile: Compile Duration
+ execution: Execution Duraion
+ transaction:
+ tps: Transaction Per Second
+ average_duration: Transaction Duration
+ server:
+ tidb_uptime: TiDB Uptime
+ tidb_cpu_usage: TiDB CPU Usage
+ tidb_memory_usage: TiDB Memory Usage
+ tikv_uptime: TiKV Uptime
+ tikv_cpu_usage: TiKV CPU Usage
+ tikv_memory_usage: TiKV Memory Usage
+ tikv_io_mbps: TiKV IO MBps
+ tikv_storage_usage: TiKV Storage Usage
+ connection_count: Connection Count
diff --git a/ui/lib/apps/Overview/translations/zh.yaml b/ui/lib/apps/Overview/translations/zh.yaml
index 156eb794c7..ed482093f2 100644
--- a/ui/lib/apps/Overview/translations/zh.yaml
+++ b/ui/lib/apps/Overview/translations/zh.yaml
@@ -1,5 +1,7 @@
overview:
nav_title: 概况
+ back: 返回
+ view_more_metrics: 查看更多指标
top_statements:
title: 最耗时的 SQL 语句
recent_slow_query:
@@ -8,15 +10,44 @@ overview:
title: 在线实例
monitor_alert:
title: 监控和告警
- view_monitor: 查看监控
+ view_grafana_monitor: 查看监控
view_monitor_warn: 监控不可用
view_alerts: '查看 {{alertCount}} 条告警'
view_zero_alerts: 查看告警
view_alerts_warn: 告警不可用
run_diagnose: 运行诊断
metrics:
- total_requests: QPS
- latency: 延迟
- cpu: CPU 使用率
- memory: 内存使用率
- io: IO 使用率
+ connection:
+ total: Total Connection
+ active: Active Connection
+ disconnection: Disconnection
+ idle: Average Idle Connection Duration
+ database_time:
+ total: Database Time
+ by_sql_type: Database Time by SQL Types
+ by_steps_of_sql_processig: Database Time by Steps of SQL Processing
+ sql_count:
+ qps: Query Per Second
+ failed_queries: Failed Queries
+ cps: Command Per Second
+ core_feature_usag:
+ ops: Queries Using Plan Cache OPS
+ latency:
+ query: Query Duration
+ get_token: Get Token Duration
+ parse: Parse Duration
+ compile: Compile Duration
+ execution: Execution Duraion
+ transaction:
+ tps: Transaction Per Second
+ average_duration: Transaction Duration
+ server:
+ tidb_uptime: TiDB Uptime
+ tidb_cpu_usage: TiDB CPU Usage
+ tidb_memory_usage: TiDB Memory Usage
+ tikv_uptime: TiKV Uptime
+ tikv_cpu_usage: TiKV CPU Usage
+ tikv_memory_usage: TiKV Memory Usage
+ tikv_io_mbps: TiKV IO MBps
+ tikv_storage_usage: TiKV Storage Usage
+ connection_count: Connection Count
diff --git a/ui/lib/components/MetricChart/ChartContext.tsx b/ui/lib/components/MetricChart/ChartContext.tsx
new file mode 100644
index 0000000000..b8f42f478d
--- /dev/null
+++ b/ui/lib/components/MetricChart/ChartContext.tsx
@@ -0,0 +1,7 @@
+import React from 'react'
+import { PointerEvent } from '@elastic/charts'
+import { EventEmitter } from 'ahooks/lib/useEventEmitter'
+
+export const ChartContext = React.createContext>(
+ null as any
+)
diff --git a/ui/lib/components/MetricChart/index.tsx b/ui/lib/components/MetricChart/index.tsx
index d3b5e4661a..30d5d08e1d 100644
--- a/ui/lib/components/MetricChart/index.tsx
+++ b/ui/lib/components/MetricChart/index.tsx
@@ -1,6 +1,12 @@
import { Space } from 'antd'
import _ from 'lodash'
-import React, { useCallback, useMemo, useRef, useState } from 'react'
+import React, {
+ useCallback,
+ useContext,
+ useMemo,
+ useRef,
+ useState,
+} from 'react'
import format from 'string-template'
import { getValueFormat } from '@baurine/grafana-value-formats'
import client, { ErrorStrategy } from '@lib/client'
@@ -18,6 +24,7 @@ import {
Position,
ScaleType,
Settings,
+ PointerEvent,
} from '@elastic/charts'
import { GraphType, QueryData, renderQueryData } from './seriesRenderer'
import {
@@ -35,6 +42,8 @@ import {
resolveQueryTemplate,
} from '@lib/utils/prometheus'
+import { ChartContext } from './ChartContext'
+
export type { GraphType }
const translations = {
@@ -85,7 +94,7 @@ export interface IMetricChartProps {
yDomain?: DomainRange
queries: IQueryOption[]
- unit: string
+ unit?: string
type: GraphType
height?: number
@@ -111,12 +120,17 @@ export default function MetricChart({
onRangeChange,
onLoadingStateChange,
}: IMetricChartProps) {
+ const chartRef = useRef(null)
const chartContainerRef = useRef(null)
const [chartHandle] = useChartHandle(chartContainerRef, 150)
const [isLoading, setLoading] = useState(false)
const [data, setData] = useState(null)
const [error, setError] = useState(null)
+ const ee = useContext(ChartContext)
+
+ ee.useSubscription((e) => chartRef.current?.dispatchExternalPointerEvent(e))
+
useChange(() => {
onLoadingStateChange?.(isLoading)
}, [isLoading])
@@ -245,11 +259,13 @@ export default function MetricChart({
)
} else {
inner = (
-
+
ee.emit(e)}
+ legendSize={130}
onBrushEnd={handleBrushEnd}
/>
getValueFormat(unit)(v, 2)}
+ tickFormat={(v) =>
+ unit ? getValueFormat(unit)(v, 2) : Number(v).toFixed(0)
+ }
ticks={5}
domain={yDomain}
/>