Help:Shortcode Chart

Create a simple chart.

Chart
Shortcode
Description
TypeHTML Shortcode
Nested?false
Shortcodechart
Return TypeHTML with inline JS
Short Description
Render a charts using chart.js.
Extensions Available
Pluginsannotation
Adaptersmoment
Development
MaintainerMichael Sasser

Use the chart shortcode to render charts using chart.js .

Parameters

The Chart shortcode has the following parameters:

ParameterDescription
widthThe width of the chart in percent of the available space. Default: 100
heightThe height of the chart in px. Default: 400
[0]The chart.js options as JS

Examples

{{< chart height=250 width=50 >}}
{
    type: 'doughnut',
    data: {
        labels: ['Python', 'Community', 'Off-Topic', 'Meta', 'Space'],
        datasets: [{
            data: [13179, 484, 262, 142, 23],
            backgroundColor: [
                'rgba(255, 99, 132, 0.2)',
                'rgba(54, 162, 235, 0.2)',
                'rgba(255, 206, 86, 0.2)',
                'rgba(75, 192, 192, 0.2)',
                'rgba(153, 102, 255, 0.2)',
            ],
            borderColor: [
                'rgba(255, 99, 132, 1)',
                'rgba(54, 162, 235, 1)',
                'rgba(255, 206, 86, 1)',
                'rgba(75, 192, 192, 1)',
                'rgba(153, 102, 255, 1)',
            ],
        }]
    },
    options: {
        responsive: true,
        maintainAspectRatio: false,
        plugins: {legend: {position: 'right'}}
    }
}
{{</ chart >}}
{{< chart >}}
{
    type: 'line',
    data: {
        datasets: [{
            label: 'Joined Members',
            lineTension: 0.2,
            pointStyle: false,
            data: [
                {x: 1688479200000, y: 398},
                {x: 1688508000000, y: 399},
                {x: 1688529600000, y: 400},
                {x: 1688680800000, y: 399},
                {x: 1688691600000, y: 400},
                {x: 1688713200000, y: 401},
                {x: 1688734800000, y: 402},
                {x: 1688738400000, y: 401},
                {x: 1688742000000, y: 402},
                {x: 1688821200000, y: 401},
                {x: 1688850000000, y: 400},
                {x: 1688929200000, y: 400},
                {x: 1688986800000, y: 399},
                {x: 1689091200000, y: 403},
                {x: 1689094800000, y: 409},
                {x: 1689098400000, y: 411},
                {x: 1689102000000, y: 412},
                {x: 1689112800000, y: 413},
                {x: 1689138000000, y: 414},
                {x: 1689170400000, y: 415},
                {x: 1689188400000, y: 416},
                {x: 1689282000000, y: 417},
                {x: 1689336000000, y: 418},
                {x: 1689397200000, y: 418},
                {x: 1689487200000, y: 419},
                {x: 1689519600000, y: 419},
                {x: 1689573600000, y: 419},
                {x: 1689588000000, y: 423},
                {x: 1689595200000, y: 426},
                {x: 1689598800000, y: 427},
                {x: 1689602400000, y: 429},
                {x: 1689609600000, y: 430},
                {x: 1689616800000, y: 431},
                {x: 1689624000000, y: 435},
                {x: 1689627600000, y: 437},
                {x: 1689631200000, y: 438},
                {x: 1689634800000, y: 441},
                {x: 1689645600000, y: 441},
                {x: 1689649200000, y: 442},
                {x: 1689656400000, y: 443},
                {x: 1689660000000, y: 444},
                {x: 1689663600000, y: 445},
                {x: 1689674400000, y: 446},
                {x: 1689685200000, y: 446},
                {x: 1689703200000, y: 447},
                {x: 1689706800000, y: 448},
                {x: 1689728400000, y: 449},
                {x: 1689782400000, y: 450},
                {x: 1689789600000, y: 449},
                {x: 1689807600000, y: 450},
                {x: 1689840000000, y: 450},
                {x: 1689854400000, y: 451},
                {x: 1689861600000, y: 451},
                {x: 1689901200000, y: 451},
                {x: 1689933600000, y: 451},
                {x: 1689958800000, y: 452},
                {x: 1690023600000, y: 451},
                {x: 1690038000000, y: 452},
                {x: 1690102800000, y: 453},
                {x: 1690146000000, y: 453},
                {x: 1690167600000, y: 453},
                {x: 1690189200000, y: 454},
                {x: 1690192800000, y: 456},
                {x: 1690203600000, y: 458},
                {x: 1690243200000, y: 459},
                {x: 1690311600000, y: 459},
                {x: 1690416000000, y: 459},
            ],
            backgroundColor: [
                'rgba(255, 99, 132, 0.2)',
            ],
            borderColor: [
                'rgba(255, 99, 132, 1)',
            ],
            borderWidth: 1
        }]
    },
    options: {
      maintainAspectRatio: false,
      plugins: {
        annotation: {
          annotations: {
            first: {
              type: 'line',
              borderColor: 'rgba(54, 162, 235, 1)',
              borderDash: [6, 6],
              borderWidth: 1,
              scaleID: 'x',
              value: 1689091200000
            },
            second: {
              type: 'line',
              borderColor: 'rgba(54, 162, 235, 1)',
              borderDash: [6, 6],
              borderWidth: 1,
              scaleID: 'x',
              value: 1689573600000
            },
            third: {
              type: 'line',
              borderColor: 'rgba(54, 162, 235, 1)',
              borderDash: [6, 6],
              borderWidth: 1,
              scaleID: 'x',
              value: 1690189200000
            }
          }
        },
        title: {
          display: true,
          text: 'Room Membership in the Python Community Space'
        },
      },
      scales: {
        x: {
          type: 'time',
          time: {
            unit: 'week',
            displayFormats: {
                week: 'YYYY-MM-DD'
            },
            tooltipFormat: 'YYYY-MM-DD'
          },
          title: {
            display: true,
            text: 'Date'
          }
        },
        y: {
          title: {
            display: true,
            text: 'Members'
          }
        }
      }
    }
}
{{</ chart >}}
Rendered
Rendered

