Skip to content

Commit a4df721

Browse files
committed
feat(multiple): add Material chart component with line, bar, and pie support
1 parent d02338b commit a4df721

14 files changed

Lines changed: 1267 additions & 0 deletions

src/material/_index.scss

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,3 +143,5 @@
143143
tree-base, tree-overrides;
144144
@forward './timepicker/timepicker-theme' as timepicker-* show timepicker-theme, timepicker-color,
145145
timepicker-typography, timepicker-density, timepicker-base, timepicker-overrides;
146+
@forward './charts/chart-theme' as chart-* show chart-theme, chart-color, chart-typography,
147+
chart-density, chart-base;

src/material/charts/BUILD.bazel

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
load(
2+
"//tools:defaults.bzl",
3+
"markdown_to_html",
4+
"ng_project",
5+
"ng_web_test_suite",
6+
"sass_library",
7+
)
8+
9+
package(default_visibility = ["//visibility:public"])
10+
11+
sass_library(
12+
name = "m3",
13+
srcs = ["_m3-chart.scss"],
14+
deps = [
15+
"//src/material/core/tokens:m3_utils",
16+
],
17+
)
18+
19+
sass_library(
20+
name = "m2",
21+
srcs = ["_m2-chart.scss"],
22+
deps = [
23+
"//src/material/core/theming:_inspection",
24+
],
25+
)
26+
27+
sass_library(
28+
name = "theme",
29+
srcs = ["_chart-theme.scss"],
30+
deps = [
31+
":m2",
32+
":m3",
33+
"//src/material/core/theming",
34+
"//src/material/core/theming:_inspection",
35+
"//src/material/core/theming:_validation",
36+
"//src/material/core/tokens:token_utils",
37+
"//src/material/core/typography",
38+
],
39+
)
40+
41+
ng_project(
42+
name = "charts",
43+
srcs = [
44+
"chart.ts",
45+
"chart-types.ts",
46+
"chart-value.pipe.ts",
47+
"charts-module.ts",
48+
"index.ts",
49+
"public-api.ts",
50+
],
51+
assets = ["chart.html"],
52+
deps = [
53+
"//:node_modules/@angular/common",
54+
"//:node_modules/@angular/core",
55+
"//src/material/core",
56+
],
57+
)
58+
59+
ng_project(
60+
name = "unit_test_sources",
61+
testonly = True,
62+
srcs = glob(
63+
["**/*.spec.ts"],
64+
exclude = ["**/*.e2e.spec.ts"],
65+
),
66+
deps = [
67+
":charts",
68+
"//:node_modules/@angular/core",
69+
"//:node_modules/@angular/platform-browser",
70+
"//src/material/core",
71+
],
72+
)
73+
74+
ng_web_test_suite(
75+
name = "unit_tests",
76+
deps = [":unit_test_sources"],
77+
)
78+
79+
markdown_to_html(
80+
name = "overview",
81+
srcs = [":charts.md"],
82+
)
83+
84+
filegroup(
85+
name = "source-files",
86+
srcs = glob(["**/*.ts"]),
87+
)
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
@use '../core/theming/inspection';
2+
@use '../core/tokens/token-utils';
3+
@use '../core/typography/typography';
4+
@use './m2-chart';
5+
@use './m3-chart';
6+
@use 'sass:map';
7+
8+
/// Outputs base theme styles for the mat-chart.
9+
/// @param {Map} $theme The theme to generate base styles for.
10+
@mixin base($theme) {
11+
$tokens: map.get(m2-chart.get-tokens($theme), base);
12+
@if inspection.get-theme-version($theme) == 1 {
13+
$tokens: map.get(m3-chart.get-tokens($theme), base);
14+
}
15+
16+
@include token-utils.values($tokens);
17+
}
18+
19+
/// Outputs color theme styles for the mat-chart.
20+
/// @param {Map} $theme The theme to generate color styles for.
21+
/// @param {String} $color-variant The color variant to use.
22+
@mixin color($theme, $color-variant: null) {
23+
$tokens: map.get(m2-chart.get-tokens($theme), color);
24+
@if inspection.get-theme-version($theme) == 1 {
25+
$tokens: map.get(m3-chart.get-tokens($theme, $color-variant), color);
26+
}
27+
28+
@include token-utils.values($tokens);
29+
}
30+
31+
/// Outputs typography theme styles for the mat-chart.
32+
/// @param {Map} $theme The theme to generate typography styles for.
33+
@mixin typography($theme) {
34+
$tokens: map.get(m2-chart.get-tokens($theme), typography);
35+
@if inspection.get-theme-version($theme) == 1 {
36+
$tokens: map.get(m3-chart.get-tokens($theme), typography);
37+
}
38+
39+
@include token-utils.values($tokens);
40+
}
41+
42+
/// Outputs density theme styles for the mat-chart.
43+
/// @param {Map} $theme The theme to generate density styles for.
44+
@mixin density($theme) {
45+
$tokens: map.get(m2-chart.get-tokens($theme), density);
46+
@if inspection.get-theme-version($theme) == 1 {
47+
$tokens: map.get(m3-chart.get-tokens($theme), density);
48+
}
49+
50+
@include token-utils.values($tokens);
51+
}
52+
53+
/// Outputs all theme styles for the mat-chart.
54+
/// @param {Map} $theme The theme to generate styles for.
55+
/// @param {String} $color-variant The color variant to use.
56+
@mixin theme($theme, $color-variant: null) {
57+
@if inspection.get-theme-version($theme) == 1 {
58+
@include base($theme);
59+
@include color($theme, $color-variant);
60+
@include density($theme);
61+
@include typography($theme);
62+
} @else {
63+
@include base($theme);
64+
@if inspection.theme-has($theme, color) {
65+
@include color($theme);
66+
}
67+
@if inspection.theme-has($theme, density) {
68+
@include density($theme);
69+
}
70+
@if inspection.theme-has($theme, typography) {
71+
@include typography($theme);
72+
}
73+
}
74+
}

