javascript:chartjs

Chart.js - デザイナーと開発者向けのシンプルでありながら柔軟な JavaScript チャート

Getting Started | Chart.js
Chart.js の「はじめに」のように、HTML、JavaScript、CSS に分けて、JavaScript は const labels (ラベル定義)、const data (データ定義)、const config (設定)、const myChart (グラフ描画) に分けて記述する🤔

公式ドキュメント Responsive Charts | Chart.js より抜粋🤔

The following examples do not work:

  • <canvas height=“40vh” width=“80vw”>: invalid values, the canvas doesn't resize (example)
  • <canvas style=“height:40vh; width:80vw”>: invalid behavior, the canvas is resized but becomes blurry (example)
  • <canvas style=“margin: 0 auto;”>: invalid behavior, the canvas continually shrinks. Chart.js needs a dedicated container for each canvas and this styling should be applied there.

Important Note
Detecting when the canvas size changes can not be done directly from the canvas element. Chart.js uses its parent container to update the canvas render and display sizes. However, this method requires the container to be relatively positioned and dedicated to the chart canvas only. Responsiveness can then be achieved by setting relative values for the container size (example):

<div class="chart-container" style="position: relative; height:40vh; width:80vw">
    <canvas id="chart"></canvas>
</div>

The chart can also be programmatically resized by modifying the container size:

chart.canvas.parentNode.style.height = '128px';
chart.canvas.parentNode.style.width = '128px';

Note that in order for the above code to correctly resize the chart height, the maintainAspectRatio option must also be set to false.

<canvas> を直接リサイズするのではなく、コンテナ <div class="chart-container"> に入れてコンテナをリサイズする🤔
optionsmaintainAspectRatio はデフォルトで true だが、これをキャンバスの縦横比を維持しないように false に設定する🤔
maintainAspectRatio: サイズ変更時に元のキャンバスの縦横比 (width/height) を維持します。
aspectRatio: キャンバスの縦横比 (width/height)。チャートの種類によりデフォルト 1 または 2。
HTML

  <div class="chart-container">
    <canvas id="myChart"></canvas>
  </div>

js

  const config = {
    options: {
      maintainAspectRatio: false,
    }
  }

css

.chart-container {
  position: relative;
  width: 200px;
  height: 400px
}

公式: インストール | pnpm
スタンドアロンスクリプトを使用してインストールする😉

$ curl -fsSL https://get.pnpm.io/install.sh | sh -

==> Downloading pnpm binaries 10.6.1
 WARN  using --force I sure hope you know what you are doing
Copying pnpm CLI from /tmp/tmp.j7EqhhSusj/pnpm to /home/tomoyan/.local/share/pnpm/pnpm
Appended new lines to /home/tomoyan/.zshrc

Next configuration changes were made:
export PNPM_HOME="/home/tomoyan/.local/share/pnpm"
case ":$PATH:" in
  *":$PNPM_HOME:"*) ;;
  *) export PATH="$PNPM_HOME:$PATH" ;;
esac

To start using pnpm, run:
source /home/tomoyan/.zshrc

$ . ~/.zshrc

動作確認…😉

$ pnpm -v

10.6.1

使い方🤔

$ pnpm -h

Version 10.6.1 (compiled to binary; bundled Node.js v20.11.1)
Usage: pnpm [command] [flags]
       pnpm [ -h | --help | -v | --version ]

Manage your dependencies:
      add                  Installs a package and any packages that it depends on. By default, any new package is
                           installed as a prod dependency
      import               Generates a pnpm-lock.yaml from an npm package-lock.json (or npm-shrinkwrap.json) file
   i, install              Install all dependencies for a project
  it, install-test         Runs a pnpm install followed immediately by a pnpm test
  ln, link                 Connect the local project to another one
      prune                Removes extraneous packages
  rb, rebuild              Rebuild a package
  rm, remove               Removes packages from node_modules and from the project's package.json
      unlink               Unlinks a package. Like yarn unlink but pnpm re-installs the dependency after removing
                           the external link
  up, update               Updates packages to their latest version based on the specified range