Code

Below you find the implementation of the shortcode.

HTML

Defined in layouts/shortcodes/chart.html.

This code is licensed under the MIT license.
<!--

  Img Shortcode
  =============

  Contributors: Michael Sasser
  Maintainer: Michael Sasser
  License: MIT
  Version: 1
  Child Shortcodes: None
  Parent Shortcodes: None

  LAYOUT: /layouts/shortcodes/chart.html
  DOCS:   /content/<language>/wiki/Help:Shortcode_Chart.md
  LIB:    chart.js, chartjs-adapter-moment, chartjs-plugin-annotation
  SCRIPT: /assets/js/chart.js

  Description
  -----------

  Use the chart shortcode to create charts.

  Changelog
  =========

  Version 1
  ---------

  Initial release

-->

{{- $width := default "100" (.Get "width") -}}
{{- $height := default "400" (.Get "height") -}}

{{/*<!--  Do not render, when the feature is disabled  --> */}}
{{- if .Site.Params.options.chartJs -}}
  {{- $random_id := delimit (shuffle (split (md5 now.UnixNano) "" )) "" -}}

  <div style="width: {{ $width }}%;height: {{ $height }}px;margin: 0 auto">
      <canvas id="{{ $random_id }}"></canvas>
  </div>

  <script type = "text/javascript"
  nonce = "9y6EUgx7+FgXutsZio8npnxsBZ8hsEWsQuMzVJLGsPSpAmHjD5AQZm7i5Hl3KvPq3p+tK77wd9fWHIaof9a1cA=="
  >
  document.addEventListener("DOMContentLoaded", function () {
    // Your code that uses Chart can go here
    var ctx = document.getElementById('{{ $random_id }}')
      .getContext('2d');
    var options = {{ .Inner | chomp | safeJS }};
    var myChart = new Chart(ctx, options);

    // TODO: Accept wildcard, that only changes all elements inside the
    //       structure, when the last element exists
    function set(obj, path, value) {
        var schema = obj
        var pList = path.split('.');
        var len = pList.length;
        for(var i = 0; i < len-1; i++) {
            var elem = pList[i];
            if( !schema[elem] ) schema[elem] = {}
            schema = schema[elem];
        }
        schema[pList[len-1]] = value;
    }

    function defined_structure(obj, attrs) {
        var tmp = obj;
        for(i=0; i<attrs.length; ++i) {
            if(tmp[attrs[i]] == undefined)
                return false;
            tmp = tmp[attrs[i]];
        }
        return true;
    }

    // TODO: Use CSS boder color instead of the defined one here.
    //
    // Update grid line colors
    function updateChartGridLines(isDarkMode) {
      const gridColor = isDarkMode ? 'rgba(255, 255, 255, 0.2)' : 'rgba(0, 0, 0, 0.1)';
      const fontColor = isDarkMode ? 'rgba(255, 255, 255, 0.8)' : 'rgba(0, 0, 0, 0.1)';

      // options.scales.x
      if(defined_structure(myChart, ['options', 'scales', 'x'])) {
        set(myChart, 'options.scales.x.grid.color', gridColor);
        set(myChart, 'options.scales.x.ticks.color', fontColor);
        if(defined_structure(myChart, ['options', 'scales', 'x', 'title'])) {
          set(myChart, 'options.scales.x.title.color', fontColor);
        }
      }

      // TODO: Fix y axis color
      //
      // options.scales.y
      if(defined_structure(myChart, ['options', 'scales', 'y'])) {
        set(myChart, 'options.scales.y.grid.color', gridColor);
        set(myChart, 'options.scales.y.ticks.color', fontColor);
        if(defined_structure(myChart, ['options', 'scales', 'y', 'title'])) {
          set(myChart, 'options.scales.y.title.color', fontColor);
        }
      }

      // options.plugins.legend
      if(defined_structure(myChart, ['options', 'plugins', 'legend'])) {
        set(myChart, 'options.plugins.legend.labels.color', fontColor);
      }
      set(myChart, 'options.plugins.title.color', fontColor);

      set(Chart, "defaults.font.size", 14);

      myChart.update();
    }

    const htmlElement = document.querySelector('html');

    // Handle attribute changes
    const handleThemeAttributeChange = (mutationsList, observer) => {
      for (const mutation of mutationsList) {
        if (mutation.type === 'attributes' && mutation.attributeName === 'data-bs-theme') {
          const newTheme = htmlElement.getAttribute('data-bs-theme');
          updateChartGridLines(newTheme === 'dark');
        }
      }
    };

    // Create a new MutationObserver
    const observer = new MutationObserver(handleThemeAttributeChange);
    const observerOptions = {
      attributes: true, // Watch for attribute changes
    };
    observer.observe(htmlElement, observerOptions);


    // Check the initial color mode and apply it to the chart because the
    // options that would account for that are static.
    function applyInitialColorMode() {
      const htmlElement = document.querySelector('html');
      const themeAttribute = htmlElement.getAttribute('data-bs-theme');

      const isDarkMode = themeAttribute === 'dark';
      themeAttribute.checked = isDarkMode;
      updateChartGridLines(isDarkMode);
    }
    applyInitialColorMode();
  });
  </script>
{{- end -}}

Download

Copy the source code above or use the download link below to use this file on your website according to the license.

  • Ln Shortcode
    chart.html4.75 KB
  • md5   4ac149d7c59212767abd0947e8a290e7
  • sha1   ad4e1dcea4bf65a5b9b341471ebd5e9e2a91096c
  • sha256   d1aa00a9a6fdd082e08e05dcfaa878ab94f9506e30e28dc92361b1d40e43bbbe
Top