src/material/charts/_m2-chart.scss

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
@use 'sass:map';
2+
@use '../core/theming/inspection';
3+
4+
/// Generates custom tokens for the mat-chart (M2 theme).
5+
@function get-tokens($theme) {
6+
$foreground: inspection.get-theme-color($theme, foreground);
7+
$background: inspection.get-theme-color($theme, background);
8+
9+
@return (
10+
base: (
11+
chart-axis-color: map.get($foreground, divider),
12+
chart-grid-color: map.get($foreground, divider),
13+
),
14+
color: (
15+
chart-label-text-color: map.get($foreground, text),
16+
chart-axis-label-color: map.get($foreground, secondary-text),
17+
chart-tooltip-background: map.get($foreground, text),
18+
chart-tooltip-text-color: map.get($background, card),
19+
chart-legend-text-color: map.get($foreground, secondary-text),
20+
),
21+
typography: (
22+
chart-label-text-size: 14px,
23+
chart-label-text-weight: 500,
24+
chart-axis-label-size: 11px,
25+
chart-legend-text-size: 12px,
26+
),
27+
density: (),
28+
);
29+
}

src/material/charts/_m3-chart.scss

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
@use 'sass:map';
2+
@use '../core/tokens/m3-utils';
3+
@use '../core/tokens/m3';
4+
5+
/// Generates custom tokens for the mat-chart.
6+
@function get-tokens($theme: m3.$sys-theme, $color-variant: null) {
7+
$system: m3-utils.get-system($theme);
8+
@if $color-variant {
9+
$system: m3-utils.replace-colors-with-variant($system, primary, $color-variant);
10+
}
11+
12+
$tokens: (
13+
base: (
14+
chart-axis-color: map.get($system, outline),
15+
chart-grid-color: map.get($system, outline-variant),
16+
),
17+
color: (
18+
chart-label-text-color: map.get($system, on-surface),
19+
chart-axis-label-color: map.get($system, on-surface-variant),
20+
chart-tooltip-background: map.get($system, inverse-surface),
21+
chart-tooltip-text-color: map.get($system, inverse-on-surface),
22+
chart-legend-text-color: map.get($system, on-surface-variant),
23+
),
24+
typography: (
25+
chart-label-text-size: map.get($system, title-small-size),
26+
chart-label-text-weight: map.get($system, title-small-weight),
27+
chart-axis-label-size: map.get($system, label-small-size),
28+
chart-legend-text-size: map.get($system, label-small-size),
29+
),
30+
density: (),
31+
);
32+
33+
@return $tokens;
34+
}

src/material/charts/chart-types.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.dev/license
7+
*/
8+
9+
/** Supported chart types. */
10+
export type MatChartType = 'line' | 'bar' | 'pie';
11+
12+
/** A single data point in a chart dataset. */
13+
export interface MatChartDataPoint {
14+
label: string;
15+
value: number;
16+
}
17+
18+
/** A dataset to be rendered in the chart. */
19+
export interface MatChartDataset {
20+
label: string;
21+
data: MatChartDataPoint[];
22+
color?: string;
23+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.dev/license
7+
*/
8+
9+
import {Pipe, PipeTransform} from '@angular/core';
10+
import {MatChartDataPoint} from './chart-types';
11+
12+
/**
13+
* Looks up the numeric value for a given label inside a dataset's data array.
14+
* Used in the chart template to avoid calling methods inside `@for` loops.
15+
*
16+
* @example
17+
* {{ dataset.data | chartValue: 'Jan' }} // → 42
18+
*/
19+
@Pipe({name: 'chartValue'})
20+
export class MatChartValuePipe implements PipeTransform {
21+
transform(data: MatChartDataPoint[], label: string): number {
22+
return data.find(pt => pt.label === label)?.value ?? 0;
23+
}
24+
}

0 commit comments

Comments
 (0)