Review your dependencies:
      audit                Checks for known security issues with the installed packages
      licenses             Check licenses in consumed packages
  ls, list                 Print all the versions of packages that are installed, as well as their dependencies,
                           in a tree-structure
      outdated             Check for outdated packages

Run your scripts:
      exec                 Executes a shell command in scope of a project
      run                  Runs a defined package script
      start                Runs an arbitrary command specified in the package's "start" property of its "scripts"
                           object
   t, test                 Runs a package's "test" script, if one was provided

Other:
      cat-file             Prints the contents of a file based on the hash value stored in the index file
      cat-index            Prints the index file of a specific package from the store
      find-hash            Experimental! Lists the packages that include the file with the specified hash.
      pack                 Create a tarball from a package
      publish              Publishes a package to the registry
      root                 Prints the effective modules directory

Manage your store:
      store add            Adds new packages to the pnpm store directly. Does not modify any projects or files
                           outside the store
      store path           Prints the path to the active store directory
      store prune          Removes unreferenced (extraneous, orphan) packages from the store
      store status         Checks for modified packages in the store

Options:
  -r, --recursive          Run the command for each project in the workspace.

公式: pnpm env <cmd> | pnpm
Node.js LTS をインストールする🤔

$ pnpm env add -g lts

Fetching Node.js 20.17.0 ...
Node.js 20.17.0 was installed
  /home/tomoyan/.local/share/pnpm/nodejs/20.17.0
All specified Node.js versions were installed

Or

$ pnpm env use -g lts

Node.js 20.17.0 was installed
  /home/tomoyan/.local/share/pnpm/nodejs/20.17.0
Node.js 20.17.0 was activated
/home/tomoyan/.local/share/pnpm/node -> /home/tomoyan/.local/share/pnpm/nodejs/20.17.0/bin/node

2024/08/25 14:13 · ともやん

公式: Step-by-step guide | Chart.js

新しいプロジェクトディレクトリに、以下の内容の package.json を作成する…🤔

$ mkdir chartjs-example && cd chartjs-example
$ nano package.json

{
  "name": "chartjs-example",
  "version": "1.0.0",
  "license": "MIT",
  "scripts": {
    "dev": "parcel src/index.html",
    "build": "parcel build src/index.html"
  },
  "devDependencies": {
    "parcel": "^2.6.2"
  },
  "dependencies": {
    "@cubejs-client/core": "^0.31.0",
    "chart.js": "^4.0.0"
  }
}

pnpm install を実行して依存関係をインストールする…🤔

$ pnpm install

Lockfile is up to date, resolution step is skipped
Packages: +188
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Progress: resolved 188, reused 188, downloaded 0, added 188, done
node_modules/.pnpm/@swc+core@1.7.18_@swc+helpers@0.5.12/node_modules/@swc/core: Running postinstall script, done in 1.3ses/.pnpm/msgpackr-extract@3.0.3/node_modules/msgpackr-extract: Running install script, done in 268ms
node_modules/.pnpm/lmdb@2.8.5/node_modules/lmdb: Running install script, done in 221ms

dependencies:
+ @cubejs-client/core 0.31.63
+ chart.js 4.4.4

devDependencies:
+ parcel 2.12.0

Done in 4.6s

src ディレクトリを作成して、以下の内容で src/index.htmlsrc/acquisitions.js を作成する…🤔

$ mkdir src
$ nano src/index.html

<!doctype html>
<html lang="en">
  <head>
    <title>Chart.js example</title>
  </head>
  <body>
    <!-- <div style="width: 500px;"><canvas id="dimensions"></canvas></div><br/> -->
    <div style="width: 800px;"><canvas id="acquisitions"></canvas></div>

    <!-- <script type="module" src="dimensions.js"></script> -->
    <script type="module" src="acquisitions.js"></script>
  </body>
</html>

$ nano src/acquisitions.js

import Chart from 'chart.js/auto'

