diff --git a/src/dashboard-front/src/views/operate-data/statistics-report/components/line-chart.vue b/src/dashboard-front/src/views/operate-data/statistics-report/components/line-chart.vue
index 448dbcc2e..7b114f6c4 100644
--- a/src/dashboard-front/src/views/operate-data/statistics-report/components/line-chart.vue
+++ b/src/dashboard-front/src/views/operate-data/statistics-report/components/line-chart.vue
@@ -1,5 +1,22 @@
 <template>
-  <div v-show="!isEmpty" class="line-chart" :id="instanceId"></div>
+  <div v-show="!isEmpty" class="chart-wrapper">
+    <div
+      :class="['line-chart', ['requests', 'non_200_status'].includes(instanceId) ? 'mini' : 'middle']"
+      :id="instanceId"></div>
+    <div
+      :class="['chart-legend', 'custom-scroll-bar', { 'side-legend': instanceId === 'non_200_status' }]"
+      v-if="chartLegend[instanceId]">
+      <div
+        v-for="({ color, name, selected }, legendIndex) in chartLegend[instanceId]"
+        :key="legendIndex"
+        :class="['legend-item', { selected, unselected: !selected }]"
+        @click.stop="handleClickLegend(legendIndex)">
+        <div class="legend-icon" :style="{ background: color }"></div>
+        <div class="legend-name">{{name}}</div>
+      </div>
+    </div>
+  </div>
+
   <div v-show="isEmpty" class="ap-nodata">
     <TableEmpty
       :keyword="tableEmptyConf.keyword"
@@ -17,6 +34,7 @@ import { merge } from 'lodash';
 import { userChartIntervalOption } from '@/hooks';
 import { SeriesItemType, SearchParamsType } from '../type';
 import TableEmpty from '@/components/table-empty.vue';
