diff --git a/package-lock.json b/package-lock.json index 14b9d38..5567222 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "3.3.0", "license": "MIT", "devDependencies": { + "@rollup/plugin-terser": "^0.4.4", "ejs": "^2.5.5", "express": "^4.14.1", "jest": "^29.7.0", @@ -975,14 +976,14 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, "dependencies": { - "@jridgewell/set-array": "^1.0.1", + "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" @@ -998,14 +999,24 @@ } }, "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true, "engines": { "node": ">=6.0.0" } }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.15", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", @@ -1013,9 +1024,9 @@ "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.22", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz", - "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -1044,6 +1055,28 @@ "node": ">=18" } }, + "node_modules/@rollup/plugin-terser": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz", + "integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==", + "dev": true, + "dependencies": { + "serialize-javascript": "^6.0.1", + "smob": "^1.0.0", + "terser": "^5.17.4" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.12.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.12.0.tgz", @@ -1399,6 +1432,18 @@ "node": ">= 0.6" } }, + "node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/agent-base": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", @@ -5309,6 +5354,15 @@ "dev": true, "peer": true }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -5553,6 +5607,15 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, "node_modules/serve-static": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", @@ -5662,6 +5725,12 @@ "npm": ">= 3.0.0" } }, + "node_modules/smob": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/smob/-/smob-1.5.0.tgz", + "integrity": "sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==", + "dev": true + }, "node_modules/socks": { "version": "2.7.3", "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.3.tgz", @@ -5900,6 +5969,40 @@ "streamx": "^2.15.0" } }, + "node_modules/terser": { + "version": "5.30.3", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.30.3.tgz", + "integrity": "sha512-STdUgOUx8rLbMGO9IOwHLpCqolkDITFFQSMYYwKE1N2lY6MVSaeoi10z/EhWxRc6ybqoVmKSkhKYH/XUpl7vSA==", + "dev": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/terser/node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", diff --git a/package.json b/package.json index 49b2964..7d84464 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "jquery.peity.min.js" ], "devDependencies": { + "@rollup/plugin-terser": "^0.4.4", "ejs": "^2.5.5", "express": "^4.14.1", "jest": "^29.7.0", diff --git a/rollup.config.mjs b/rollup.config.mjs index 9a0e973..6bd126c 100644 --- a/rollup.config.mjs +++ b/rollup.config.mjs @@ -1,3 +1,5 @@ +import terser from '@rollup/plugin-terser' + import packageJSON from './package.json' assert { type: 'json' } const banner = `// Piety version ${packageJSON.version} @@ -5,6 +7,32 @@ const banner = `// Piety version ${packageJSON.version} // https://benpickles.github.io/piety` export default [ + { + input: 'src/jquery.js', + output: { + banner, + file: 'dist/jquery.piety.js', + format: 'es', + intro: '(function($, document, Math, undefined) {', + outro: '})(jQuery, document, Math)', + }, + }, + { + input: 'dist/jquery.piety.js', + output: { + banner, + file: 'dist/jquery.piety.min.js', + format: 'es', + }, + // context: "window", + plugins: [ + terser({ + format: { + // comments: 'all', + }, + }), + ], + }, { input: 'src/piety.js', output: { diff --git a/src/jquery.js b/src/jquery.js new file mode 100644 index 0000000..3db420c --- /dev/null +++ b/src/jquery.js @@ -0,0 +1,102 @@ +import * as bar from './charts/bar' +import * as line from './charts/line' +import * as pie from './charts/pie' +import { + normaliseData, + normaliseFill, + normalisePieData, + svgElement, +} from './utils' + +const piety = ($.fn.piety = function (type, options) { + return this.each(function () { + const $this = $(this) + let chart = $this.data('_peity') + + if (chart) { + if (type) chart.type = type + $.extend(chart.opts, options) + } else { + chart = new Piety($this, type, { + ...piety.defaults[type], + ...$this.data('piety'), + ...options, + }) + + $this.change(() => chart.render()).data('_peity', chart) + } + + chart.render() + }) +}) + +piety.defaults = {} +piety.graphers = {} + +piety.register = function (type, defaults, grapher) { + this.defaults[type] = defaults + this.graphers[type] = grapher +} + +class Piety { + constructor($el, type, opts) { + this.$el = $el + this.type = type + this.opts = opts + } + + svgElement = svgElement + + get data() { + return normaliseData(this.$el.text()) + } + + prepare(width, height) { + if (!this.$svg) { + const svg = svgElement('svg', { class: 'piety' }) + this.svg = svg + this.$svg = $(svg) + this.$el.hide().after(svg) + } + + return this.$svg.empty().data('_peity', this).attr({ + height: height, + width: width, + }) + } + + render() { + const opts = { + ...this.opts, + fill: normaliseFill(this.opts.fill), + } + const { helpers, parts } = piety.graphers[this.type](this, opts) + + this.prepare(opts.width, opts.height) + + parts.forEach(({ props, type }) => + this.$svg.append(svgElement(type, props)) + ) + + this.helpers = helpers + + if (opts.after) opts.after(this, helpers) + } +} + +piety.register('bar', bar.defaults, (obj, opts) => bar.renderer(obj.data, opts)) + +piety.register('donut', { ...pie.defaults }, (obj, opts) => { + if (!opts.innerRadius) opts.innerRadius = opts.radius / 2 + return piety.graphers.pie(obj, opts) +}) + +piety.register('line', line.defaults, (obj, opts) => + line.renderer(obj.data, opts) +) + +piety.register('pie', pie.defaults, (obj, opts) => { + if (!opts.width) opts.width = opts.radius * 2 + if (!opts.height) opts.height = opts.radius * 2 + return pie.renderer(normalisePieData(obj.$el.text()), opts) +}) diff --git a/test/__snapshots__/jquery.peity.test.js.snap b/test/__snapshots__/jquery.piety.test.js.snap similarity index 92% rename from test/__snapshots__/jquery.peity.test.js.snap rename to test/__snapshots__/jquery.piety.test.js.snap index 120fa18..c8d3fcb 100644 --- a/test/__snapshots__/jquery.peity.test.js.snap +++ b/test/__snapshots__/jquery.piety.test.js.snap @@ -8,7 +8,7 @@ exports[`renders test chart bar1 correctly 1`] = ` 5,0,9,6,5,9,7,3,5,2 @@ -104,7 +104,7 @@ exports[`renders test chart bar2 correctly 1`] = ` 0,3,2,-1,-3,-2,2,3,5,2 @@ -200,7 +200,7 @@ exports[`renders test chart bar3 correctly 1`] = ` -3,0,-6,-4,-5,-4,-7,-3,-5,-2 @@ -296,7 +296,7 @@ exports[`renders test chart bar4 correctly 1`] = ` 5,3,9,6,5,9,7,3,5,2 @@ -392,7 +392,7 @@ exports[`renders test chart bar5 correctly 1`] = ` 5,3,2,-1,-3,-2,2,3,5,2 @@ -488,7 +488,7 @@ exports[`renders test chart bar6 correctly 1`] = ` 0,-3,-6,-4,-5,-4,-7,-3,-5,-2 @@ -584,7 +584,7 @@ exports[`renders test chart bar7 correctly 1`] = ` 0,0,0,0,0 @@ -640,7 +640,7 @@ exports[`renders test chart bar8 correctly 1`] = ` 1,1,1,1,1 @@ -696,7 +696,7 @@ exports[`renders test chart bar9 correctly 1`] = ` 1,1,1,1,1 @@ -752,7 +752,7 @@ exports[`renders test chart bar10 correctly 1`] = ` -10,-15,-13,-14,-11 @@ -808,7 +808,7 @@ exports[`renders test chart bar11 correctly 1`] = ` -10,-15,-13,-14,-11 @@ -864,7 +864,7 @@ exports[`renders test chart bar12 correctly 1`] = ` 1000,1005,1003,1004,1001 @@ -913,6 +913,62 @@ exports[`renders test chart bar12 correctly 1`] = ` `; exports[`renders test chart bar13 correctly 1`] = ` + + + 1000,1005,1003,1004,1001 + + + + + + + + + +`; + +exports[`renders test chart bar14 correctly 1`] = ` @@ -1008,7 +1064,7 @@ exports[`renders test chart bar13 correctly 1`] = ` `; -exports[`renders test chart bar14 correctly 1`] = ` +exports[`renders test chart bar15 correctly 1`] = ` @@ -1119,7 +1175,7 @@ exports[`renders test chart donut1 correctly 1`] = ` 1/5 @@ -1145,7 +1201,7 @@ exports[`renders test chart donut2 correctly 1`] = ` 0.52/1.561 @@ -1171,7 +1227,7 @@ exports[`renders test chart donut3 correctly 1`] = ` 1,4 @@ -1197,7 +1253,7 @@ exports[`renders test chart donut4 correctly 1`] = ` 4,7,6,5 @@ -1233,7 +1289,7 @@ exports[`renders test chart donut5 correctly 1`] = ` 3/3 @@ -1254,7 +1310,7 @@ exports[`renders test chart donut6 correctly 1`] = ` 0/3 @@ -1275,7 +1331,7 @@ exports[`renders test chart donut7 correctly 1`] = ` 3,0 @@ -1296,7 +1352,7 @@ exports[`renders test chart donut8 correctly 1`] = ` 4/3 @@ -1317,7 +1373,7 @@ exports[`renders test chart donut9 correctly 1`] = ` 1/5 @@ -1343,7 +1399,7 @@ exports[`renders test chart donut10 correctly 1`] = ` 1,-2,3 @@ -1369,13 +1425,13 @@ exports[`renders test chart donut11 correctly 1`] = ` -2/3 @@ -1390,13 +1446,13 @@ exports[`renders test chart donut12 correctly 1`] = ` 0,0,0,0,0 @@ -1411,7 +1467,7 @@ exports[`renders test chart donut13 correctly 1`] = ` 2,4,5 @@ -1450,7 +1506,7 @@ exports[`renders test chart line1 correctly 1`] = ` 5,3,9,6,5,9,7,3,5,2 @@ -1477,7 +1533,7 @@ exports[`renders test chart line2 correctly 1`] = ` 5,3,2,-1,-3,-2,2,3,5,2 @@ -1504,7 +1560,7 @@ exports[`renders test chart line3 correctly 1`] = ` 0,-3,-6,-4,-5,-4,-7,-3,-5,-2 @@ -1531,7 +1587,7 @@ exports[`renders test chart line4 correctly 1`] = ` 5,3,9,6,5,9,7,3,5,2 @@ -1558,7 +1614,7 @@ exports[`renders test chart line5 correctly 1`] = ` 0,0,0,0,0 @@ -1585,7 +1641,7 @@ exports[`renders test chart line6 correctly 1`] = ` 1,1,1,1,1 @@ -1612,7 +1668,7 @@ exports[`renders test chart line7 correctly 1`] = ` -10,-15,-13,-14,-11 @@ -1639,7 +1695,7 @@ exports[`renders test chart line8 correctly 1`] = ` -10,-15,-13,-14,-11 @@ -1666,7 +1722,7 @@ exports[`renders test chart line9 correctly 1`] = ` 1000,1005,1003,1004,1001 @@ -1686,6 +1742,33 @@ exports[`renders test chart line9 correctly 1`] = ` `; exports[`renders test chart line10 correctly 1`] = ` + + + 1000,1005,1003,1004,1001 + + + + + + +`; + +exports[`renders test chart line11 correctly 1`] = ` @@ -1712,7 +1795,7 @@ exports[`renders test chart line10 correctly 1`] = ` `; -exports[`renders test chart line11 correctly 1`] = ` +exports[`renders test chart line12 correctly 1`] = ` @@ -1735,7 +1818,7 @@ exports[`renders test chart line11 correctly 1`] = ` `; -exports[`renders test chart line12 correctly 1`] = ` +exports[`renders test chart line13 correctly 1`] = ` @@ -1777,7 +1860,7 @@ exports[`renders test chart pie1 correctly 1`] = ` 1/5 @@ -1803,7 +1886,7 @@ exports[`renders test chart pie2 correctly 1`] = ` 0.52/1.561 @@ -1829,7 +1912,7 @@ exports[`renders test chart pie3 correctly 1`] = ` 1,4 @@ -1855,7 +1938,7 @@ exports[`renders test chart pie4 correctly 1`] = ` 4,7,6,5 @@ -1891,7 +1974,7 @@ exports[`renders test chart pie5 correctly 1`] = ` 3/3 @@ -1914,7 +1997,7 @@ exports[`renders test chart pie6 correctly 1`] = ` 0/3 @@ -1937,7 +2020,7 @@ exports[`renders test chart pie7 correctly 1`] = ` 3,0 @@ -1960,7 +2043,7 @@ exports[`renders test chart pie8 correctly 1`] = ` 4/3 @@ -1983,7 +2066,7 @@ exports[`renders test chart pie9 correctly 1`] = ` 1,-2,3 @@ -2009,14 +2092,14 @@ exports[`renders test chart pie10 correctly 1`] = ` -2/3 @@ -2029,17 +2112,17 @@ exports[`renders test chart pie11 correctly 1`] = ` - 0,0,0,0,0 + 0/0 @@ -2048,6 +2131,29 @@ exports[`renders test chart pie11 correctly 1`] = ` `; exports[`renders test chart pie12 correctly 1`] = ` + + + 0,0,0,0 + + + + + +`; + +exports[`renders test chart pie13 correctly 1`] = ` diff --git a/test/app.js b/test/app.js index 59cd8db..40be4be 100644 --- a/test/app.js +++ b/test/app.js @@ -7,7 +7,7 @@ const sendfile = (filename, root) => (_, res) => res.sendFile(filename, { root }) const jquery = sendfile('/jquery-1.6.2.min.js', __dirname) -const pietyJquery = sendfile('/jquery.peity.js', __dirname + '/..') +const pietyJquery = sendfile('/jquery.piety.js', __dirname + '/../dist') const pietyWc = sendfile('/piety.js', __dirname + '/../dist') const style = sendfile('/style.css', __dirname) @@ -45,7 +45,7 @@ const app = express() .set('view engine', 'ejs') .set('views', __dirname + '/views') .get('/jquery.min.js', jquery) - .get('/jquery.peity.js', pietyJquery) + .get('/jquery.piety.js', pietyJquery) .get('/piety.js', pietyWc) .get('/style.css', style) .get('/', index) diff --git a/test/jquery.peity.test.js b/test/jquery.piety.test.js similarity index 100% rename from test/jquery.peity.test.js rename to test/jquery.piety.test.js diff --git a/test/views/chart.ejs b/test/views/chart.ejs index 63af3b8..cb95ff0 100644 --- a/test/views/chart.ejs +++ b/test/views/chart.ejs @@ -3,5 +3,5 @@ diff --git a/test/views/index.ejs b/test/views/index.ejs index 9eb6731..6c16721 100644 --- a/test/views/index.ejs +++ b/test/views/index.ejs @@ -4,11 +4,10 @@ Charts + + - - -
<% charts.forEach(function(chart) { %> <% include chart %> diff --git a/test/views/show.ejs b/test/views/show.ejs index 92e57ce..a9c93eb 100644 --- a/test/views/show.ejs +++ b/test/views/show.ejs @@ -4,11 +4,10 @@ <%= chart.id %> + + - - - <% include chart %>