Skip to content

Commit

Permalink
Percent gauge SSR (#1982)
Browse files Browse the repository at this point in the history
* Fix SSR for percent gauge chart

* Fix light theme

* Remove comments

* Update changelog and version
  • Loading branch information
marjan-georgiev authored Dec 20, 2024
1 parent cc4a393 commit 3688955
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 89 deletions.
6 changes: 6 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## 21.1.1

- Fix: Percent Gauge Chart: Fixes server-side-rendering
- Fix: Percent Gauge Chart: Fixes light theme
- Fix: Percent Gauge Chart: Makes target circle highlight only when target is reached

## 21.1.0

- Feature: Add Percent Gauge chart type
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@
"d3-time-format": "^4.1.0",
"d3-transition": "^3.0.1",
"emoji-flags": "^1.2.0",
"gradient-path": "^2.3.0",
"moment-timezone": "^0.5.40",
"ng-in-viewport": "^6.1.5",
"ngx-moment": "^5.0.0",
Expand Down
2 changes: 1 addition & 1 deletion projects/swimlane/ngx-charts/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@swimlane/ngx-charts",
"version": "21.1.0",
"version": "21.1.1",
"description": "Declarative Charting Framework for Angular",
"repository": {
"type": "git",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,16 @@
}

.dashes-back {
stroke: #455066;
stroke: #e7e7e7;
}

.target-circle {
fill: #1b1e27;
.target-circle,
.target-circle-bg {
fill: white;
}

.target-label {
fill: #a0aabe;
}

.target-value {
fill: #cdd2dd;
.target-circle-bg {
stroke: #e7e7e7;
}

.total {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Component, Input, ViewEncapsulation, ChangeDetectionStrategy, ElementRef, ViewChild } from '@angular/core';
import { GradientPath } from 'gradient-path';
import { Component, Input, ViewEncapsulation, ChangeDetectionStrategy } from '@angular/core';

import { BaseChartComponent } from '../../common/base-chart.component';
import { calculateViewDimensions } from '../../common/view-dimensions.helper';
Expand All @@ -26,11 +25,10 @@ import { ScaleType } from '../../common/types/scale-type.enum';
[style.stroke-dashoffset]="circumference * (1 - percent / 100)"
/>
</mask>
<text x="0" y="0" fill="white" stroke="none" class="total" [style.font-size]="valueFontSize">
<text x="0" y="0" stroke="none" class="total" [style.font-size]="valueFontSize">
{{ displayValue }}
</text>
<circle
#circleEl
class="dashes-back"
[style.stroke-width]="radius / 5"
[attr.r]="radius"
Expand All @@ -56,6 +54,14 @@ import { ScaleType } from '../../common/types/scale-type.enum';
<svg:g [attr.transform]="targetTransform">
<circle
class="target-circle-bg"
[attr.r]="targetRadius"
[style.stroke-width]="targetRadius / 10"
[attr.cx]="-targetRadius / 2"
[attr.cy]="-targetRadius / 2"
/>
<circle
*ngIf="percent >= target"
class="target-circle"
[attr.r]="targetRadius"
[style.stroke-width]="targetRadius / 10"
Expand Down Expand Up @@ -106,8 +112,6 @@ export class PercentGaugeComponent extends BaseChartComponent {
@Input() valueFormatting: any;
@Input() showLabel = true;

@ViewChild('circleEl') circleElement: ElementRef;

defaultMargin: number[] = [20, 40, 20, 40];
margin: number[] = [20, 40, 20, 40];
dims: ViewDimensions;
Expand Down Expand Up @@ -182,46 +186,34 @@ export class PercentGaugeComponent extends BaseChartComponent {
this.cd.markForCheck();
}

generateCirclePoints(radius: number, numPoints: number): { x: number; y: number }[] {
const points = [];
for (let i = 0; i < numPoints; i++) {
const angle = (i / numPoints) * 2 * Math.PI;
const x = radius * Math.cos(angle);
const y = radius * Math.sin(angle);
points.push({ x, y });
}
return points;
}

generateticks() {
if (this.circleElement?.nativeElement) {
const clonedCircle = this.circleElement.nativeElement.cloneNode(true);
clonedCircle.setAttribute('stroke-width', this.radius / 5);
clonedCircle.setAttribute('r', this.radius);

this.circleElement.nativeElement.parentElement.appendChild(clonedCircle);

try {
const gp = new GradientPath({
path: clonedCircle,
segments: 60,
samples: 2,
precision: 2
});

clonedCircle.remove();

const data = gp.data.flatMap(({ samples }) => samples);
this.ticks = [];
this.circleTransform = `rotate(-90,0,0)`;
for (let j = 0; j < data.length; j++) {
const { x, y } = data[j];
let progress = data[j].progress;
if (progress === 1) {
progress = 0;
}

this.ticks.push({
height: this.ticHeight,
width: this.radius / 60,
fill: this.colors.getColor(progress * this.max),
transform: `translate(${x}, ${y}), rotate(${360 * progress - 90})`
});
}
} catch (e) {
console.log('Unable to generate ticks for percent gauge chart', e);
} finally {
clonedCircle.remove();
const numPoints = 60;
const points = this.generateCirclePoints(this.radius, numPoints);
this.ticks = [];
this.circleTransform = `rotate(-90,0,0)`;
for (let j = 0; j < points.length; j++) {
const { x, y } = points[j];
let progress = j / numPoints;
if (progress === 1) {
progress = 0;
}
this.ticks.push({
height: this.ticHeight,
width: this.radius / 60,
fill: this.colors.getColor(progress * this.max),
transform: `translate(${x}, ${y}), rotate(${360 * progress - 90})`
});
}
}

Expand Down
23 changes: 23 additions & 0 deletions src/app/app.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -334,4 +334,27 @@ main {
font-size: 0.8em;
color: $color-text-med;
}

.percent-gauge {
.dashes-back {
stroke: #455066;
}

.target-circle,
.target-circle-bg {
fill: #1b1e27;
}

.target-circle-bg {
stroke: #455066;
}

.target-label {
fill: #a0aabe;
}

.target-value {
fill: #cdd2dd;
}
}
}
34 changes: 0 additions & 34 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4600,13 +4600,6 @@ __metadata:
languageName: node
linkType: hard

"@types/tinycolor2@npm:^1.4.0":
version: 1.4.6
resolution: "@types/tinycolor2@npm:1.4.6"
checksum: 10c0/922020c3326460e9d8502c8a98f80db69f06fd14e07fe5a48e8ffe66175762298a9bd51263f2a0c9a40632886a74975a3ff79396defcdbeac0dc176e3e5056e8
languageName: node
linkType: hard

"@types/wrap-ansi@npm:^3.0.0":
version: 3.0.0
resolution: "@types/wrap-ansi@npm:3.0.0"
Expand Down Expand Up @@ -8573,15 +8566,6 @@ __metadata:
languageName: node
linkType: hard

"gradient-path@npm:^2.3.0":
version: 2.3.0
resolution: "gradient-path@npm:2.3.0"
dependencies:
tinygradient: "npm:^1.0.0"
checksum: 10c0/5008d2c89b1985a41e5ac8932285b934a9ffed1a8fd26b006be8770c10be2fc00f3b8038b2373c387595307ad659bf0f396365756ec781301ef9348d0f444b8e
languageName: node
linkType: hard

"graphemer@npm:^1.4.0":
version: 1.4.0
resolution: "graphemer@npm:1.4.0"
Expand Down Expand Up @@ -11245,7 +11229,6 @@ __metadata:
eslint: "npm:^8.57.0"
eslint-config-prettier: "npm:^8.5.0"
eslint-plugin-security: "npm:^1.5.0"
gradient-path: "npm:^2.3.0"
jasmine-core: "npm:~4.2.0"
jasmine-spec-reporter: "npm:~7.0.0"
karma: "npm:~6.4.0"
Expand Down Expand Up @@ -14260,23 +14243,6 @@ __metadata:
languageName: node
linkType: hard

"tinycolor2@npm:^1.0.0":
version: 1.6.0
resolution: "tinycolor2@npm:1.6.0"
checksum: 10c0/9aa79a36ba2c2a87cb221453465cabacd04b9e35f9694373e846fdc78b1c768110f81e581ea41440106c0f24d9a023891d0887e8075885e790ac40eb0e74a5c1
languageName: node
linkType: hard

"tinygradient@npm:^1.0.0":
version: 1.1.5
resolution: "tinygradient@npm:1.1.5"
dependencies:
"@types/tinycolor2": "npm:^1.4.0"
tinycolor2: "npm:^1.0.0"
checksum: 10c0/00503406e1a49822e58e90ddbda7e9db332b6a237fab5f413be9644eb29ca14f6a30e7961fc61328407fa6159437908c11eeda4f1d56e62586f9a48267d1094d
languageName: node
linkType: hard

"tmp@npm:0.0.30":
version: 0.0.30
resolution: "tmp@npm:0.0.30"
Expand Down

0 comments on commit 3688955

Please sign in to comment.