chart

HTML-first chart container, legend, axis, and tooltip primitives

Use Chart to frame application-rendered HTML, SVG, canvas, or a locally bundled chart library with a consistent container, axis, legend, and tooltip contract. For simple authored HTML plots, data-value and data-color synchronize to --value and --chart-color.

<figure aria-label="Monthly visitors" class="chart">
  <section>
    <hr />
    <ul>
      <li>
        <span
          aria-label="January desktop"
          data-value="72%"
          data-color="var(--chart-1)"
        ></span>
      </li>
    </ul>
  </section>
  <footer><span>Jan</span></footer>
</figure>

AngularCSS does not implement a chart engine. Plotting, scales, data, formatting, hover selection, and active-series state remain with authored HTML, the application’s selected chart library, and AngularTS. This keeps Chart from covering AngularTS application behavior while providing stable semantic and customization hooks.

Example

View source
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>AngularCSS Chart</title>
    <link rel="stylesheet" href="../../css/preflight.css" />
    <link rel="stylesheet" href="../../css/angular.css" />
    <link rel="stylesheet" href="../example.css" />
    <script src="../../js/angular-ts.umd.js"></script>
    <script src="../../js/angular-css.umd.js"></script>
  </head>
  <body ng-app="angular.css" ng-cloak data-example="chart-example">
    <figure
      class="visual-example chart"
      aria-label="Desktop and mobile visitors from January through June"
    >
      <section>
        <ul>
          <li>
            <span
              role="img"
              aria-label="January desktop"
              data-value="61%"
              data-color="#2563eb"
              style="--value: 61%; --chart-color: #2563eb"
            ></span>
            <span
              role="img"
              aria-label="January mobile"
              data-value="26%"
              data-color="#60a5fa"
              style="--value: 26%; --chart-color: #60a5fa"
            ></span>
          </li>
          <li>
            <span
              role="img"
              aria-label="February desktop"
              data-value="100%"
              data-color="#2563eb"
              style="--value: 100%; --chart-color: #2563eb"
            ></span>
            <span
              role="img"
              aria-label="February mobile"
              data-value="66%"
              data-color="#60a5fa"
              style="--value: 66%; --chart-color: #60a5fa"
            ></span>
          </li>
          <li>
            <span
              role="img"
              aria-label="March desktop"
              data-value="78%"
              data-color="#2563eb"
              style="--value: 78%; --chart-color: #2563eb"
            ></span>
            <span
              role="img"
              aria-label="March mobile"
              data-value="39%"
              data-color="#60a5fa"
              style="--value: 39%; --chart-color: #60a5fa"
            ></span>
          </li>
          <li>
            <span
              role="img"
              aria-label="April desktop"
              data-value="24%"
              data-color="#2563eb"
              style="--value: 24%; --chart-color: #2563eb"
            ></span>
            <span
              role="img"
              aria-label="April mobile"
              data-value="62%"
              data-color="#60a5fa"
              style="--value: 62%; --chart-color: #60a5fa"
            ></span>
          </li>
          <li>
            <span
              role="img"
              aria-label="May desktop"
              data-value="69%"
              data-color="#2563eb"
              style="--value: 69%; --chart-color: #2563eb"
            ></span>
            <span
              role="img"
              aria-label="May mobile"
              data-value="43%"
              data-color="#60a5fa"
              style="--value: 43%; --chart-color: #60a5fa"
            ></span>
          </li>
          <li>
            <span
              role="img"
              aria-label="June desktop"
              data-value="70%"
              data-color="#2563eb"
              style="--value: 70%; --chart-color: #2563eb"
            ></span>
            <span
              role="img"
              aria-label="June mobile"
              data-value="46%"
              data-color="#60a5fa"
              style="--value: 46%; --chart-color: #60a5fa"
            ></span>
          </li>
        </ul>
      </section>
    </figure>
  </body>
</html>

Axis, grid, tooltip, and legend