(async function() {
  const data = [
    { year: 2010, count: 10 },
    { year: 2011, count: 20 },
    { year: 2012, count: 15 },
    { year: 2013, count: 25 },
    { year: 2014, count: 22 },
    { year: 2015, count: 30 },
    { year: 2016, count: 28 },
  ];

  new Chart(
    document.getElementById('acquisitions'),
    {
      type: 'bar',
      data: {
        labels: data.map(row => row.year),
        datasets: [
          {
            label: 'Acquisitions by year',
            data: data.map(row => row.count)
          }
        ]
      }
    }
  );
})();

pnpm dev を実行して http://localhost:1234/ にアクセスする😉

$ pnpm dev


> chartjs-example@1.0.0 dev /home/tomoyan/my_projects/chartjs-example
> parcel src/index.html

Server running at http://localhost:1234Built in 22ms

http://localhost:1234/

Chart.js example

pnpm のインストール

Chart.js のソースコードをクローンする…🤔

$ git clone --depth 1 https://github.com/chartjs/Chart.js.git

Cloning into 'Chart.js'...
remote: Enumerating objects: 1890, done.
remote: Counting objects: 100% (1890/1890), done.
remote: Compressing objects: 100% (1501/1501), done.
remote: Total 1890 (delta 506), reused 1350 (delta 373), pack-reused 0 (from 0)
Receiving objects: 100% (1890/1890), 11.70 MiB | 10.65 MiB/s, done.
Resolving deltas: 100% (506/506), done.

Performant NPM でプロジェクトの依存関係をインストールする…🤔

$ pnpm install

Scope: all 7 workspace projects
Lockfile is up to date, resolution step is skipped
Packages: +1984
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Progress: resolved 1984, reused 1982, downloaded 0, added 1984, done

dependencies:
+ @kurkle/color 0.3.2

devDependencies:
+ @rollup/plugin-commonjs 23.0.7
+ @rollup/plugin-inject 5.0.3
+ @rollup/plugin-json 5.0.2
+ @rollup/plugin-node-resolve 15.0.1
+ @swc/core 1.3.42
+ @types/estree 1.0.0
+ @types/offscreencanvas 2019.7.0
+ @typescript-eslint/eslint-plugin 5.57.0
+ @typescript-eslint/parser 5.57.0
+ chartjs-adapter-luxon 1.3.1
+ chartjs-adapter-moment 1.0.1
+ chartjs-test-utils 0.4.0
+ concurrently 7.6.0
+ coveralls 3.1.1
+ cross-env 7.0.3
+ eslint 8.37.0
+ eslint-config-chartjs 0.3.0
+ eslint-plugin-es 4.1.0
+ eslint-plugin-html 7.1.0
+ eslint-plugin-markdown 3.0.0
+ esm 3.2.25
+ glob 8.1.0
+ jasmine 3.99.0
+ jasmine-core 3.99.1
+ karma 6.4.1
+ karma-chrome-launcher 3.1.1
+ karma-coverage 2.2.0
+ karma-edge-launcher 0.4.2
+ karma-firefox-launcher 2.1.2
+ karma-jasmine 4.0.2
+ karma-jasmine-html-reporter 1.7.0
+ karma-rollup-preprocessor 7.0.7
+ karma-safari-private-launcher 1.0.0
+ karma-spec-reporter 0.0.32
+ luxon 3.3.0
+ moment 2.29.4
+ moment-timezone 0.5.42
+ pixelmatch 5.3.0
+ rollup 3.20.2
+ rollup-plugin-cleanup 3.2.1
+ rollup-plugin-istanbul 4.0.0
+ rollup-plugin-swc3 0.7.0
+ rollup-plugin-terser 7.0.2
+ typescript 4.9.5
+ yargs 17.7.1

Done in 14.4s

Chart.js ドキュメントを実行する…🤔
Node.js の OpenSSL レガシープロバイダー オプションを有効にして pnpm で実行する😉
Node.js 17 では webpack v4 が使用する openssl 標準が非推奨になったので、これが修正されるまでは OpenSSL レガシープロバイダー オプションを有効にすることで回避する😊
nodejs 17: digital envelope routines::unsupported · Issue #14532 · webpack/webpack · GitHub
webpack v5 では対応されている😉 (add wasm md4 implementation by sokra · Pull Request #14584 · webpack/webpack · GitHub)

$ export NODE_OPTIONS=--openssl-legacy-provider

$ pnpm run docs:dev

> chart.js@4.4.4 docs:dev /home/tomoyan/my_projects/_js_src/Chart.js
> pnpm run build && pnpm --filter "./docs/**" dev


> chart.js@4.4.4 build /home/tomoyan/my_projects/_js_src/Chart.js
> rollup -c && pnpm emitDeclarations


src/index.umd.tsdist/chart.umd.js...
(!) Circular dependency
src/plugins/index.js -> src/plugins/plugin.colors.ts -> src/index.ts -> src/plugins/index.js
created dist/chart.umd.js in 6.9s

src/index.ts, src/helpers/index.ts./...
(!) Circular dependency
src/index.ts -> src/plugins/index.js -> src/plugins/plugin.colors.ts -> src/index.ts
created ./ in 1.8s

src/index.ts, src/helpers/index.ts./...
(!) Circular dependency
src/index.ts -> src/plugins/index.js -> src/plugins/plugin.colors.ts -> src/index.ts
created ./ in 1.9s

> chart.js@4.4.4 emitDeclarations /home/tomoyan/my_projects/_js_src/Chart.js
> tsc --emitDeclarationOnly && pnpm copyDeclarations


> chart.js@4.4.4 copyDeclarations /home/tomoyan/my_projects/_js_src/Chart.js
> node -e "fs.cpSync('./src/types/', './dist/types/', {recursive:true})"


> docs@4.0.0-dev dev /home/tomoyan/my_projects/_js_src/Chart.js/docs
> vuepress dev --no-cache

wait Extracting site metadata...
tip Apply theme vuepress-theme-chartjs (extends @vuepress/theme-default) ...
warning pointStyle has multiple declarations with a comment. An arbitrary comment will be used.
The comments for pointStyle are declared at:
	/home/tomoyan/my_projects/_js_src/Chart.js/src/types/index.d.ts:1994
	/home/tomoyan/my_projects/_js_src/Chart.js/src/types/index.d.ts:2044
tip Apply plugin container (i.e. "vuepress-plugin-container") ...
tip Apply plugin @vuepress/last-updated (i.e. "@vuepress/plugin-last-updated") ...
tip Apply plugin @vuepress/register-components (i.e. "@vuepress/plugin-register-components") ...
tip Apply plugin @vuepress/active-header-links (i.e. "@vuepress/plugin-active-header-links") ...
tip Apply plugin @vuepress/search (i.e. "@vuepress/plugin-search") ...
tip Apply plugin @vuepress/nprogress (i.e. "@vuepress/plugin-nprogress") ...
tip Apply plugin tabs (i.e. "vuepress-plugin-tabs") ...
tip Apply plugin flexsearch (i.e. "vuepress-plugin-flexsearch") ...
tip Apply plugin @vuepress/html-redirect (i.e. "@vuepress/plugin-html-redirect") ...
tip Apply plugin @vuepress/google-analytics (i.e. "@vuepress/plugin-google-analytics") ...
tip Apply plugin redirect (i.e. "vuepress-plugin-redirect") ...
tip Apply plugin dehydrate (i.e. "vuepress-plugin-dehydrate") ...
tip Apply plugin code-copy (i.e. "vuepress-plugin-code-copy") ...
tip Apply plugin typedoc (i.e. "vuepress-plugin-typedoc") ...
tip Apply plugin @simonbrunel/versions (i.e. "@simonbrunel/vuepress-plugin-versions") ...
Documentation generated at ./api
tip Clean cache...

 Client █████████████████████████ building (66%) 1192/1270 modules 78 active
 ... cache-loader  vue-loader  markdown-loader  api/interfaces/RenderTextOpts.md

 「wds」: Project is running at http://0.0.0.0:8080/
 「wds」: webpack output is served from /docs/master/
 「wds」: Content not from webpack is served from /home/tomoyan/my_projects/_js_src/Chart.js/docs/.vuepress/public
 「wds」: 404s will fallback to /index.html
Browserslist: caniuse-lite is outdated. Please run:
  npx update-browserslist-db@latest
  Why you should do it regularly: https://github.com/browserslist/update-db#readme
[BABEL] Note: The code generator has deoptimised the styling of /home/tomoyan/my_projects/_js_src/Chart.js/node_modules/.pnpm/@vuepress+core@1.9.9/node_modules/@vuepress/core/.temp/internal/siteData.js as it exceeds the max of 500KB.

success [09:27:10] Build e5d5ff finished in 98069 ms! 
> VuePress dev server listening at http://localhost:8080/docs/master/

http://localhost:8080/samples/

Chart.js Samples

vuepress dev --no-cache が opensslError を吐く場合…😢

$ pnpm run docs:dev

> chart.js@4.4.4 docs:dev /home/tomoyan/my_projects/_js_src/Chart.js
> pnpm run build && pnpm --filter "./docs/**" dev


> chart.js@4.4.4 build /home/tomoyan/my_projects/_js_src/Chart.js
> rollup -c && pnpm emitDeclarations


src/index.umd.tsdist/chart.umd.js...
(!) Circular dependency
src/plugins/index.js -> src/plugins/plugin.colors.ts -> src/index.ts -> src/plugins/index.js
created dist/chart.umd.js in 6.5s

src/index.ts, src/helpers/index.ts./...
(!) Circular dependency
src/index.ts -> src/plugins/index.js -> src/plugins/plugin.colors.ts -> src/index.ts
created ./ in 1.9s

src/index.ts, src/helpers/index.ts./...
(!) Circular dependency
src/index.ts -> src/plugins/index.js -> src/plugins/plugin.colors.ts -> src/index.ts
created ./ in 1.8s

> chart.js@4.4.4 emitDeclarations /home/tomoyan/my_projects/_js_src/Chart.js
> tsc --emitDeclarationOnly && pnpm copyDeclarations


> chart.js@4.4.4 copyDeclarations /home/tomoyan/my_projects/_js_src/Chart.js
> node -e "fs.cpSync('./src/types/', './dist/types/', {recursive:true})"


> docs@4.0.0-dev dev /home/tomoyan/my_projects/_js_src/Chart.js/docs
> vuepress dev --no-cache

wait Extracting site metadata...
tip Apply theme vuepress-theme-chartjs (extends @vuepress/theme-default) ...
warning pointStyle has multiple declarations with a comment. An arbitrary comment will be used.
The comments for pointStyle are declared at:
	/home/tomoyan/my_projects/_js_src/Chart.js/src/types/index.d.ts:1994
	/home/tomoyan/my_projects/_js_src/Chart.js/src/types/index.d.ts:2044
tip Apply plugin container (i.e. "vuepress-plugin-container") ...
tip Apply plugin @vuepress/last-updated (i.e. "@vuepress/plugin-last-updated") ...
tip Apply plugin @vuepress/register-components (i.e. "@vuepress/plugin-register-components") ...
tip Apply plugin @vuepress/active-header-links (i.e. "@vuepress/plugin-active-header-links") ...
tip Apply plugin @vuepress/search (i.e. "@vuepress/plugin-search") ...
tip Apply plugin @vuepress/nprogress (i.e. "@vuepress/plugin-nprogress") ...
tip Apply plugin tabs (i.e. "vuepress-plugin-tabs") ...
tip Apply plugin flexsearch (i.e. "vuepress-plugin-flexsearch") ...
tip Apply plugin @vuepress/html-redirect (i.e. "@vuepress/plugin-html-redirect") ...
tip Apply plugin @vuepress/google-analytics (i.e. "@vuepress/plugin-google-analytics") ...
tip Apply plugin redirect (i.e. "vuepress-plugin-redirect") ...
tip Apply plugin dehydrate (i.e. "vuepress-plugin-dehydrate") ...
tip Apply plugin code-copy (i.e. "vuepress-plugin-code-copy") ...
tip Apply plugin typedoc (i.e. "vuepress-plugin-typedoc") ...
tip Apply plugin @simonbrunel/versions (i.e. "@simonbrunel/vuepress-plugin-versions") ...
Documentation generated at ./api
tip Clean cache...



 Client █████████████████████████ building (40%) 1/2 modules 1 active
 ..../node_modules/.pnpm/webpack-dev-server@3.11.3_webpack@4.46.0/node_modules/webpack-dev-server/client/ind
ex.js

 「wds」: Project is running at http://0.0.0.0:8080/
 「wds」: webpack output is served from /docs/master/
 「wds」: Content not from webpack is served from /home/tomoyan/my_projects/_js_src/Chart.js/docs/.vuepress/public
 「wds」: 404s will fallback to /index.html
node:internal/crypto/hash:79
  this[kHandle] = new _Hash(algorithm, xofLen, algorithmId, getHashCache());
                  ^

Error: error:0308010C:digital envelope routines::unsupported
    at new Hash (node:internal/crypto/hash:79:19)
    at Object.createHash (node:crypto:139:10)
    at module.exports (/home/tomoyan/my_projects/_js_src/Chart.js/node_modules/.pnpm/webpack@4.46.0/node_modules/webpack/lib/util/createHash.js:135:53)
    at NormalModule._initBuildHash (/home/tomoyan/my_projects/_js_src/Chart.js/node_modules/.pnpm/webpack@4.46.0/node_modules/webpack/lib/NormalModule.js:417:16)
    at handleParseError (/home/tomoyan/my_projects/_js_src/Chart.js/node_modules/.pnpm/webpack@4.46.0/node_modules/webpack/lib/NormalModule.js:471:10)
    at /home/tomoyan/my_projects/_js_src/Chart.js/node_modules/.pnpm/webpack@4.46.0/node_modules/webpack/lib/NormalModule.js:503:5
    at /home/tomoyan/my_projects/_js_src/Chart.js/node_modules/.pnpm/webpack@4.46.0/node_modules/webpack/lib/NormalModule.js:358:12
    at /home/tomoyan/my_projects/_js_src/Chart.js/node_modules/.pnpm/loader-runner@2.4.0/node_modules/loader-runner/lib/LoaderRunner.js:373:3
    at iterateNormalLoaders (/home/tomoyan/my_projects/_js_src/Chart.js/node_modules/.pnpm/loader-runner@2.4.0/node_modules/loader-runner/lib/LoaderRunner.js:214:10)
    at Array.<anonymous> (/home/tomoyan/my_projects/_js_src/Chart.js/node_modules/.pnpm/loader-runner@2.4.0/node_modules/loader-runner/lib/LoaderRunner.js:205:4)
    at Storage.finished (/home/tomoyan/my_projects/_js_src/Chart.js/node_modules/.pnpm/enhanced-resolve@4.5.0/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:55:16)
    at /home/tomoyan/my_projects/_js_src/Chart.js/node_modules/.pnpm/enhanced-resolve@4.5.0/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:91:9
    at /home/tomoyan/my_projects/_js_src/Chart.js/node_modules/.pnpm/graceful-fs@4.2.11/node_modules/graceful-fs/graceful-fs.js:123:16
    at FSReqCallback.readFileAfterClose [as oncomplete] (node:internal/fs/read/context:68:3) {
  opensslErrorStack: [
    'error:03000086:digital envelope routines::initialization error',
    'error:0308010C:digital envelope routines::unsupported'
  ],
  library: 'digital envelope routines',
  reason: 'unsupported',
  code: 'ERR_OSSL_EVP_UNSUPPORTED'
}

Node.js v20.17.0
/home/tomoyan/my_projects/_js_src/Chart.js/docs:
 ERR_PNPM_RECURSIVE_RUN_FIRST_FAIL  docs@4.0.0-dev dev: `vuepress dev --no-cache`
Exit status 1
 ELIFECYCLE  Command failed with exit code 1.

参考: Node 19 Error: error:0308010C:digital envelope routines::unsupported · Issue #3136 · vuejs/vuepress · GitHub
Node.js の OpenSSL レガシープロバイダー オプションを有効にして再実行する😉

$ export NODE_OPTIONS=--openssl-legacy-provider

$ pnpm run docs:dev

  • javascript/chartjs.txt
  • 最終更新: 2024/08/27 13:46
  • by ともやん