Unverified Commit be4fffc5 authored by zsnmwy's avatar zsnmwy
Browse files

feat: Add PieChart

Signed-off-by: default avatarzsnmwy <szlszl35622@gmail.com>
parent 9b47a36d
Showing with 198 additions and 51 deletions
+198 -51
import { useCraneUrl } from '../../hooks';
import { Card, CardProps, DateRangePicker, MessagePlugin, Popup } from 'tdesign-react';
import React, { useState } from 'react';
import ReactEcharts from 'echarts-for-react';
import dayjs from 'dayjs';
import { TimeIcon } from 'tdesign-icons-react';
import { useRangePrometheusQuery } from '../../services/prometheusApi';
export interface IPieChart {
title?: string;
subTitle?: string;
// DatePicker option
datePicker?: boolean;
// Prometheus Query Time Range unit: second e.g. 1h => 3600
timeRange?: number;
// Prometheus Query Step e.g. 15m
step?: string;
// legend: string[];
query: string;
}
const fetchPieData = (craneUrl, title, timeDateRangePicker, step, query) => {
const start = dayjs(timeDateRangePicker[0]).valueOf();
const end = dayjs(timeDateRangePicker[1]).valueOf();
const { data, isError } = useRangePrometheusQuery({ craneUrl, start, end, step, query });
if (isError) MessagePlugin.error(`[${title}] Check Your Network Or Query Params !!!`, 10 * 1000);
const result: never[] = [];
data?.data?.map((namesapce) => {
const namespaceName = namesapce.metric.namespace;
namesapce.values.map((value) => {
const timestamp = dayjs(value[0]).format('MM-DD');
// const timestamp = value[0];
const metricValue = value[1];
if (typeof result[timestamp] !== 'object') result[timestamp] = [];
const item = {
name: namespaceName,
value: metricValue,
};
result[timestamp].push(item);
return value;
});
return namesapce;
});
return result;
};
const PieChart = ({ title, subTitle, datePicker, timeRange, step, query }: IPieChart) => {
const craneUrl: any = useCraneUrl();
// Time
let timeDateRangePicker;
let setTimeDateRangePicker: (arg0: any) => void;
if (timeRange != null) {
[timeDateRangePicker, setTimeDateRangePicker] = useState([
dayjs().subtract(timeRange, 's').format('YYYY-MM-DD'),
dayjs().subtract(0, 's').format('YYYY-MM-DD HH:mm:ss'),
]);
} else {
[timeDateRangePicker, setTimeDateRangePicker] = useState([
dayjs().subtract(3, 'days').format('YYYY-MM-DD'),
dayjs().subtract(0, 's').format('YYYY-MM-DD HH:mm:ss'),
]);
}
const [presets] = useState({
最近7天: [dayjs().subtract(7, 'day'), dayjs()],
最近3天: [dayjs().subtract(3, 'day'), dayjs()],
最近2天: [dayjs().subtract(2, 'day'), dayjs()],
最近1天: [dayjs().subtract(1, 'day'), dayjs()],
实时: [dayjs(), dayjs()],
});
const onTimeChange = (time: any) => {
console.log(time);
setTimeDateRangePicker(time);
};
// Fetch Data
const pieData = fetchPieData(craneUrl, title, timeDateRangePicker, step, query);
const timeLineData: string[] = [];
const options: { series: { data: any; }[]; }[] = [];
Object.keys(pieData).map(
(value) =>
timeLineData.push(value) &&
options.push({
series: [{ data: pieData[value] }],
}),
);
const dynamicPieChartOption = {
tooltip: {
trigger: 'item',
},
grid: {
top: '0',
right: '0',
},
legend: {
type: 'scroll',
top: '0%',
left: 'center',
},
label: {
show: false,
position: 'center',
},
timeline: {
currentIndex: Object.keys(pieData).length - 1,
bottom: '0',
axisType: 'category',
data: timeLineData,
},
series: [
{
type: 'pie',
height: '90%',
label: {
show: false,
},
},
],
options,
};
return (
<Card
title={title}
subtitle={subTitle}
actions={
datePicker && (
<Popup
attach='body'
content={
<DateRangePicker
mode='date'
placeholder={['开始时间', '结束时间']}
enableTimePicker
value={timeDateRangePicker}
format='YYYY-MM-DD HH:mm'
presets={presets}
onChange={onTimeChange}
/>
}
destroyOnClose={false}
hideEmptyPopup={false}
placement='top'
showArrow={false}
trigger='hover'
>
<TimeIcon />
</Popup>
)
}
>
<ReactEcharts option={dynamicPieChartOption} notMerge={true} lazyUpdate={true} />
</Card>
);
};
export default React.memo(PieChart);
......@@ -82,6 +82,12 @@ const buildLineChartOption = (lineStyle: LineStyle | undefined, linesData: ISeri
legend: {
data: legend,
},
dataZoom: [
{
type: 'slider',
show: true,
},
],
grid: {
left: '1%',
right: '1%',
......
......@@ -5,52 +5,31 @@ import useDynamicChart from 'hooks/useDynamicChart';
import { getLineChartOptions, getPieChartOptions } from '../chart';
import Style from './MiddleChart.module.less';
import SeriesLineChart, { LineStyle } from '../../../../components/SeriesLineChart';
import PieChart from '../../../../components/PieChart';
const lineOptions = getLineChartOptions();
const pieOptions = getPieChartOptions();
const MiddleChart = () => {
const [customOptions, setCustomOptions] = useState(lineOptions);
const onTimeChange = (value: Array<string>) => {
const options = getLineChartOptions(value);
setCustomOptions(options);
};
const dynamicLineChartOption = useDynamicChart(customOptions, {
placeholderColor: ['legend.textStyle.color', 'xAxis.axisLabel.color', 'yAxis.axisLabel.color'],
borderColor: ['series.0.itemStyle.borderColor', 'series.1.itemStyle.borderColor'],
});
const dynamicPieChartOption = useDynamicChart(pieOptions, {
placeholderColor: ['legend.textStyle.color'],
containerColor: ['series.0.itemStyle.borderColor'],
textColor: ['label.color', 'label.color'],
});
return (
<Row gutter={[16, 16]} className={Style.middleChartPanel}>
<Col xs={12} xl={9}>
<SeriesLineChart
title='成本走势'
subTitle='( 元 )'
datePicker={true}
step={'1h'}
lineStyle={LineStyle.Area}
lines={[
{
name: 'Nodes-Monthly-Estimated-Costs',
query: `sum (
const MiddleChart = () => (
<Row gutter={[16, 16]} className={Style.middleChartPanel}>
<Col xs={12} xl={9}>
<SeriesLineChart
title='成本走势'
subTitle='( 元 )'
datePicker={true}
step={'1h'}
lineStyle={LineStyle.Area}
lines={[
{
name: 'Nodes-Monthly-Estimated-Costs',
query: `sum (
avg(
avg_over_time(node_total_hourly_cost[1h])
* on (node) group_left() max(kube_node_labels{label_beta_kubernetes_io_instance_type!~"eklet", label_node_kubernetes_io_instance_type!~"eklet"}) by (node)
)
by (node)) * 730 * (100.0/100.0)`,
},
{
name: 'Total-Requests-Monthly-Estimated-Costs',
query: `sum(
},
{
name: 'Total-Requests-Monthly-Estimated-Costs',
query: `sum(
sum(
sum(kube_pod_container_resource_requests{resource="cpu", unit="core"}) by (container, pod, node, namespace)
* on (node) group_left()
......@@ -71,17 +50,19 @@ sum(
)
) * 730 * (100.0/100.0)`,
},
]}
></SeriesLineChart>
</Col>
<Col xs={12} xl={3}>
<Card title='命名空间成本分布' subtitle='2021-12'>
<ReactEcharts option={dynamicPieChartOption} notMerge={true} lazyUpdate={true} />
</Card>
</Col>
</Row>
);
};
},
]}
></SeriesLineChart>
</Col>
<Col xs={12} xl={3}>
<PieChart
title={'命名空间成本分布'}
datePicker={true}
step={'24h'}
query={`sum(sum_over_time(namespace:container_cpu_usage_costs_hourly:sum_rate{}[7d]) + sum_over_time(namespace:container_memory_usage_costs_hourly:sum_rate{}[7d])) by (namespace) * (100.0/100.0)`}
></PieChart>
</Col>
</Row>
);
export default React.memo(MiddleChart);
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment