Skip to content

Commit

Permalink
feat(aws-cloudwatch): add support for sparkline graphs in SingleValue…
Browse files Browse the repository at this point in the history
…Widget (#21684)

Adds configuration option for enabling sparkline in SingleValueWidget.



Fixes #21683
  • Loading branch information
ackjewtn authored Aug 22, 2022
1 parent 60336c2 commit cf5d115
Show file tree
Hide file tree
Showing 11 changed files with 275 additions and 0 deletions.
13 changes: 13 additions & 0 deletions packages/@aws-cdk/aws-cloudwatch/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,7 @@ dashboard.addWidgets(new cloudwatch.SingleValueWidget({

Show as many digits as can fit, before rounding.


```ts
declare const dashboard: cloudwatch.Dashboard;

Expand All @@ -440,6 +441,18 @@ dashboard.addWidgets(new cloudwatch.SingleValueWidget({
}));
```

Sparkline allows you to glance the trend of a metric by displaying a simplified linegraph below the value. You can't use `sparkline: true` together with `setPeriodToTimeRange: true`

```ts
declare const dashboard: cloudwatch.Dashboard;

dashboard.addWidgets(new cloudwatch.SingleValueWidget({
metrics: [ /* ... */ ],

sparkline: true,
}));
```

### Text widget

A text widget shows an arbitrary piece of MarkDown. Use this to add explanations
Expand Down
13 changes: 13 additions & 0 deletions packages/@aws-cdk/aws-cloudwatch/lib/graph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,14 @@ export interface SingleValueWidgetProps extends MetricWidgetProps {
* @default false
*/
readonly fullPrecision?: boolean;

/**
* Whether to show a graph below the value illustrating the value for the whole time range.
* Cannot be used in combination with `setPeriodToTimeRange`
*
* @default false
*/
readonly sparkline?: boolean;
}

/**
Expand All @@ -347,6 +355,10 @@ export class SingleValueWidget extends ConcreteWidget {
super(props.width || 6, props.height || 3);
this.props = props;
this.copyMetricWarnings(...props.metrics);

if (props.setPeriodToTimeRange && props.sparkline) {
throw new Error('You cannot use setPeriodToTimeRange with sparkline');
}
}

public toJson(): any[] {
Expand All @@ -360,6 +372,7 @@ export class SingleValueWidget extends ConcreteWidget {
view: 'singleValue',
title: this.props.title,
region: this.props.region || cdk.Aws.REGION,
sparkline: this.props.sparkline,
metrics: allMetricsGraphJson(this.props.metrics, []),
setPeriodToTimeRange: this.props.setPeriodToTimeRange,
singleValueFullPrecision: this.props.fullPrecision,
Expand Down
1 change: 1 addition & 0 deletions packages/@aws-cdk/aws-cloudwatch/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
"@aws-cdk/assertions": "0.0.0",
"@aws-cdk/cdk-build-tools": "0.0.0",
"@aws-cdk/integ-runner": "0.0.0",
"@aws-cdk/integ-tests": "0.0.0",
"@aws-cdk/cfn2ts": "0.0.0",
"@aws-cdk/pkglint": "0.0.0",
"@types/jest": "^27.5.2",
Expand Down
47 changes: 47 additions & 0 deletions packages/@aws-cdk/aws-cloudwatch/test/graphs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,53 @@ describe('Graphs', () => {

});

test('add sparkline to singleValueWidget', () => {
// GIVEN
const stack = new Stack();
const metric = new Metric({ namespace: 'CDK', metricName: 'Test' });

// WHEN
const widget = new SingleValueWidget({
metrics: [metric],
sparkline: true,
});

// THEN
expect(stack.resolve(widget.toJson())).toEqual([{
type: 'metric',
width: 6,
height: 3,
properties: {
view: 'singleValue',
region: { Ref: 'AWS::Region' },
metrics: [
['CDK', 'Test'],
],
sparkline: true,
},
}]);


});

test('throws if setPeriodToTimeRange and sparkline is set on singleValueWidget', () => {
// GIVEN
new Stack();
const metric = new Metric({ namespace: 'CDK', metricName: 'Test' });

// WHEN
const toThrow = () => {
new SingleValueWidget({
metrics: [metric],
setPeriodToTimeRange: true,
sparkline: true,
});
};

// THEN
expect(() => toThrow()).toThrow(/You cannot use setPeriodToTimeRange with sparkline/);
});

test('add singleValueFullPrecision to singleValueWidget', () => {
// GIVEN
const stack = new Stack();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { App, Stack, StackProps } from '@aws-cdk/core';
import { IntegTest } from '@aws-cdk/integ-tests';
import { Dashboard, SingleValueWidget, Metric } from '../lib';

class TestStack extends Stack {
constructor(scope: App, id: string, props?: StackProps) {
super(scope, id, props);

const dashboard = new Dashboard(this, 'Dashboard');

const testMetric = new Metric({
namespace: 'CDK/Test',
metricName: 'Metric',
});

const widget = new SingleValueWidget({
metrics: [testMetric],
sparkline: true,
});

dashboard.addWidgets(widget);
}
}
const app = new App();
const testCase = new TestStack(app, 'aws-cdk-cloudwatch-singlevaluewidget-sparkline-integ');
new IntegTest(app, 'singlevaluewidget-with-sparkline', {
testCases: [testCase],
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"Resources": {
"Dashboard9E4231ED": {
"Type": "AWS::CloudWatch::Dashboard",
"Properties": {
"DashboardBody": {
"Fn::Join": [
"",
[
"{\"widgets\":[{\"type\":\"metric\",\"width\":6,\"height\":3,\"x\":0,\"y\":0,\"properties\":{\"view\":\"singleValue\",\"region\":\"",
{
"Ref": "AWS::Region"
},
"\",\"sparkline\":true,\"metrics\":[[\"CDK/Test\",\"Metric\"]]}}]}"
]
]
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"version":"20.0.0"}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"version": "20.0.0",
"testCases": {
"singlevaluewidget-with-sparkline/DefaultTest": {
"stacks": [
"aws-cdk-cloudwatch-singlevaluewidget-sparkline-integ"
],
"assertionStack": "singlevaluewidget-with-sparkline/DefaultTest/DeployAssert"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"version": "20.0.0",
"artifacts": {
"Tree": {
"type": "cdk:tree",
"properties": {
"file": "tree.json"
}
},
"aws-cdk-cloudwatch-singlevaluewidget-sparkline-integ": {
"type": "aws:cloudformation:stack",
"environment": "aws://unknown-account/unknown-region",
"properties": {
"templateFile": "aws-cdk-cloudwatch-singlevaluewidget-sparkline-integ.template.json",
"validateOnSynth": false
},
"metadata": {
"/aws-cdk-cloudwatch-singlevaluewidget-sparkline-integ/Dashboard/Resource": [
{
"type": "aws:cdk:logicalId",
"data": "Dashboard9E4231ED"
}
]
},
"displayName": "aws-cdk-cloudwatch-singlevaluewidget-sparkline-integ"
},
"singlevaluewidgetwithsparklineDefaultTestDeployAssert6B085881": {
"type": "aws:cloudformation:stack",
"environment": "aws://unknown-account/unknown-region",
"properties": {
"templateFile": "singlevaluewidgetwithsparklineDefaultTestDeployAssert6B085881.template.json",
"validateOnSynth": false
},
"displayName": "singlevaluewidget-with-sparkline/DefaultTest/DeployAssert"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
{
"version": "tree-0.1",
"tree": {
"id": "App",
"path": "",
"children": {
"Tree": {
"id": "Tree",
"path": "Tree",
"constructInfo": {
"fqn": "constructs.Construct",
"version": "10.1.78"
}
},
"aws-cdk-cloudwatch-singlevaluewidget-sparkline-integ": {
"id": "aws-cdk-cloudwatch-singlevaluewidget-sparkline-integ",
"path": "aws-cdk-cloudwatch-singlevaluewidget-sparkline-integ",
"children": {
"Dashboard": {
"id": "Dashboard",
"path": "aws-cdk-cloudwatch-singlevaluewidget-sparkline-integ/Dashboard",
"children": {
"Resource": {
"id": "Resource",
"path": "aws-cdk-cloudwatch-singlevaluewidget-sparkline-integ/Dashboard/Resource",
"attributes": {
"aws:cdk:cloudformation:type": "AWS::CloudWatch::Dashboard",
"aws:cdk:cloudformation:props": {
"dashboardBody": {
"Fn::Join": [
"",
[
"{\"widgets\":[{\"type\":\"metric\",\"width\":6,\"height\":3,\"x\":0,\"y\":0,\"properties\":{\"view\":\"singleValue\",\"region\":\"",
{
"Ref": "AWS::Region"
},
"\",\"sparkline\":true,\"metrics\":[[\"CDK/Test\",\"Metric\"]]}}]}"
]
]
}
}
},
"constructInfo": {
"fqn": "@aws-cdk/aws-cloudwatch.CfnDashboard",
"version": "0.0.0"
}
}
},
"constructInfo": {
"fqn": "@aws-cdk/aws-cloudwatch.Dashboard",
"version": "0.0.0"
}
}
},
"constructInfo": {
"fqn": "@aws-cdk/core.Stack",
"version": "0.0.0"
}
},
"singlevaluewidget-with-sparkline": {
"id": "singlevaluewidget-with-sparkline",
"path": "singlevaluewidget-with-sparkline",
"children": {
"DefaultTest": {
"id": "DefaultTest",
"path": "singlevaluewidget-with-sparkline/DefaultTest",
"children": {
"Default": {
"id": "Default",
"path": "singlevaluewidget-with-sparkline/DefaultTest/Default",
"constructInfo": {
"fqn": "constructs.Construct",
"version": "10.1.78"
}
},
"DeployAssert": {
"id": "DeployAssert",
"path": "singlevaluewidget-with-sparkline/DefaultTest/DeployAssert",
"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"
}
}
},
"constructInfo": {
"fqn": "@aws-cdk/core.App",
"version": "0.0.0"
}
}
}

0 comments on commit cf5d115

Please sign in to comment.