diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.dashboard-with-graphwidget-with-annotations.js.snapshot/DashboardWithGraphWidgetWithAnnotationsIntegrationTest.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.dashboard-with-graphwidget-with-annotations.js.snapshot/DashboardWithGraphWidgetWithAnnotationsIntegrationTest.assets.json new file mode 100644 index 0000000000000..33c0bbc425f69 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.dashboard-with-graphwidget-with-annotations.js.snapshot/DashboardWithGraphWidgetWithAnnotationsIntegrationTest.assets.json @@ -0,0 +1,19 @@ +{ + "version": "30.0.0", + "files": { + "fa0b1fe0c3043238b7413b794c626bac246c94f150aa6e3ff441a030d7dce521": { + "source": { + "path": "DashboardWithGraphWidgetWithAnnotationsIntegrationTest.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "fa0b1fe0c3043238b7413b794c626bac246c94f150aa6e3ff441a030d7dce521.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.dashboard-with-graphwidget-with-annotations.js.snapshot/DashboardWithGraphWidgetWithAnnotationsIntegrationTest.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.dashboard-with-graphwidget-with-annotations.js.snapshot/DashboardWithGraphWidgetWithAnnotationsIntegrationTest.template.json new file mode 100644 index 0000000000000..b081129c76389 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.dashboard-with-graphwidget-with-annotations.js.snapshot/DashboardWithGraphWidgetWithAnnotationsIntegrationTest.template.json @@ -0,0 +1,55 @@ +{ + "Resources": { + "DashCCD7F836": { + "Type": "AWS::CloudWatch::Dashboard", + "Properties": { + "DashboardBody": { + "Fn::Join": [ + "", + [ + "{\"widgets\":[{\"type\":\"metric\",\"width\":6,\"height\":6,\"x\":0,\"y\":0,\"properties\":{\"view\":\"timeSeries\",\"title\":\"My fancy graph\",\"region\":\"", + { + "Ref": "AWS::Region" + }, + "\",\"metrics\":[[\"CDK/Test\",\"Metric\",{\"label\":\"Metric left 1 - p99\",\"stat\":\"p99\"}],[\"CDK/Test\",\"Metric\",{\"label\":\"Metric left 2 - TC_10P_90P\",\"stat\":\"TC(10%:90%)\"}],[\"CDK/Test\",\"Metric\",{\"label\":\"Metric left 3 - TS(5%:95%)\",\"stat\":\"TS(5%:95%)\"}],[\"CDK/Test\",\"Metric\",{\"label\":\"Metric right 1 - p90.1234\",\"stat\":\"p90.1234\",\"yAxis\":\"right\"}]],\"annotations\":{\"horizontal\":[{\"value\":10,\"label\":\"Left annotation\",\"color\":\"#00ff00\",\"fill\":\"above\",\"visible\":true,\"yAxis\":\"left\"},{\"value\":20,\"label\":\"Right annotation\",\"color\":\"#e30d0d\",\"fill\":\"below\",\"visible\":false,\"yAxis\":\"right\"}],\"vertical\":[{\"value\":\"2023-08-20T00:00:00.000Z\",\"label\":\"Vertical annotation\",\"color\":\"#2556f6\",\"fill\":\"after\",\"visible\":true}]},\"yAxis\":{}}}]}" + ] + ] + } + } + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.dashboard-with-graphwidget-with-annotations.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.dashboard-with-graphwidget-with-annotations.js.snapshot/cdk.out new file mode 100644 index 0000000000000..9982913536117 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.dashboard-with-graphwidget-with-annotations.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"30.0.0"} diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.dashboard-with-graphwidget-with-annotations.js.snapshot/cdkintegdashboardwithgraphwidgetwithannotationsDefaultTestDeployAssertD4707D74.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.dashboard-with-graphwidget-with-annotations.js.snapshot/cdkintegdashboardwithgraphwidgetwithannotationsDefaultTestDeployAssertD4707D74.assets.json new file mode 100644 index 0000000000000..5904b65ebec07 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.dashboard-with-graphwidget-with-annotations.js.snapshot/cdkintegdashboardwithgraphwidgetwithannotationsDefaultTestDeployAssertD4707D74.assets.json @@ -0,0 +1,19 @@ +{ + "version": "30.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "cdkintegdashboardwithgraphwidgetwithannotationsDefaultTestDeployAssertD4707D74.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.dashboard-with-graphwidget-with-annotations.js.snapshot/cdkintegdashboardwithgraphwidgetwithannotationsDefaultTestDeployAssertD4707D74.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.dashboard-with-graphwidget-with-annotations.js.snapshot/cdkintegdashboardwithgraphwidgetwithannotationsDefaultTestDeployAssertD4707D74.template.json new file mode 100644 index 0000000000000..ec488341c0126 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.dashboard-with-graphwidget-with-annotations.js.snapshot/cdkintegdashboardwithgraphwidgetwithannotationsDefaultTestDeployAssertD4707D74.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.dashboard-with-graphwidget-with-annotations.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.dashboard-with-graphwidget-with-annotations.js.snapshot/integ.json new file mode 100644 index 0000000000000..df1157fba97e4 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.dashboard-with-graphwidget-with-annotations.js.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "30.0.0", + "testCases": { + "cdk-integ-dashboard-with-graph-widget-with-annotations/DefaultTest": { + "stacks": [ + "DashboardWithGraphWidgetWithAnnotationsIntegrationTest" + ], + "assertionStack": "cdk-integ-dashboard-with-graph-widget-with-annotations/DefaultTest/DeployAssert", + "assertionStackName": "cdkintegdashboardwithgraphwidgetwithannotationsDefaultTestDeployAssertD4707D74" + } + } +} diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.dashboard-with-graphwidget-with-annotations.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.dashboard-with-graphwidget-with-annotations.js.snapshot/manifest.json new file mode 100644 index 0000000000000..6e42eab89b36c --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.dashboard-with-graphwidget-with-annotations.js.snapshot/manifest.json @@ -0,0 +1,111 @@ +{ + "version": "30.0.0", + "artifacts": { + "DashboardWithGraphWidgetWithAnnotationsIntegrationTest.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "DashboardWithGraphWidgetWithAnnotationsIntegrationTest.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "DashboardWithGraphWidgetWithAnnotationsIntegrationTest": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "DashboardWithGraphWidgetWithAnnotationsIntegrationTest.template.json", + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/fa0b1fe0c3043238b7413b794c626bac246c94f150aa6e3ff441a030d7dce521.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "DashboardWithGraphWidgetWithAnnotationsIntegrationTest.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "DashboardWithGraphWidgetWithAnnotationsIntegrationTest.assets" + ], + "metadata": { + "/DashboardWithGraphWidgetWithAnnotationsIntegrationTest/Dash/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "DashCCD7F836" + } + ], + "/DashboardWithGraphWidgetWithAnnotationsIntegrationTest/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/DashboardWithGraphWidgetWithAnnotationsIntegrationTest/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "DashboardWithGraphWidgetWithAnnotationsIntegrationTest" + }, + "cdkintegdashboardwithgraphwidgetwithannotationsDefaultTestDeployAssertD4707D74.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "cdkintegdashboardwithgraphwidgetwithannotationsDefaultTestDeployAssertD4707D74.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "cdkintegdashboardwithgraphwidgetwithannotationsDefaultTestDeployAssertD4707D74": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "cdkintegdashboardwithgraphwidgetwithannotationsDefaultTestDeployAssertD4707D74.template.json", + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "cdkintegdashboardwithgraphwidgetwithannotationsDefaultTestDeployAssertD4707D74.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "cdkintegdashboardwithgraphwidgetwithannotationsDefaultTestDeployAssertD4707D74.assets" + ], + "metadata": { + "/cdk-integ-dashboard-with-graph-widget-with-annotations/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/cdk-integ-dashboard-with-graph-widget-with-annotations/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "cdk-integ-dashboard-with-graph-widget-with-annotations/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.dashboard-with-graphwidget-with-annotations.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.dashboard-with-graphwidget-with-annotations.js.snapshot/tree.json new file mode 100644 index 0000000000000..09407c21d6fa8 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.dashboard-with-graphwidget-with-annotations.js.snapshot/tree.json @@ -0,0 +1,136 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "DashboardWithGraphWidgetWithAnnotationsIntegrationTest": { + "id": "DashboardWithGraphWidgetWithAnnotationsIntegrationTest", + "path": "DashboardWithGraphWidgetWithAnnotationsIntegrationTest", + "children": { + "Dash": { + "id": "Dash", + "path": "DashboardWithGraphWidgetWithAnnotationsIntegrationTest/Dash", + "children": { + "Resource": { + "id": "Resource", + "path": "DashboardWithGraphWidgetWithAnnotationsIntegrationTest/Dash/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::CloudWatch::Dashboard", + "aws:cdk:cloudformation:props": { + "dashboardBody": { + "Fn::Join": [ + "", + [ + "{\"widgets\":[{\"type\":\"metric\",\"width\":6,\"height\":6,\"x\":0,\"y\":0,\"properties\":{\"view\":\"timeSeries\",\"title\":\"My fancy graph\",\"region\":\"", + { + "Ref": "AWS::Region" + }, + "\",\"metrics\":[[\"CDK/Test\",\"Metric\",{\"label\":\"Metric left 1 - p99\",\"stat\":\"p99\"}],[\"CDK/Test\",\"Metric\",{\"label\":\"Metric left 2 - TC_10P_90P\",\"stat\":\"TC(10%:90%)\"}],[\"CDK/Test\",\"Metric\",{\"label\":\"Metric left 3 - TS(5%:95%)\",\"stat\":\"TS(5%:95%)\"}],[\"CDK/Test\",\"Metric\",{\"label\":\"Metric right 1 - p90.1234\",\"stat\":\"p90.1234\",\"yAxis\":\"right\"}]],\"annotations\":{\"horizontal\":[{\"value\":10,\"label\":\"Left annotation\",\"color\":\"#00ff00\",\"fill\":\"above\",\"visible\":true,\"yAxis\":\"left\"},{\"value\":20,\"label\":\"Right annotation\",\"color\":\"#e30d0d\",\"fill\":\"below\",\"visible\":false,\"yAxis\":\"right\"}],\"vertical\":[{\"value\":\"2023-08-20T00:00:00.000Z\",\"label\":\"Vertical annotation\",\"color\":\"#2556f6\",\"fill\":\"after\",\"visible\":true}]},\"yAxis\":{}}}]}" + ] + ] + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-cloudwatch.CfnDashboard", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-cloudwatch.Dashboard", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "DashboardWithGraphWidgetWithAnnotationsIntegrationTest/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "DashboardWithGraphWidgetWithAnnotationsIntegrationTest/CheckBootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + }, + "cdk-integ-dashboard-with-graph-widget-with-annotations": { + "id": "cdk-integ-dashboard-with-graph-widget-with-annotations", + "path": "cdk-integ-dashboard-with-graph-widget-with-annotations", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "cdk-integ-dashboard-with-graph-widget-with-annotations/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "cdk-integ-dashboard-with-graph-widget-with-annotations/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.252" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "cdk-integ-dashboard-with-graph-widget-with-annotations/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "cdk-integ-dashboard-with-graph-widget-with-annotations/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "cdk-integ-dashboard-with-graph-widget-with-annotations/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.252" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.App", + "version": "0.0.0" + } + } +} diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.dashboard-with-graphwidget-with-annotations.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.dashboard-with-graphwidget-with-annotations.ts new file mode 100644 index 0000000000000..371cafb60a47b --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.dashboard-with-graphwidget-with-annotations.ts @@ -0,0 +1,79 @@ +import { App, Stack, StackProps } from 'aws-cdk-lib'; +import { IntegTest } from '@aws-cdk/integ-tests-alpha'; +import { Dashboard, GraphWidget, Metric, Shading, Stats, VerticalShading } from 'aws-cdk-lib/aws-cloudwatch'; + +class DashboardWithGraphWidgetWithAnnotationsIntegrationTest extends Stack { + constructor(scope: App, id: string, props?: StackProps) { + super(scope, id, props); + + const dashboard = new Dashboard(this, 'Dash'); + + const widget = new GraphWidget({ + title: 'My fancy graph', + left: [ + new Metric({ + namespace: 'CDK/Test', + metricName: 'Metric', + label: 'Metric left 1 - p99', + statistic: Stats.p(99), + }), + + new Metric({ + namespace: 'CDK/Test', + metricName: 'Metric', + label: 'Metric left 2 - TC_10P_90P', + statistic: Stats.tc(10, 90), + }), + + new Metric({ + namespace: 'CDK/Test', + metricName: 'Metric', + label: 'Metric left 3 - TS(5%:95%)', + statistic: 'TS(5%:95%)', + }), + ], + right: [ + new Metric({ + namespace: 'CDK/Test', + metricName: 'Metric', + label: 'Metric right 1 - p90.1234', + statistic: 'p90.1234', + }), + ], + leftAnnotations: [ + { + value: 10, + label: 'Left annotation', + color: '#00ff00', + fill: Shading.ABOVE, + visible: true, + }, + ], + rightAnnotations: [ + { + value: 20, + label: 'Right annotation', + color: '#e30d0d', + fill: Shading.BELOW, + visible: false, + }, + ], + verticalAnnotations: [ + { + date: '2023-08-20T00:00:00.000Z', + label: 'Vertical annotation', + color: '#2556f6', + fill: VerticalShading.AFTER, + visible: true, + }, + ], + }); + + dashboard.addWidgets(widget); + } +} + +const app = new App(); +new IntegTest(app, 'cdk-integ-dashboard-with-graph-widget-with-annotations', { + testCases: [new DashboardWithGraphWidgetWithAnnotationsIntegrationTest(app, 'DashboardWithGraphWidgetWithAnnotationsIntegrationTest')], +}); diff --git a/packages/aws-cdk-lib/aws-cloudwatch/README.md b/packages/aws-cdk-lib/aws-cloudwatch/README.md index c28f46e28b476..7a6dc35cb6c64 100644 --- a/packages/aws-cdk-lib/aws-cloudwatch/README.md +++ b/packages/aws-cdk-lib/aws-cloudwatch/README.md @@ -428,7 +428,7 @@ dashboard.addWidgets(new cloudwatch.GraphWidget({ Using the methods `addLeftMetric()` and `addRightMetric()` you can add metrics to a graph widget later on. -Graph widgets can also display annotations attached to the left or the right y-axis. +Graph widgets can also display annotations attached to the left or right y-axis or the x-axis. ```ts declare const dashboard: cloudwatch.Dashboard; @@ -440,6 +440,9 @@ dashboard.addWidgets(new cloudwatch.GraphWidget({ { value: 1800, label: Duration.minutes(30).toHumanString(), color: cloudwatch.Color.RED, }, { value: 3600, label: '1 hour', color: '#2ca02c', } ], + verticalAnnotations: [ + { date: '2022-10-19T00:00:00Z', label: 'Deployment', color: cloudwatch.Color.RED, } + ] })); ``` diff --git a/packages/aws-cdk-lib/aws-cloudwatch/lib/graph.ts b/packages/aws-cdk-lib/aws-cloudwatch/lib/graph.ts index c7b5c7d497a34..8dfb0ff612abe 100644 --- a/packages/aws-cdk-lib/aws-cloudwatch/lib/graph.ts +++ b/packages/aws-cdk-lib/aws-cloudwatch/lib/graph.ts @@ -300,6 +300,13 @@ export interface GraphWidgetProps extends MetricWidgetProps { */ readonly rightAnnotations?: HorizontalAnnotation[]; + /** + * Annotations for the X axis + * + * @default - No annotations + */ + readonly verticalAnnotations?: VerticalAnnotation[]; + /** * Whether the graph should be shown as stacked lines * @@ -375,6 +382,12 @@ export interface GraphWidgetProps extends MetricWidgetProps { */ export class GraphWidget extends ConcreteWidget { + private static readonly ISO8601_REGEX = /^(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(.[0-9]+)?(Z)?$/; + + private static isIso8601(date: string): boolean { + return this.ISO8601_REGEX.test(date); + } + private readonly props: GraphWidgetProps; private readonly leftMetrics: IMetric[]; @@ -382,6 +395,12 @@ export class GraphWidget extends ConcreteWidget { constructor(props: GraphWidgetProps) { super(props.width || 6, props.height || 6); + props.verticalAnnotations?.forEach(annotation => { + const date = annotation.date; + if (!GraphWidget.isIso8601(date)) { + throw new Error(`Given date ${date} is not in ISO 8601 format`); + } + }); this.props = props; this.leftMetrics = props.left ?? []; this.rightMetrics = props.right ?? []; @@ -413,7 +432,14 @@ export class GraphWidget extends ConcreteWidget { ...(this.props.leftAnnotations || []).map(mapAnnotation('left')), ...(this.props.rightAnnotations || []).map(mapAnnotation('right')), ]; - + const verticalAnnotations = (this.props.verticalAnnotations || []).map(({ date, ...rest }) => ({ + value: date, + ...rest, + })); + const annotations = horizontalAnnotations.length > 0 || verticalAnnotations.length > 0 ? ({ + horizontal: horizontalAnnotations.length > 0 ? horizontalAnnotations : undefined, + vertical: verticalAnnotations.length > 0 ? verticalAnnotations : undefined, + }) : undefined; const metrics = allMetricsGraphJson(this.leftMetrics, this.rightMetrics); return [{ type: 'metric', @@ -427,7 +453,7 @@ export class GraphWidget extends ConcreteWidget { region: this.props.region || cdk.Aws.REGION, stacked: this.props.stacked, metrics: metrics.length > 0 ? metrics : undefined, - annotations: horizontalAnnotations.length > 0 ? { horizontal: horizontalAnnotations } : undefined, + annotations, yAxis: { left: this.props.leftYAxis ?? undefined, right: this.props.rightYAxis ?? undefined, @@ -651,7 +677,46 @@ export interface HorizontalAnnotation { } /** - * Fill shading options that will be used with an annotation + * Vertical annotation to be added to a graph + */ +export interface VerticalAnnotation { + /** + * The date and time (in ISO 8601 format) in the graph where the vertical annotation line is to appear + */ + readonly date: string; + + /** + * Label for the annotation + * + * @default - No label + */ + readonly label?: string; + + /** + * The hex color code, prefixed with '#' (e.g. '#00ff00'), to be used for the annotation. + * The `Color` class has a set of standard colors that can be used here. + * + * @default - Automatic color + */ + readonly color?: string; + + /** + * Add shading before or after the annotation + * + * @default No shading + */ + readonly fill?: VerticalShading; + + /** + * Whether the annotation is visible + * + * @default true + */ + readonly visible?: boolean; +} + +/** + * Fill shading options that will be used with a horizontal annotation */ export enum Shading { /** @@ -670,6 +735,26 @@ export enum Shading { BELOW = 'below' } +/** + * Fill shading options that will be used with a vertical annotation + */ +export enum VerticalShading { + /** + * Don't add shading + */ + NONE = 'none', + + /** + * Add shading before the annotation + */ + BEFORE = 'before', + + /** + * Add shading after the annotation + */ + AFTER = 'after' +} + /** * A set of standard colours that can be used in annotations in a GraphWidget. */ diff --git a/packages/aws-cdk-lib/aws-cloudwatch/test/graphs.test.ts b/packages/aws-cdk-lib/aws-cloudwatch/test/graphs.test.ts index fc440f1c416b9..3c3e93b9524ac 100644 --- a/packages/aws-cdk-lib/aws-cloudwatch/test/graphs.test.ts +++ b/packages/aws-cdk-lib/aws-cloudwatch/test/graphs.test.ts @@ -1,5 +1,5 @@ import { Duration, Stack } from '../../core'; -import { Alarm, AlarmWidget, Color, GraphWidget, GraphWidgetView, LegendPosition, LogQueryWidget, Metric, Shading, SingleValueWidget, LogQueryVisualizationType, CustomWidget, GaugeWidget } from '../lib'; +import { Alarm, AlarmWidget, Color, GraphWidget, GraphWidgetView, LegendPosition, LogQueryWidget, Metric, Shading, SingleValueWidget, LogQueryVisualizationType, CustomWidget, GaugeWidget, VerticalShading } from '../lib'; describe('Graphs', () => { test('add stacked property to graphs', () => { @@ -401,7 +401,7 @@ describe('Graphs', () => { }]); }); - test('add annotations to graph', () => { + test('add horizontal annotations to graph', () => { // WHEN const stack = new Stack(); const widget = new GraphWidget({ @@ -444,6 +444,65 @@ describe('Graphs', () => { }); + test('add vertical annotations to graph', () => { + // WHEN + const stack = new Stack(); + const widget = new GraphWidget({ + title: 'My fancy graph', + left: [ + new Metric({ namespace: 'CDK', metricName: 'Test' }), + ], + verticalAnnotations: [{ + date: '2021-07-29T02:31:09.890Z', + color: '667788', + fill: VerticalShading.AFTER, + label: 'this is the annotation', + }], + }); + + // THEN + expect(stack.resolve(widget.toJson())).toEqual([{ + type: 'metric', + width: 6, + height: 6, + properties: { + view: 'timeSeries', + title: 'My fancy graph', + region: { Ref: 'AWS::Region' }, + metrics: [ + ['CDK', 'Test'], + ], + annotations: { + vertical: [{ + value: '2021-07-29T02:31:09.890Z', + color: '667788', + fill: 'after', + label: 'this is the annotation', + }], + }, + yAxis: {}, + }, + }]); + }); + + test('vertical annotation date must match ISO 8601', () => { + // WHEN + expect(() => { + new GraphWidget({ + title: 'My fancy graph', + left: [ + new Metric({ namespace: 'CDK', metricName: 'Test' }), + ], + verticalAnnotations: [{ + date: '2021-07-29T02:31:09.890ZZ', + color: '667788', + fill: VerticalShading.AFTER, + label: 'this is the annotation', + }], + }); + }).toThrow(); + }); + test('convert alarm to annotation', () => { // GIVEN const stack = new Stack();