Source

client/ux/chart/chart.js

/**
 * 
 * The chart derives from [Component](kiss.ui.Component.html).
 * 
 * Encapsulates original Chart.js bar chart inside a KissJS UI component:
 * https://www.chartjs.org/
 * 
 * @param {object} config
 * @param {string} config.chartType - Chart type (bar, line, pie, doughnut, radar, polarArea, bubble, scatter)
 * @param {object} config.data - Chart data
 * @param {object} config.options - Chart options
 * @param {integer} [config.width] - Width in pixels
 * @param {integer} [config.height] - Height in pixels
 * @param {boolean} [config.useCDN] - Set to false to use the local version of OpenLayers. Default is true.
 * @returns this
 * 
 * ## Generated markup
 * ```
 * <a-chart class="a-chart">
 * </a-chart>
 * ```
 */
kiss.ux.Chart = class uxChart extends kiss.ui.Component {
    /**
     * Its a Custom Web Component. Do not use the constructor directly with the **new** keyword.
     * Instead, use one of the 3 following methods:
     * 
     * Create the Web Component and call its **init** method:
     * ```
     * const myChart = document.createElement("a-chart").init(config)
     * ```
     * 
     * Or use the shorthand for it:
     * ```
     * const myChart = createChart({
     *  chartType: "bar",
     *  data: {...},
     *  options: {...},
     *  width: 300,
     *  height: 200
     * })
     * 
     * myChart.render()
     * ```
     * 
     * Or directly declare the config inside a container component:
     * ```
     * const myPanel = createPanel({
     *   title: "My panel",
     *   items: [
     *       {
     *          type: "chart",
     *          chartType: "bar",
     *          data: {...},
     *          options: {...},
     *          width: 300,
     *          height: 200
     *       }
     *   ]
     * })
     * myPanel.render()
     * ```
     */
    constructor() {
        super()
    }

    /**
     * Generates a chart from a JSON config
     * 
     * @ignore
     * @param {object} config - JSON config
     * @returns {HTMLElement}
     */
    init(config = {}) {

        // Set default values
        config.width = config.width || 300
        config.height = config.height || 225
        this.useCDN = (config.useCDN === false) ? false : true

        super.init(config)

        this.innerHTML = `<canvas id="chart-${this.id}"></canvas>`
        this.chartContainer = this.querySelector("canvas")

        // Set the style
        this.style.display = "flex"
        this.chartContainer.style.flex = 1

        this._setProperties(config, [
            [
                ["flex", "position", "top", "left", "width", "height", "margin", "padding", "background", "backgroundColor", "borderColor", "borderRadius", "borderStyle", "borderWidth", "boxShadow"],
                [this.style]
            ]
        ])

        return this
    }

    /**
     * Check if the Chart.js library is loaded, and initialize the chart
     * 
     * @ignore
     */
    async _afterRender() {
        if (window.Chart) {
            this.initChart(this.config)
        } else {
            await this.initChartJS(this.config)
            this.initChart()
        }
    }

    /**
     * Load the OpenLayers library
     * 
     * @ignore
     */
    async initChartJS() {
        if (this.useCDN === false) {
            // Local
            await kiss.loader.loadScript("../../kissjs/client/ux/chart/chartjs")
        } else {
            // CDN
            await kiss.loader.loadScript("https://cdn.jsdelivr.net/npm/chart")
        }
    }

    /**
     * Initialize the chart
     * 
     * @ignore
     */
    initChart() {
        this.chart = new Chart(this.chartContainer, {
            type: this.config.chartType,
            data: this.config.data,
            options: this.config.options
        })
    }

    /**
     * Set the width of the map
     * 
     * @param {number} width 
     * @returns this
     */
    setWidth(width) {
        this.style.width = width
        return this
    }

    /**
     * Set the height of the map
     * 
     * @param {number} height 
     * @returns this
     */
    setHeight(height) {
        this.style.height = height
        return this
    }
}

// Create a Custom Element and add a shortcut to create it
customElements.define("a-chart", kiss.ux.Chart)
const createBarChart = (config) => document.createElement("a-chart").init(config)

;