Repository: cdklabs/cdk-monitoring-constructs (language: python)

Issue:
[custom metrics] Add a property to adjust legend position
### Feature scope

Custom metrics

### Describe your suggested feature

User request: add a property to custom metrics that allows them to modify the legend position.


Discussion / hints:

Fix patch:
diff --git a/API.md b/API.md
index c5ec2164..c7dd5442 100644
--- a/API.md
+++ b/API.md
@@ -10104,7 +10104,8 @@ const customMetricGroup: CustomMetricGroup = { ... }
 | <code><a href="#cdk-monitoring-constructs.CustomMetricGroup.property.metrics">metrics</a></code> | <code>aws-cdk-lib.aws_cloudwatch.Metric \| aws-cdk-lib.aws_cloudwatch.MathExpression \| <a href="#cdk-monitoring-constructs.CustomMetricWithAlarm">CustomMetricWithAlarm</a> \| <a href="#cdk-monitoring-constructs.CustomMetricWithAnomalyDetection">CustomMetricWithAnomalyDetection</a> \| <a href="#cdk-monitoring-constructs.CustomMetricSearch">CustomMetricSearch</a>[]</code> | list of metrics in the group (can be defined in different ways, see the type documentation). |
 | <code><a href="#cdk-monitoring-constructs.CustomMetricGroup.property.title">title</a></code> | <code>string</code> | title of the whole group. |
 | <code><a href="#cdk-monitoring-constructs.CustomMetricGroup.property.graphWidgetAxis">graphWidgetAxis</a></code> | <code>aws-cdk-lib.aws_cloudwatch.YAxisProps</code> | optional axis. |
-| <code><a href="#cdk-monitoring-constructs.CustomMetricGroup.property.graphWidgetRightAxis">graphWidgetRightAxis</a></code> | <code>aws-cdk-lib.aws_cloudwatch.YAxisProps</code> | optional right axis default: undefined. |
+| <code><a href="#cdk-monitoring-constructs.CustomMetricGroup.property.graphWidgetLegend">graphWidgetLegend</a></code> | <code>aws-cdk-lib.aws_cloudwatch.LegendPosition</code> | graph widget legend. |
+| <code><a href="#cdk-monitoring-constructs.CustomMetricGroup.property.graphWidgetRightAxis">graphWidgetRightAxis</a></code> | <code>aws-cdk-lib.aws_cloudwatch.YAxisProps</code> | optional right axis. |
 | <code><a href="#cdk-monitoring-constructs.CustomMetricGroup.property.graphWidgetType">graphWidgetType</a></code> | <code><a href="#cdk-monitoring-constructs.GraphWidgetType">GraphWidgetType</a></code> | type of the widget. |
 | <code><a href="#cdk-monitoring-constructs.CustomMetricGroup.property.horizontalAnnotations">horizontalAnnotations</a></code> | <code>aws-cdk-lib.aws_cloudwatch.HorizontalAnnotation[]</code> | optional custom horizontal annotations which will be displayed over the metrics on the left axis (if there are any alarms, any existing annotations will be merged together). |
 | <code><a href="#cdk-monitoring-constructs.CustomMetricGroup.property.horizontalRightAnnotations">horizontalRightAnnotations</a></code> | <code>aws-cdk-lib.aws_cloudwatch.HorizontalAnnotation[]</code> | optional custom horizontal annotations which will be displayed over the metrics on the right axis (if there are any alarms, any existing annotations will be merged together). |
@@ -10149,6 +10150,19 @@ optional axis.
 
 ---
 