View source
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>AngularCSS Chart Workflows</title>
    <link rel="stylesheet" href="../../css/preflight.css" />
    <link rel="stylesheet" href="../../css/angular.css" />
    <link rel="stylesheet" href="../example.css" />
    <script src="../../js/angular-ts.umd.js"></script>
    <script src="../../js/angular-css.umd.js"></script>
  </head>
  <body
    ng-app="angular.css"
    ng-cloak
    ng-init="chartData=[{month:'January',short:'Jan',desktop:186,mobile:80,d:'61%',m:'26%'},{month:'February',short:'Feb',desktop:305,mobile:200,d:'100%',m:'66%'},{month:'March',short:'Mar',desktop:237,mobile:120,d:'78%',m:'39%'},{month:'April',short:'Apr',desktop:73,mobile:190,d:'24%',m:'62%'},{month:'May',short:'May',desktop:209,mobile:130,d:'69%',m:'43%'},{month:'June',short:'Jun',desktop:214,mobile:140,d:'70%',m:'46%'}]; tooltip={visible:false}; legendTip={visible:false}"
    data-example="chart-example-grid chart-example-axis chart-example-tooltip chart-example-legend"
  >
    <main class="chart-workflow-grid" aria-label="Chart composition workflows">
      <section class="chart-workflow" aria-labelledby="chart-grid-heading">
        <h2 id="chart-grid-heading">Grid</h2>
        <figure
          class="chart-reference-demo chart"
          aria-label="Visitor chart with horizontal grid"
        >
          <section>
            <hr />
            <ul>
              <li ng-repeat="point in chartData">
                <span
                  role="img"
                  aria-label="{{ point.month }} desktop"
                  data-value="{{ point.d }}"
                  data-color="#2563eb"
                  style="--value: {{ point.d }}; --chart-color: #2563eb"
                ></span>
                <span
                  role="img"
                  aria-label="{{ point.month }} mobile"
                  data-value="{{ point.m }}"
                  data-color="#60a5fa"
                  style="--value: {{ point.m }}; --chart-color: #60a5fa"
                ></span>
              </li>
            </ul>
          </section>
        </figure>
      </section>

      <section class="chart-workflow" aria-labelledby="chart-axis-heading">
        <h2 id="chart-axis-heading">Axis</h2>
        <figure
          class="chart-reference-demo chart"
          aria-label="Visitor chart with horizontal axis"
        >
          <section>
            <hr />
            <ul>
              <li ng-repeat="point in chartData">
                <span
                  role="img"
                  aria-label="{{ point.month }} desktop"
                  data-value="{{ point.d }}"
                  data-color="#2563eb"
                  style="--value: {{ point.d }}; --chart-color: #2563eb"
                ></span>
                <span
                  role="img"
                  aria-label="{{ point.month }} mobile"
                  data-value="{{ point.m }}"
                  data-color="#60a5fa"
                  style="--value: {{ point.m }}; --chart-color: #60a5fa"
                ></span>
              </li>
            </ul>
          </section>
          <footer>
            <span ng-repeat="point in chartData"> {{ point.short }} </span>
          </footer>
        </figure>
      </section>

      <section class="chart-workflow" aria-labelledby="chart-tooltip-heading">
        <h2 id="chart-tooltip-heading">Tooltip</h2>
        <figure
          class="chart-reference-demo chart"
          aria-label="Visitor chart with tooltip"
        >
          <section>
            <hr />
            <ul>
              <li
                ng-repeat="point in chartData"
                ng-mouseenter="tooltip.visible=true;tooltip.month=point.month;tooltip.desktop=point.desktop;tooltip.mobile=point.mobile"
                ng-mouseleave="tooltip.visible=false"
              >
                <span
                  role="img"
                  aria-label="{{ point.month }} desktop"
                  data-value="{{ point.d }}"
                  data-color="#2563eb"
                  style="--value: {{ point.d }}; --chart-color: #2563eb"
                ></span>
                <span
                  role="img"
                  aria-label="{{ point.month }} mobile"
                  data-value="{{ point.m }}"
                  data-color="#60a5fa"
                  style="--value: {{ point.m }}; --chart-color: #60a5fa"
                ></span>
              </li>
            </ul>
            <output class="chart-floating-tooltip" ng-if="tooltip.visible">
              <strong>{{ tooltip.month }}</strong>
              <dl>
                <div>
                  <dt>
                    <span
                      aria-hidden="true"
                      data-color="#2563eb"
                      style="--chart-color: #2563eb"
                    ></span
                    >Desktop
                  </dt>
                  <dd>{{ tooltip.desktop }}</dd>
                </div>
                <div>
                  <dt>
                    <span
                      aria-hidden="true"
                      data-color="#60a5fa"
                      style="--chart-color: #60a5fa"
                    ></span
                    >Mobile
                  </dt>
                  <dd>{{ tooltip.mobile }}</dd>
                </div>
              </dl>
            </output>
          </section>
          <footer>
            <span ng-repeat="point in chartData"> {{ point.short }} </span>
          </footer>
        </figure>
      </section>

      <section class="chart-workflow" aria-labelledby="chart-legend-heading">
        <h2 id="chart-legend-heading">Legend</h2>
        <figure
          class="chart-reference-demo chart"
          aria-label="Visitor chart with legend and tooltip"
        >
          <section>
            <hr />
            <ul>
              <li
                ng-repeat="point in chartData"
                ng-mouseenter="legendTip.visible=true;legendTip.month=point.month;legendTip.desktop=point.desktop;legendTip.mobile=point.mobile"
                ng-mouseleave="legendTip.visible=false"
              >
                <span
                  role="img"
                  aria-label="{{ point.month }} desktop"
                  data-value="{{ point.d }}"
                  data-color="#2563eb"
                  style="--value: {{ point.d }}; --chart-color: #2563eb"
                ></span>
                <span
                  role="img"
                  aria-label="{{ point.month }} mobile"
                  data-value="{{ point.m }}"
                  data-color="#60a5fa"
                  style="--value: {{ point.m }}; --chart-color: #60a5fa"
                ></span>
              </li>
            </ul>
            <output class="chart-floating-tooltip" ng-if="legendTip.visible">
              <strong>{{ legendTip.month }}</strong>
              <dl>
                <div>
                  <dt>
                    <span
                      aria-hidden="true"
                      data-color="#2563eb"
                      style="--chart-color: #2563eb"
                    ></span
                    >Desktop
                  </dt>
                  <dd>{{ legendTip.desktop }}</dd>
                </div>
                <div>
                  <dt>
                    <span
                      aria-hidden="true"
                      data-color="#60a5fa"
                      style="--chart-color: #60a5fa"
                    ></span
                    >Mobile
                  </dt>
                  <dd>{{ legendTip.mobile }}</dd>
                </div>
              </dl>
            </output>
          </section>
          <footer>
            <span ng-repeat="point in chartData"> {{ point.short }} </span>
          </footer>
          <ul>
            <li>
              <span data-color="#2563eb" style="--chart-color: #2563eb"></span
              >Desktop
            </li>
            <li>
              <span data-color="#60a5fa" style="--chart-color: #60a5fa"></span
              >Mobile
            </li>
          </ul>
        </figure>
      </section>
    </main>
  </body>
