{"version":3,"sources":["jsdelivr-header.js","/npm/lchart@0.1.1/index.js"],"names":[],"mappings":"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","file":"/npm/lchart@0.1.1/index.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/lchart@0.1.1/index.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","\"use strict\";\n\nconst { createCanvas } = require(\"canvas\");\n\nclass Line {\n    /**\n     * @param {Object} data\n     * @param {String} data.name\n     * @param {Array<{x:Number, y:Number}>} data.points\n     * @param {{lineColor:String, pointFillColor:String}} [data.configs]\n     * @param {{lineColor:String, pointFillColor:String}} defaultConfigs\n     */\n    constructor(data, defaultConfigs) {\n        this.name = data.name;\n        this.points = data.points;\n        this.lineConfigs = data.configs || {};\n        this.lineColor = this.lineConfigs.lineColor || defaultConfigs.lineColor;\n        this.pointFillColor = this.lineConfigs.pointFillColor || defaultConfigs.pointFillColor;\n    }\n}\n\n/**\n * calculate chart layout & draw coordinates\n */\nclass Chart {\n    /**\n     * lchart v0.1   WARNING: Not compatible with versions below v0.1\n     * @param {Array<{name:String,points:Array<{x:Number, y:Number}>,configs:{lineColor:String, pointFillColor:String}}>} datas\n     * @param {Object} [picConfigs]\n     * @param {{left:Number, right:Number, up:Number, down:Number}} [picConfigs.padding]\n     * @param {{width:Number, height:Number}} [picConfigs.size] pic size\n     * @param {String} [picConfigs.font] exp. \"15px Georgia\"\n     * @param {{background:String ,title:String, titleX:String, titleY:String, coordinate:String, grid:String}} [picConfigs.color] \n     * @param {{title:String, titleX:String, titleY:String, divideX:Number, divideY:Number}} [picConfigs.label]\n     * @param {Boolean} [picConfigs.xDateMode] x-coordinate is date etc... divited evenly, point.x must be [1, 2, 3, ...] or [3, 5, 6, ...] etc...\n     * @param {Array<String>} [picConfigs.xDateLabel] when xDateMode = true, show xDateLabel at x-coordinate instead of x value, length must contains all data's point.x\n     *                                                for example:   line1 point.x [1, 2, 3, 4, 5]   line2 point.x [2, 4, 6, 7, 8]\n     *                                                xDateLabel should be like [\"day1\", \"day2\", \"day3\", \"day4\", \"day5\", \"day6\", \"day7\", \"day8\"] contains 1-8\n     *                                                the reason that I don't use Date() directly is x-coordinate can be other things like team numbers, seasons, years...\n     */\n    constructor(datas, picConfigs = {}) {\n        // lines count should be no more than 8\n        this.defaultLineColor = [\"#E74C3C\", \"#3498DB\", \"#9B59B6\", \"#2ECC71\", \"#F1C40F\", \"#34495E\", \"#95A5A6\", \"#1ABC9C\"];\n        this.defaultPointColor = [\"#C0392B\", \"#2980B9\", \"#8E44AD\", \"#27AE60\", \"#F39C12\", \"#2C3E50\", \"#7F8C8D\", \"#16A085\"];\n        if (datas.length <= 1) this.lines = [new Line(datas.pop(), { lineColor: \"#111\", pointFillColor: \"#000\" })];\n        else this.lines = datas.map((data, index) => {\n            const lineColor = this.defaultLineColor[index] || this.randomColor();\n            const pointFillColor = this.defaultPointColor[index] || lineColor;\n            return new Line(data, { lineColor, pointFillColor });\n        });\n        // padding\n        this.padding = {};\n        if (!picConfigs.padding) picConfigs.padding = {};\n        this.padding.left = picConfigs.padding.left || 50;\n        this.padding.right = picConfigs.padding.right || (this.lines.length > 1) ? 150 : 50;\n        this.padding.up = picConfigs.padding.up || 50;\n        this.padding.down = picConfigs.padding.down || 50;\n        // size\n        this.size = {};\n        if (!picConfigs.size) picConfigs.size = {};\n        this.size.width = picConfigs.size.width || 800;\n        this.size.height = picConfigs.size.height || 600;\n        // font\n        this.font = picConfigs.font || \"15px Georgia\";\n        // color\n        this.color = {};\n        if (!picConfigs.color) picConfigs.color = {};\n        this.color.background = picConfigs.color.background || \"white\";\n        this.color.title = picConfigs.color.title || \"#000\";\n        this.color.titleX = picConfigs.color.titleX || \"#000\";\n        this.color.titleY = picConfigs.color.titleY || \"#000\";\n        this.color.coordinate = picConfigs.color.coordinate || \"#000\";\n        this.color.grid = picConfigs.color.grid || \"#999\";\n        // labels\n        this.label = {};\n        if (!picConfigs.label) picConfigs.label = {};\n        this.label.title = picConfigs.label.title || \"\";\n        this.label.titleX = picConfigs.label.titleX || \"\";\n        this.label.titleY = picConfigs.label.titleY || \"\";\n        // how many segments are the coordinates divided into, it may be changed by getDatasRange()\n        this.label.divideX = picConfigs.label.divideX || 10;\n        this.label.divideY = picConfigs.label.divideY || 10;\n        // xDateMode\n        this.xDateMode = picConfigs.xDateMode || false;\n        this.xDateLabel = picConfigs.xDateLabel || null;\n        // draw zone\n        /*\n        -123-in-pic----------------------------------------------------------------\n        1         |                                                    |          |\n        2         |                      up padding                    |          |\n        3         |                        (title)                     |          |\n        |---------^---------------------------------------------------------------|\n        |         |                                                    |          |\n        |   left  |                                                    |   right  |\n        | (y-coor 3                       data zone                    |  padding |\n        | dinate) 2                                                    | (legend) |\n        |         1                                                    |          |\n        |---------+1-2-3-in-data--------------------------------------->----------|\n        |         |                                                    |          |\n        |         |                         down                       |          |\n        |         |                    (x-coordinate)                  |          |\n        ---------------------------------------------------------------------------\n        */\n        this.zone = {};\n        // data zone\n        this.zone.data = {};\n        this.zone.data.width = this.size.width - this.padding.left - this.padding.right;\n        this.zone.data.height = this.size.height - this.padding.up - this.padding.down;\n        this.zone.data.originX = this.padding.left;\n        this.zone.data.originY = this.size.height - this.padding.down;\n        // left zone\n        this.zone.left = {};\n        this.zone.left.width = this.padding.left;\n        this.zone.left.height = this.zone.data.height;\n        // down zone\n        this.zone.down = {};\n        this.zone.down.width = this.zone.data.width;\n        this.zone.down.height = this.padding.down;\n\n        // dataRange\n        this.dataRange = this.getCoordinatesRanges();\n        // Calculate how many pixels equal to 1 \n        this.dataInterval = this.getDataInterval();\n\n        // initCtx\n        this.canvas = createCanvas(this.size.width, this.size.height);\n        this.ctx = this.canvas.getContext('2d');\n    }\n\n    randomColor() {\n        var color = \"#\";\n        for (var i = 0; i < 6; i++) color += parseInt(Math.random() * 16).toString(16);\n        return color;\n    }\n\n    getSuitableRange(min, max, divideCount) {\n        const interval = (max - min) / divideCount;\n        const digit = Math.floor(Math.log10(interval)) + 1;\n        const fixedInterval = Math.pow(10, digit);\n        let fixedMin = (min >= 0) ? (min - (min % fixedInterval)) : (min - (min % fixedInterval) - fixedInterval);\n        let fixedMax = (max > 0) ? (max - (max % fixedInterval) + fixedInterval) : (max - (max % fixedInterval));\n        // Avoid accuracy problems\n        const mul = Math.pow(10, -digit);\n        if (fixedMin.toString().length > 10) fixedMin = Math.round((fixedMin + Number.EPSILON) * mul) / mul;\n        if (fixedMax.toString().length > 10) fixedMax = Math.round((fixedMax + Number.EPSILON) * mul) / mul;\n        const fixedDivideCount = Math.round((fixedMax - fixedMin) / fixedInterval);\n        return { min: fixedMin, max: fixedMax, divideCount: fixedDivideCount };\n    }\n\n    getDataRange(data) {\n        let xmin = data[0].x;\n        let xmax = data[0].x;\n        let ymin = data[0].y;\n        let ymax = data[0].y;\n        data.map((point) => {\n            if (point.x > xmax) xmax = point.x;\n            if (point.x < xmin) xmin = point.x;\n            if (point.y > ymax) ymax = point.y;\n            if (point.y < ymin) ymin = point.y;\n        });\n        return { xmin, xmax, ymin, ymax };\n\n    }\n\n    getCoordinatesRanges() {\n        const ranges = this.lines.map((line) => {\n            return this.getDataRange(line.points);\n        })\n        let xmin = ranges[0].xmin;\n        let xmax = ranges[0].xmax;\n        let ymin = ranges[0].ymin;\n        let ymax = ranges[0].ymax;\n        ranges.map((range) => {\n            if (range.xmax > xmax) xmax = range.xmax;\n            if (range.xmin < xmin) xmin = range.xmin;\n            if (range.ymax > ymax) ymax = range.ymax;\n            if (range.ymin < ymin) ymin = range.ymin;\n        });\n        const suitableX = (this.xDateMode) ? { min: xmin, max: xmax, divideCount: this.label.divideX } : this.getSuitableRange(xmin, xmax, this.label.divideX);\n        this.label.divideX = suitableX.divideCount;\n        const suitableY = this.getSuitableRange(ymin, ymax, this.label.divideY);\n        this.label.divideY = suitableY.divideCount;\n        return { xmin: suitableX.min, xmax: suitableX.max, ymin: suitableY.min, ymax: suitableY.max };\n    }\n\n    getDataInterval() {\n        const widthInterval = this.zone.data.width / (this.dataRange.xmax - this.dataRange.xmin);\n        const heightInterval = this.zone.data.height / (this.dataRange.ymax - this.dataRange.ymin);\n        return { widthInterval, heightInterval };\n    }\n\n    drawCoordinates() {\n        this.ctx.beginPath();\n        this.ctx.strokeStyle = this.color.coordinate;\n        this.ctx.lineWidth = 1;\n        this.ctx.moveTo(this.zone.data.originX, this.zone.data.originY);\n        this.ctx.lineTo(this.zone.data.originX, this.padding.up);\n        this.ctx.moveTo(this.zone.data.originX, this.zone.data.originY);\n        this.ctx.lineTo(this.zone.data.originX + this.zone.data.width, this.zone.data.originY);\n        this.ctx.stroke();\n    }\n\n    // accuary fix\n    accAdd(arg1, arg2) {\n        let r1, r2;\n        try { r1 = arg1.toString().split(\".\")[1].length } catch (e) { r1 = 0 }\n        try { r2 = arg2.toString().split(\".\")[1].length } catch (e) { r2 = 0 }\n        const m = Math.pow(10, Math.max(r1, r2));\n        return (arg1 * m + arg2 * m) / m;\n    }\n\n    accDiv(arg1, arg2) {\n        let t1 = 0, t2 = 0, r1, r2;\n        try { t1 = arg1.toString().split(\".\")[1].length } catch (e) { r1 = 0 }\n        try { t2 = arg2.toString().split(\".\")[1].length } catch (e) { r2 = 0 }\n        r1 = Number(arg1.toString().replace(\".\", \"\"))\n        r2 = Number(arg2.toString().replace(\".\", \"\"))\n        return (r1 / r2) * Math.pow(10, t2 - t1);\n    }\n\n    drawUp() {\n        // title\n        this.ctx.beginPath();\n        this.ctx.font = this.font;\n        this.ctx.fillStyle = this.color.title;\n        // min label at origin\n        this.ctx.textAlign = \"center\";\n        this.ctx.fillText(this.label.title, Math.floor(this.size.width / 2), Math.floor(this.padding.up / 2));\n        this.ctx.stroke();\n    }\n\n    drawRight() {\n        // legend\n        // ----------------\n        // | right padding|\n        // |        name O|\n        // | anothername O|\n        // |              |\n        // ----------------\n        const fontHeight = 20;\n        const circleX = this.size.width - 10;\n        let circleY = this.padding.up + fontHeight;\n        const colors = [];\n        const names = [];\n        this.lines.map((line) => {\n            colors.push(line.lineColor);\n            names.push(line.name);\n        })\n        this.ctx.textAlign = \"right\";\n        for (let i = 0; i < colors.length; i++) {\n            this.ctx.beginPath();\n            this.ctx.fillStyle = colors[i];\n            this.ctx.arc(circleX, circleY, 10, 0, 2 * Math.PI);\n            this.ctx.fill();\n            this.ctx.fillText(names[i], circleX - 20, circleY + 5);\n            circleY += fontHeight\n        }\n        this.ctx.stroke();\n    }\n\n    drawLeft() {\n        this.ctx.beginPath();\n        this.ctx.font = this.font;\n        this.ctx.strokeStyle = this.color.grid;\n        this.ctx.fillStyle = this.color.titleY;\n        // min label at origin\n        this.ctx.textAlign = \"center\";\n        const intervalY = this.accDiv(this.accAdd(this.dataRange.ymax, -this.dataRange.ymin), this.label.divideY);\n        const fontWidth = 5;\n        let nowY = this.dataRange.ymin;\n        for (let i = 0; i <= this.label.divideY; i++) {\n            const y = Math.ceil(this.size.height - this.dataInterval.heightInterval * i * intervalY - this.padding.down);\n            const text = nowY.toString();\n            this.ctx.moveTo(this.zone.data.originX, y);\n            this.ctx.lineTo(this.zone.data.originX + this.zone.data.width, y);\n            this.ctx.textAlign = \"right\";\n            this.ctx.fillText(text, this.zone.data.originX - fontWidth * text.length, y);\n            nowY = this.accAdd(nowY, intervalY);\n        }\n        this.ctx.stroke();\n        // titleY\n        this.ctx.beginPath();\n        this.ctx.font = this.font;\n        this.ctx.fillStyle = this.color.titleY;\n        this.ctx.fillText(this.label.titleY, this.zone.data.originX, this.padding.up - 20);\n        this.ctx.stroke();\n    }\n\n    drawBottom() {\n        if (this.xDateMode && this.xDateLabel) {\n            this.ctx.beginPath();\n            this.ctx.font = this.font;\n            this.ctx.strokeStyle = this.color.grid;\n            this.ctx.fillStyle = this.color.titleX;\n            // min label at origin\n            this.ctx.textAlign = \"center\";\n            const intervalX = this.accAdd(this.dataRange.xmax, -this.dataRange.xmin) / this.label.divideX;\n            const fontHeight = 20;\n            let nowX = this.dataRange.xmin;\n            for (let i = 0; i <= this.label.divideX; i++) {\n                const x = Math.ceil(this.padding.left + this.dataInterval.widthInterval * i * intervalX);\n                let labelIndex = (this.label.divideX <= 1) ? (this.xDateLabel.length - 1) * i : Math.floor(this.xDateLabel.length / this.label.divideX * i);\n                if (labelIndex >= this.xDateLabel.length) labelIndex = this.xDateLabel.length - 1;\n                const text = this.xDateLabel[labelIndex];\n                this.ctx.textAlign = \"center\";\n                this.ctx.fillText(text, x, this.zone.data.originY + fontHeight);\n                nowX = this.accAdd(nowX, intervalX);\n            }\n            this.ctx.stroke();\n            // titleX\n            this.ctx.beginPath();\n            this.ctx.font = this.font;\n            this.ctx.fillStyle = this.color.titleX;\n            this.ctx.fillText(this.label.titleX, this.zone.data.originX + this.zone.data.width + 5, this.zone.data.originY - 10);\n            this.ctx.stroke();\n        }\n        else {\n            this.ctx.beginPath();\n            this.ctx.font = this.font;\n            this.ctx.strokeStyle = this.color.grid;\n            this.ctx.fillStyle = this.color.titleX;\n            // min label at origin\n            this.ctx.textAlign = \"center\";\n            const intervalX = this.accAdd(this.dataRange.xmax, -this.dataRange.xmin) / this.label.divideX;\n            const fontHeight = 20;\n            let nowX = this.dataRange.xmin;\n            for (let i = 0; i <= this.label.divideX; i++) {\n                const x = Math.ceil(this.padding.left + this.dataInterval.widthInterval * i * intervalX);\n                const text = nowX.toString();\n                this.ctx.moveTo(x, this.zone.data.originY);\n                this.ctx.lineTo(x, this.padding.up);\n                this.ctx.textAlign = \"center\";\n                this.ctx.fillText(text, x, this.zone.data.originY + fontHeight);\n                nowX = this.accAdd(nowX, intervalX);\n            }\n            this.ctx.stroke();\n            // titleX\n            this.ctx.beginPath();\n            this.ctx.font = this.font;\n            this.ctx.fillStyle = this.color.titleX;\n            this.ctx.fillText(this.label.titleX, this.zone.data.originX + this.zone.data.width + 5, this.zone.data.originY - 10);\n            this.ctx.stroke();\n        }\n    }\n\n    setBackground() {\n        this.ctx.rect(0, 0, this.size.width, this.size.height);\n        this.ctx.fillStyle = this.color.background;\n        this.ctx.fill();\n    }\n\n    data2Point(points) {\n        // true point in pic\n        return points.map((point) => {\n            const x = Math.ceil(this.dataInterval.widthInterval * (point.x - this.dataRange.xmin) + this.padding.left);\n            const y = Math.ceil(this.size.height - this.dataInterval.heightInterval * (point.y - this.dataRange.ymin) - this.padding.down);\n            return { x, y };\n        });\n    }\n\n    /**\n     * @param {Line} line\n     */\n    drawLine(line) {\n        const drawPoints = this.data2Point(line.points);\n        this.ctx.beginPath();\n        this.ctx.moveTo(drawPoints[0].x, drawPoints[0].y);\n        drawPoints.map((point) => {\n            this.ctx.lineWidth = 2;\n            this.ctx.lineTo(point.x, point.y);\n            this.ctx.strokeStyle = line.lineColor;\n            this.ctx.stroke();\n            this.ctx.beginPath();\n            this.ctx.fillStyle = line.pointFillColor;\n            this.ctx.arc(point.x, point.y, 3, 0, 2 * Math.PI);\n            this.ctx.fill();\n            this.ctx.beginPath();\n            this.ctx.moveTo(point.x, point.y);\n        });\n        this.ctx.stroke();\n    }\n\n    drawLines() {\n        this.lines.map((line) => {\n            this.drawLine(line);\n        })\n    }\n\n    draw() {\n        this.setBackground();\n        this.drawUp();\n        this.drawCoordinates();\n        this.drawLeft();\n        if (this.lines.length > 1) this.drawRight();\n        this.drawBottom();\n        this.drawLines();\n        // data:image/png;base64,#picdata#\n        return this.canvas.toDataURL();\n        // return this;\n    }\n\n}\n\n\nmodule.exports = Chart;"]}