+##### `graphWidgetLegend`<sup>Optional</sup> <a name="graphWidgetLegend" id="cdk-monitoring-constructs.CustomMetricGroup.property.graphWidgetLegend"></a>
+
+```typescript
+public readonly graphWidgetLegend: LegendPosition;
+```
+
+- *Type:* aws-cdk-lib.aws_cloudwatch.LegendPosition
+- *Default:* BOTTOM
+
+graph widget legend.
+
+---
+
 ##### `graphWidgetRightAxis`<sup>Optional</sup> <a name="graphWidgetRightAxis" id="cdk-monitoring-constructs.CustomMetricGroup.property.graphWidgetRightAxis"></a>
 
 ```typescript
@@ -10156,8 +10170,9 @@ public readonly graphWidgetRightAxis: YAxisProps;
 ```
 
 - *Type:* aws-cdk-lib.aws_cloudwatch.YAxisProps
+- *Default:* undefined
 
-optional right axis default: undefined.
+optional right axis.
 
 ---
 
diff --git a/lib/monitoring/custom/CustomMonitoring.ts b/lib/monitoring/custom/CustomMonitoring.ts
index e3ec9f15..753f5775 100644
--- a/lib/monitoring/custom/CustomMonitoring.ts
+++ b/lib/monitoring/custom/CustomMonitoring.ts
@@ -6,6 +6,7 @@ import {
   HorizontalAnnotation,
   IMetric,
   IWidget,
+  LegendPosition,
   Row,
   TextWidget,
   YAxisProps,
@@ -15,18 +16,18 @@ import {
   AnomalyDetectingAlarmFactory,
   AnomalyDetectionThreshold,
   BaseMonitoringProps,
+  createGraphWidget,
   CustomAlarmFactory,
   CustomThreshold,
   DefaultGraphWidgetHeight,
   DefaultSummaryWidgetHeight,
   FullWidth,
+  getHashForMetricExpressionId,
   GraphWidgetType,
   MetricStatistic,
   MetricWithAlarmSupport,
   Monitoring,
   MonitoringScope,
-  createGraphWidget,
-  getHashForMetricExpressionId,
   recommendedWidgetWidth,
 } from "../../common";
 import {
@@ -150,22 +151,27 @@ export interface CustomMetricGroup {
   readonly title: string;
   /**
    * type of the widget
-   * @default - line
+   * @default line
    */
   readonly graphWidgetType?: GraphWidgetType;
   /**
    * optional axis
-   * @default - undefined
+   * @default undefined
    */
   readonly graphWidgetAxis?: YAxisProps;
   /**
    * optional right axis
-   * default: undefined
+   * @default undefined
    */
   readonly graphWidgetRightAxis?: YAxisProps;
+  /**
+   * graph widget legend
+   * @default BOTTOM
+   */
+  readonly graphWidgetLegend?: LegendPosition;
   /**
    * Flag indicating, whether this is an important metric group that should be included in the summary as well.
-   * @default - false
+   * @default false
    */
   readonly important?: boolean;
   /**
@@ -368,6 +374,7 @@ export class CustomMonitoring extends Monitoring {
         rightAnnotations: annotatedGroup.rightAnnotations,
         leftYAxis: annotatedGroup.metricGroup.graphWidgetAxis,
         rightYAxis: annotatedGroup.metricGroup.graphWidgetRightAxis,
+        legendPosition: annotatedGroup.metricGroup.graphWidgetLegend,
       };
 
       const widget = useAnomalyDetectionWidget


Test patch:
diff --git a/test/monitoring/custom/CustomMonitoring.test.ts b/test/monitoring/custom/CustomMonitoring.test.ts
index 4402cb54..90f20a89 100644
--- a/test/monitoring/custom/CustomMonitoring.test.ts
+++ b/test/monitoring/custom/CustomMonitoring.test.ts
@@ -2,6 +2,7 @@ import { Stack } from "aws-cdk-lib";
 import { Template } from "aws-cdk-lib/assertions";
 import {
   ComparisonOperator,
+  LegendPosition,
   MathExpression,
   Metric,
   Shading,
@@ -148,6 +149,7 @@ test("snapshot test", () => {
         horizontalRightAnnotations: [
           { label: "DummyAnnotation3", value: 20, fill: Shading.BELOW },
         ],
+        graphWidgetLegend: LegendPosition.RIGHT,
       },
       {
         title: "DummyGroup4",
diff --git a/test/monitoring/custom/__snapshots__/CustomMonitoring.test.ts.snap b/test/monitoring/custom/__snapshots__/CustomMonitoring.test.ts.snap
index 3890934a..d16a6dfe 100644
--- a/test/monitoring/custom/__snapshots__/CustomMonitoring.test.ts.snap
+++ b/test/monitoring/custom/__snapshots__/CustomMonitoring.test.ts.snap
@@ -498,7 +498,7 @@ Object {
               Object {
                 "Ref": "AWS::Region",
               },
-              "\\",\\"metrics\\":[[\\"DummyCustomNamespace\\",\\"DummyMetric20\\",\\"CustomDimension\\",\\"CustomDimensionValue\\"],[\\"DummyCustomNamespace\\",\\"DummyMetric21\\",\\"CustomDimension\\",\\"CustomDimensionValue\\"],[\\"DummyCustomNamespace\\",\\"DummyMetric22\\",\\"CustomDimension\\",\\"CustomDimensionValue\\",{\\"yAxis\\":\\"right\\"}]],\\"annotations\\":{\\"horizontal\\":[{\\"label\\":\\"DummyAnnotation1\\",\\"value\\":30,\\"fill\\":\\"above\\",\\"yAxis\\":\\"left\\"},{\\"label\\":\\"DummyAnnotation2\\",\\"value\\":20,\\"fill\\":\\"below\\",\\"yAxis\\":\\"left\\"},{\\"label\\":\\"DummyAnnotation3\\",\\"value\\":20,\\"fill\\":\\"below\\",\\"yAxis\\":\\"right\\"},{\\"label\\":\\"DummyMetric22 > 10 for 3 datapoints within 15 minutes\\",\\"value\\":10,\\"yAxis\\":\\"right\\"},{\\"label\\":\\"DummyMetric22 > 50 for 3 datapoints within 15 minutes\\",\\"value\\":50,\\"yAxis\\":\\"right\\"}]},\\"yAxis\\":{\\"right\\":{\\"label\\":\\"CustomValue\\"}}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":3,\\"x\\":18,\\"y\\":3,\\"properties\\":{\\"view\\":\\"singleValue\\",\\"region\\":\\"",
+              "\\",\\"metrics\\":[[\\"DummyCustomNamespace\\",\\"DummyMetric20\\",\\"CustomDimension\\",\\"CustomDimensionValue\\"],[\\"DummyCustomNamespace\\",\\"DummyMetric21\\",\\"CustomDimension\\",\\"CustomDimensionValue\\"],[\\"DummyCustomNamespace\\",\\"DummyMetric22\\",\\"CustomDimension\\",\\"CustomDimensionValue\\",{\\"yAxis\\":\\"right\\"}]],\\"annotations\\":{\\"horizontal\\":[{\\"label\\":\\"DummyAnnotation1\\",\\"value\\":30,\\"fill\\":\\"above\\",\\"yAxis\\":\\"left\\"},{\\"label\\":\\"DummyAnnotation2\\",\\"value\\":20,\\"fill\\":\\"below\\",\\"yAxis\\":\\"left\\"},{\\"label\\":\\"DummyAnnotation3\\",\\"value\\":20,\\"fill\\":\\"below\\",\\"yAxis\\":\\"right\\"},{\\"label\\":\\"DummyMetric22 > 10 for 3 datapoints within 15 minutes\\",\\"value\\":10,\\"yAxis\\":\\"right\\"},{\\"label\\":\\"DummyMetric22 > 50 for 3 datapoints within 15 minutes\\",\\"value\\":50,\\"yAxis\\":\\"right\\"}]},\\"yAxis\\":{\\"right\\":{\\"label\\":\\"CustomValue\\"}},\\"legend\\":{\\"position\\":\\"right\\"}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":3,\\"x\\":18,\\"y\\":3,\\"properties\\":{\\"view\\":\\"singleValue\\",\\"region\\":\\"",
               Object {
                 "Ref": "AWS::Region",
               },