</html>

Interactive, RTL, and tooltip variants

View source
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>AngularCSS Chart Compositions</title>
    <link rel="stylesheet" href="../../css/preflight.css" />
    <link rel="stylesheet" href="../../css/angular.css" />
    <link rel="stylesheet" href="../example.css" />
    <script src="../../js/angular-ts.umd.js"></script>
    <script src="../../js/angular-css.umd.js"></script>
  </head>
  <body
    ng-app="angular.css"
    ng-cloak
    ng-init="activeChart='desktop'; demoTip={visible:false}; rtlTip={visible:false}; interactiveData=[{date:'Apr 1',d:222,m:150,dp:'49%',mp:'36%'},{date:'Apr 2',d:97,m:180,dp:'21%',mp:'43%'},{date:'Apr 3',d:167,m:120,dp:'37%',mp:'29%'},{date:'Apr 4',d:242,m:260,dp:'53%',mp:'62%'},{date:'Apr 5',d:373,m:290,dp:'82%',mp:'69%'},{date:'Apr 6',d:301,m:340,dp:'66%',mp:'81%'},{date:'Apr 7',d:245,m:180,dp:'54%',mp:'43%'},{date:'Apr 8',d:409,m:320,dp:'90%',mp:'76%'},{date:'Apr 9',d:59,m:110,dp:'13%',mp:'26%'},{date:'Apr 10',d:261,m:190,dp:'57%',mp:'45%'},{date:'Apr 11',d:327,m:350,dp:'72%',mp:'83%'},{date:'Apr 12',d:292,m:210,dp:'64%',mp:'50%'},{date:'Apr 13',d:342,m:380,dp:'75%',mp:'90%'},{date:'Apr 14',d:137,m:220,dp:'30%',mp:'52%'},{date:'Apr 15',d:120,m:170,dp:'26%',mp:'40%'},{date:'Apr 16',d:138,m:190,dp:'30%',mp:'45%'},{date:'Apr 17',d:446,m:360,dp:'98%',mp:'86%'},{date:'Apr 18',d:364,m:410,dp:'80%',mp:'98%'},{date:'Apr 19',d:243,m:180,dp:'54%',mp:'43%'},{date:'Apr 20',d:89,m:150,dp:'20%',mp:'36%'},{date:'Apr 21',d:137,m:200,dp:'30%',mp:'48%'},{date:'Apr 22',d:224,m:170,dp:'49%',mp:'40%'},{date:'Apr 23',d:138,m:230,dp:'30%',mp:'55%'},{date:'Apr 24',d:387,m:290,dp:'85%',mp:'69%'},{date:'Apr 25',d:215,m:250,dp:'47%',mp:'60%'},{date:'Apr 26',d:75,m:130,dp:'17%',mp:'31%'},{date:'Apr 27',d:383,m:420,dp:'84%',mp:'100%'},{date:'Apr 28',d:122,m:180,dp:'27%',mp:'43%'},{date:'Apr 29',d:315,m:240,dp:'69%',mp:'57%'},{date:'Apr 30',d:454,m:380,dp:'100%',mp:'90%'}]; rtlData=[{month:'يناير',short:'ينا',desktop:186,mobile:80,d:'61%',m:'26%'},{month:'فبراير',short:'فبر',desktop:305,mobile:200,d:'100%',m:'66%'},{month:'مارس',short:'مار',desktop:237,mobile:120,d:'78%',m:'39%'},{month:'أبريل',short:'أبر',desktop:73,mobile:190,d:'24%',m:'62%'},{month:'مايو',short:'ماي',desktop:209,mobile:130,d:'69%',m:'43%'},{month:'يونيو',short:'يون',desktop:214,mobile:140,d:'70%',m:'46%'}]"
    data-example="chart-demo chart-rtl chart-tooltip"
  >
    <main
      class="chart-composition-grid"
      aria-label="Chart reference compositions"
    >
      <article class="chart-interactive-card chart-composition-wide card">
        <header class="chart-interactive-header">
          <div class="chart-interactive-copy">
            <h2>Bar Chart - Interactive</h2>
            <p>Showing total visitors for the last 3 months</p>
          </div>
          <div class="chart-series-controls" aria-label="Visitor series">
            <button
              type="button"
              variant="ghost"
              aria-pressed="{{ activeChart == 'desktop' }}"
              ng-click="activeChart='desktop'"
            >
              <span>Desktop</span><strong>7,324</strong>
            </button>
            <button
              type="button"
              variant="ghost"
              aria-pressed="{{ activeChart == 'mobile' }}"
              ng-click="activeChart='mobile'"
            >
              <span>Mobile</span><strong>7,250</strong>
            </button>
          </div>
        </header>
        <section class="chart-interactive-content">
          <figure
            class="chart-interactive-demo chart"
            aria-label="Interactive daily visitors"
          >
            <section>
              <hr />
              <div class="chart-daily-bars">
                <span
                  role="img"
                  ng-repeat="point in interactiveData"
                  aria-label="{{ point.date }} {{ activeChart }}"
                  data-value="{{ activeChart == 'desktop' ? point.dp : point.mp }}"
                  data-color="{{ activeChart == 'desktop' ? 'var(--chart-2)' : 'var(--chart-1)' }}"
                  ng-mouseenter="demoTip.visible=true;demoTip.date=point.date;demoTip.value=activeChart == 'desktop' ? point.d : point.m"
                  ng-mouseleave="demoTip.visible=false"
                  style="--value: {{ activeChart == 'desktop' ? point.dp : point.mp }}; --chart-color: {{ activeChart == 'desktop' ? 'var(--chart-2)' : 'var(--chart-1)' }}"
                ></span>
              </div>
              <output class="chart-floating-tooltip" ng-if="demoTip.visible">
                <strong>{{ demoTip.date }}, 2024</strong>
                <dl>
                  <div>
                    <dt>
                      <span
                        aria-hidden="true"
                        data-color="{{ activeChart == 'desktop' ? 'var(--chart-2)' : 'var(--chart-1)' }}"
                        style="--chart-color: {{ activeChart == 'desktop' ? 'var(--chart-2)' : 'var(--chart-1)' }}"
                      ></span>
                      {{ activeChart == 'desktop' ? 'Desktop' : 'Mobile' }}
                    </dt>
                    <dd>{{ demoTip.value }}</dd>
                  </div>
                </dl>
              </output>
            </section>
            <footer class="chart-date-axis">
              <span>Apr 1</span>
              <span>Apr 8</span>
              <span>Apr 15</span>
              <span>Apr 22</span>
              <span>Apr 30</span>
            </footer>
          </figure>
        </section>
      </article>

      <section
        class="chart-composition"
        aria-labelledby="chart-rtl-heading"
        dir="rtl"
        lang="ar"
      >
        <h2 id="chart-rtl-heading">مخطط من اليمين إلى اليسار</h2>
        <figure
          class="chart-reference-demo chart"
          aria-label="زوار سطح المكتب والجوال"
        >
          <section>
            <hr />
            <ul>
              <li
                ng-repeat="point in rtlData"
                ng-mouseenter="rtlTip.visible=true;rtlTip.month=point.month;rtlTip.desktop=point.desktop;rtlTip.mobile=point.mobile"
                ng-mouseleave="rtlTip.visible=false"
              >
                <span
                  role="img"
                  aria-label="{{ point.month }} سطح المكتب"
                  data-value="{{ point.d }}"
                  data-color="var(--chart-2)"
                  style="--value: {{ point.d }}; --chart-color: var(--chart-2)"
                ></span>
                <span
                  role="img"
                  aria-label="{{ point.month }} الجوال"
                  data-value="{{ point.m }}"
                  data-color="var(--chart-1)"
                  style="--value: {{ point.m }}; --chart-color: var(--chart-1)"
                ></span>
              </li>
            </ul>
            <output class="chart-floating-tooltip" ng-if="rtlTip.visible">
              <strong>{{ rtlTip.month }}</strong>
              <dl>
                <div>
                  <dt>
                    <span
                      aria-hidden="true"
                      data-color="var(--chart-2)"
                      style="--chart-color: var(--chart-2)"
                    ></span
                    >سطح المكتب
                  </dt>
                  <dd>{{ rtlTip.desktop }}</dd>
                </div>
                <div>
                  <dt>
                    <span
                      aria-hidden="true"
                      data-color="var(--chart-1)"
                      style="--chart-color: var(--chart-1)"
                    ></span
                    >الجوال
                  </dt>
                  <dd>{{ rtlTip.mobile }}</dd>
                </div>
              </dl>
            </output>
          </section>
          <footer>
            <span ng-repeat="point in rtlData"> {{ point.short }} </span>
          </footer>
          <ul>
            <li>
              <span
                data-color="var(--chart-2)"
                style="--chart-color: var(--chart-2)"
              ></span
              >سطح المكتب
            </li>
            <li>
              <span
                data-color="var(--chart-1)"
                style="--chart-color: var(--chart-1)"
              ></span
              >الجوال
            </li>
          </ul>
        </figure>
      </section>

      <section
        class="chart-composition"
        aria-labelledby="chart-tooltip-gallery-heading"
      >
        <h2 id="chart-tooltip-gallery-heading">Tooltip anatomy</h2>
        <figure
          class="chart-tooltip-gallery chart"
          aria-label="Chart tooltip anatomy examples"
        >
          <output>
            <strong>Page Views</strong>
            <dl>
              <div>
                <dt>
                  <span
                    aria-hidden="true"
                    data-color="var(--chart-1)"
                    style="--chart-color: var(--chart-1)"
                  ></span
                  >Desktop
                </dt>
                <dd>186</dd>
              </div>
              <div>
                <dt>
                  <span
                    aria-hidden="true"
                    data-color="var(--chart-2)"
                    style="--chart-color: var(--chart-2)"
                  ></span
                  >Mobile
                </dt>
                <dd>80</dd>
              </div>
            </dl>
          </output>
          <output>
            <dl>
              <div>
                <dt>
                  <span
                    aria-hidden="true"
                    indicator="dashed"
                    data-color="var(--chart-3)"
                    style="--chart-color: var(--chart-3)"
                  ></span
                  >Chrome
                </dt>
                <dd>1,286</dd>
              </div>
              <div>
                <dt>
                  <span
                    aria-hidden="true"
                    indicator="dashed"
                    data-color="var(--chart-4)"
                    style="--chart-color: var(--chart-4)"
                  ></span
                  >Firefox
                </dt>
                <dd>1,000</dd>
              </div>
            </dl>
          </output>
          <output>
            <dl>
              <div>
                <dt>
                  <span
                    aria-hidden="true"
                    indicator="line"
                    data-color="var(--chart-3)"
                    style="--chart-color: var(--chart-3)"
                  ></span
                  ><strong>Page Views</strong><br />Desktop
                </dt>
                <dd>12,486</dd>
              </div>
            </dl>
          </output>
          <output>
            <dl>
              <div>
                <dt>
                  <span
                    aria-hidden="true"
                    data-color="var(--chart-1)"
                    style="--chart-color: var(--chart-1)"
                  ></span
                  >Chrome
                </dt>
                <dd>1,286</dd>
              </div>
            </dl>
          </output>
        </figure>
      </section>
    </main>
  </body>