+import { getColorHue } from '@/common/util';
 
 const props = defineProps({
   instanceId: { // 生成图表的元素id
@@ -33,11 +51,30 @@ const props = defineProps({
   },
 });
 
+interface LegendItem {
+  color: string;
+  name: string;
+  selected: boolean,
+};
+
+interface ChartLegend {
+  requests_total?: LegendItem;
+  health_rate?: LegendItem;
+  requests?: LegendItem;
+  non_200_status?: LegendItem;
+  app_requests?: LegendItem;
+  resource_requests?: LegendItem;
+  ingress?: LegendItem;
+  egress?: LegendItem;
+  response_time_90th?: LegendItem;
+};
+
 const emit = defineEmits(['clear-params', 'report-init']);
 
 const { getChartIntervalOption } = userChartIntervalOption();
 
 const myChart = shallowRef();
+const chartLegend = ref<ChartLegend>({});
 const searchParams = ref<SearchParamsType>();
 const isEmpty = ref<boolean>(false);
 const tableEmptyConf = ref<{keyword: string, isAbnormal: boolean}>({
@@ -99,7 +136,6 @@ const chartResize = () => {
 
 const getChartOption = () => {
   const baseOption: echarts.EChartOption = {
-    color: ['#FFB43D', '#4BC7AD', '#FF7756', '#B5E0AB', '#D66F6B', '#3E96C2', '#FFA66B', '#85CCA8', '#FFC685', '#3762B8'],
     title: {
       text: props.title,
       top: 12,
@@ -112,7 +148,7 @@ const getChartOption = () => {
       },
     },
     grid: {
-      right: 140, // 设置距离右侧的间距
+      right: '8%', // 设置距离右侧的间距
     },
     xAxis: {
       type: 'time',
@@ -120,7 +156,8 @@ const getChartOption = () => {
       boundaryGap: false,
       axisLabel: { // 坐标轴刻度标签的相关设置
         color: '#666666',
-        rotate: 35,
+        fontSize: 12,
+        padding: [0, 5, 0, 0],
       },
       axisLine: { // 坐标轴轴线相关设置
         lineStyle: {
@@ -138,6 +175,8 @@ const getChartOption = () => {
       type: 'value',
       axisLabel: { // 坐标轴刻度标签的相关设置
         color: '#666666',
+        fontSize: 12,
+        padding: [0, 5, 0, 0],
       },
       splitLine: { // 坐标轴在 grid 区域中的分隔线
         lineStyle: {
@@ -164,34 +203,20 @@ const getChartOption = () => {
           borderWidth: 0, // 边框宽度为0
         },
       },
-    }],
-    legend: { // 图例组件
-      show: true,
-      type: 'scroll',
-      orient: 'vertical', // 垂直排列
-      right: 10,
-      top: 30,     // 垂直居中
-      height: 302,
-      pageIconSize: 12, // 翻页按钮的大小
-      pageIconColor: '#63656E', // 翻页按钮的颜色
-      pageIconInactiveColor: '#C4C6CC', // 翻页按钮不激活时(即翻页到头时)的颜色
-      textStyle: {       // 图例文字的样式设置
-        fontSize: 12,
-        color: '#63656E',
-      },
-      itemWidth: 16, // 图例标记的图形宽度
-      itemHeight: 6, // 图例标记的图形高度
-      itemGap: 16, // 设置图例项之间的间隔
-      tooltip: {
-        show: true,
+      lineStyle: {
+        width: 1,
       },
-      formatter: (name: string) => {
-        return echarts.format.truncateText(name, 80, '12px Microsoft Yahei', '…');
+      markPoint: {
+        symbolSize: 12,
       },
+    }],
+    legend: {
+      show: false,
     },
   };
 
   const chartOption: echarts.EChartOption = {
+    xAxis: {},
     yAxis: {},
     series: [],
     tooltip: {},
@@ -222,15 +247,15 @@ const getChartOption = () => {
       }));
       moreOption = getChartMoreOption(datapoints);
     });
-    if (props.instanceId === 'requests') {
-      chartOption.legend.show = false;
-      chartOption.grid.left = '14%';
-      chartOption.grid.right = '8%';
-    }
-
-    if (props.instanceId === 'non_200_status') {
-      chartOption.grid.left = '14%';
-      chartOption.grid.right = 80;
+    // 设置图表颜色
+    chartOption.color = generateChartColor(props.chartData.series ?? []);
+    if (['requests', 'non_200_status'].includes(props.instanceId)) {
+      chartOption.grid.left = '18%';
+      if (document.body.clientWidth < 1550) {
+        chartOption.xAxis.axisLabel = {
+          rotate: 35,
+        };
+      }
     }
 
     if (props.instanceId === 'ingress' || props.instanceId === 'egress') {
@@ -267,8 +292,6 @@ const getChartOption = () => {
       formatter: '{value} ms',
     };
 
-    chartOption.grid.right = '10%';
-
     const serieData = datapoints.reduce((a, b) => a.concat(b), []);
     moreOption = getChartMoreOption(serieData);
   }
@@ -293,11 +316,99 @@ const getChartMoreOption = (seriesData: Array<Array<number>>) => {
   return xAxisIntervalOption;
 };
 
+const generateChartColor = (chartData: SeriesItemType[]) => {
+  let baseColor = ['#3A84FF', '#5AD8A6', '#5D7092', '#F6BD16', '#FF5656', '#6DC8EC', '#FFB43D', '#4BC7AD', '#FF7756', '#B5E0AB'];
+  let angle = 30;
+  if (props.instanceId.indexOf('failed_') !== -1) {
+    baseColor = ['#FF5656', '#5AD8A6'];
+    angle = 10;
+  }
+  const colors: string[] = [];
+  const interval = Math.ceil(chartData.length / baseColor.length);
+
+  baseColor.forEach((color) => {
+    let i = 0;
+    while (i < interval) {
+      const co = getColorHue(color, i * angle);
+      colors.push(co);
+      i += 1;
+    }
+  });
+
+  const finalColors = colors.reduce((a, b) => a.concat(b), []);
+  return finalColors;
+};
+
+const generateChartLegend = () => {
+  const option = myChart.value?.getOption();
+  // 只有一个系列不需要图例
+  if (option.series.length > 1) {
+    chartLegend.value[props.instanceId] = option?.series?.map((serie: echarts.EChartOption.Series, index: number) => ({
+      color: option.color[index],
+      name: serie.name,
+      selected: false,
+    }));
+  } else {
+    chartLegend.value[props.instanceId] = null;
+  }
+};
+
+const handleClickLegend = (index: number) => {
+  const legend = chartLegend.value[props.instanceId];
+  const currentLegend = legend[index];
+
+  const { selected } = currentLegend;
+
+  // 实现切换单选显示
+  if (!selected) {
+    // 仅显示选中
+    myChart.value.dispatchAction({
+      type: 'legendUnSelect',
+      batch: legend.map(({ name }: LegendItem) => ({ name })),
+    });
+    myChart.value.dispatchAction({
+      type: 'legendSelect',
+      name: currentLegend.name,
+    });
+
+    // 选中状态设置
+    legend.forEach((item: LegendItem, i: number) => {
+      item.selected = index === i;
+    });
+    chartLegend.value = { ...chartLegend.value, ...{ [props.instanceId]: legend } };
+  } else {
+    // 全部显示
+    myChart.value.dispatchAction({
+      type: 'legendSelect',
+      batch: legend.map(({ name }: LegendItem) => ({ name })),
+    });
+
+    legend.forEach((item: LegendItem) => (item.selected = false));
+    chartLegend.value = { ...chartLegend.value, ...{ [props.instanceId]: legend } };
+  }
+};
+
 const renderChart = () => {
   nextTick(() => {
     const option = getChartOption();
     myChart.value?.setOption(option, { notMerge: true });
+    // 切换图例,处理单个数据点x轴显示问题
+    myChart.value?.on('legendselected', (params: LegendItem) => {
+      const currentOption = myChart.value.getOption();
+      const serie = currentOption.series.find((item: echarts.EChartOption.Series) => item.name === params.name) || {};
+      if (serie.data && serie.data.length === 1) {
+        // fix单个数据点xAxis显示异常,本质上是去掉动态计算出的间隔设置
+        myChart.value?.setOption({
+          xAxis: {
+            interval: 'auto',
+          },
+        });
+      } else {
+        myChart.value?.setOption(option);
+      }
+    });
     chartResize();
+    generateChartLegend();
   });
 };
 
@@ -311,8 +422,74 @@ defineExpose({
 </script>
 
 <style lang="scss" scoped>
-.line-chart {
-  width: 100%;
-  height: 100%;
+.chart-wrapper {
+  position: relative;
+  .line-chart {
+    &.mini {
+      height: 320px;
+    }
+    &.middle {
+      height: 360px;
+    }
+  }
+  .chart-legend {
+    display: flex;
+    flex-wrap: wrap;
+    margin: 0 40px;
+    height: 70px;
+    max-height: 110px;
+    overflow-y: auto;
+
+    .legend-item {
+      display: flex;
+      align-items: center;
+      flex: none;
+      font-size: 12px;
+      line-height: 22px;
+      margin-right: 12px;
+      color: #777;
+      white-space: nowrap;
+      cursor: pointer;
+
+      &:hover,
+      &.selected {
+        color: #333;
+      }
+
+      &.unselected {
+        color: #ccc;
+      }
+    }
+    .legend-icon {
+      height: 4px;
+      background: #999;
+      flex: none;
+      width: 16px;
+      border-radius: 2px;
+      margin-right: 3px;
+    }
+  }
+  .side-legend {
+    position: absolute;
+    right: -34px;
+    top: 10px;
+    flex-direction: column;
+  }
+  .custom-scroll-bar {
+    &::-webkit-scrollbar {
+      width: 4px;
+      background-color: lighten(#c4c6cc, 80%);
+    }
+
+    &::-webkit-scrollbar-thumb {
+      height: 5px;
+      border-radius: 2px;
+      background-color: #c4c6cc;
+    }
+
+    &::-webkit-scrollbar-track {
+      background: transparent;
+    }
+  }
 }
 </style>
diff --git a/src/dashboard-front/src/views/operate-data/statistics-report/index.vue b/src/dashboard-front/src/views/operate-data/statistics-report/index.vue
index b5652cc8c..77deddfc2 100644
--- a/src/dashboard-front/src/views/operate-data/statistics-report/index.vue
+++ b/src/dashboard-front/src/views/operate-data/statistics-report/index.vue
@@ -255,7 +255,7 @@ const handleReportInit = () => {
   }
   .requests {
     .total-requests {
-      width: 254px;
+      width: 200px;
       height: 320px;
       background: #FFFFFF;
       box-shadow: 0 1px 2px 0 #0000001a;
@@ -280,7 +280,6 @@ const handleReportInit = () => {
     }
     .success-requests {
       width: 673px;
-      height: 320px;
       background: #FFFFFF;
       box-shadow: 0 2px 4px 0 #1919290d;
       border-radius: 2px;
@@ -288,7 +287,6 @@ const handleReportInit = () => {
     }
     .error-requests {
       width: 673px;
-      height: 320px;
       background: #FFFFFF;
       box-shadow: 0 2px 4px 0 #1919290d;
       border-radius: 2px;
@@ -297,25 +295,25 @@ const handleReportInit = () => {
   .secondary-panel {
     .secondary-lf {
       width: 808px;
-      height: 360px;
       background: #FFFFFF;
       box-shadow: 0 2px 4px 0 #1919290d;
       border-radius: 2px;
       margin-right: 16px;
+      padding-bottom: 6px;
     }
     .secondary-rg {
       width: 808px;
-      height: 360px;
       background: #FFFFFF;
       box-shadow: 0 2px 4px 0 #1919290d;
       border-radius: 2px;
+      padding-bottom: 6px;
     }
   }
   .full-line {
-    height: 360px;
     background: #FFFFFF;
     box-shadow: 0 2px 4px 0 #1919290d;
     border-radius: 2px;
+    padding-bottom: 12px;
   }
 }
 .full-box {