</html>

Installation

Load the AngularCSS stylesheet. This entry needs no AngularCSS JavaScript or angular.css module dependency. Add AngularTS when using application bindings such as ng-model or ng-click. See Installation for the complete setup.

This entry uses native HTML and CSS. AngularCSS registers no runtime directive for it. Authored figures, tables, and CSS variables.

Anatomy

Root styling selector

  • .chart

Semantic structure

Apply .chart to an accessible figure. Compose its optional title, plot, grid, grouped bars, axis, legend, and tooltip from semantic header, section, hr, ul, li, footer, output, and description-list elements; no anatomy classes are required.

API

Attributes and state

AttributeAccessPurpose
data-colorAuthoredSeries color key used by the example or application to set --chart-color.
data-valueAuthoredAuthored bar height as a percentage when --value is not set.
indicatorAuthoredLegend indicator: line or dashed; omit for a solid mark.

Attributes remain authored HTML, native state, or AngularTS inputs. AngularCSS does not write element state.

CSS custom properties

VariablePurpose
--chart-colorColor for an authored series, mark, or legend indicator.
--valueBar height as a percentage; falls back to data-value and then 50%.

DOM events

This component does not emit a component-specific custom event.

Native DOM events continue to work normally. AngularTS event directives such as ng-click and ng-keydown, plus the data-change model callback, remain application-owned.

Behavior

Semantic figure, heading, list, and data markup owns chart meaning. CSS variables provide visual values and colors; authored HTML, SVG, canvas, or an application-selected chart library owns plotting, scales, data, formatting, and interaction. AngularCSS registers no chart directive.

AngularCSS does not replace AngularTS interpolation, bindings, structural directives, form controllers, validation, or application state.

Accessibility

Give every chart root a useful accessible name and provide a textual or tabular equivalent when exact values matter. Bars expose authored labels and values; axes and legends are lists; grid decoration is hidden; visible tooltips are status regions. Never use color as the only distinction between series.

Authored accessible names and relationships are preserved. Test the final composition with keyboard navigation and assistive technology because labels and content come from the application.

Customization

Target semantic elements, native state selectors, and component classes with ordinary CSS. Behavior and accessible state remain with native HTML and AngularTS; visual choices belong in the application stylesheet.

Read Customization for layer order, design tokens, state variants, and iframe demo isolation.