make dev environment modern

This commit is contained in:
Yuichiro Take
2021-08-23 11:15:20 +09:00
parent 3716f5b776
commit c2ab3b0132
12 changed files with 4998 additions and 344 deletions
+3
View File
@@ -0,0 +1,3 @@
build/*
demo/*
/**/*.d.ts
+31
View File
@@ -0,0 +1,31 @@
{
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module",
"ecmaFeatures": {
"modules": true,
"experimentalObjectRestSpread": true
}
},
"plugins": ["@typescript-eslint"],
"extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
"rules": {
"comma-dangle": 0,
"no-unused-vars": "warn",
"no-unexpected-multiline": "warn",
"prefer-const": "warn",
"@typescript-eslint/no-empty-function": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-var-requires": "off"
},
"settings": {},
"env": {
"browser": true,
"node": true,
"jasmine": true,
"jest": true,
"es6": true
}
}
+33
View File
@@ -0,0 +1,33 @@
# dependencies
/node_modules
# testing
/tests
/coverage
# docs
/docs
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
/.github
/demo
.esdoc.json
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Development folders and files
public
src
config
.travis.yml
README.md
.eslintignore
.eslintrc.json
webpack.config.js
+19 -3
View File
@@ -5,7 +5,10 @@
"main": "src/index.js",
"scripts": {
"deploy": "cp -R test/* demo && cp src/index.js demo/plugin.js && sed -i '' -f replace_condition demo/index.html && gh-pages -d demo",
"test": "echo \"Error: no test specified\" && exit 1"
"start": "webpack serve --mode development --config ./webpack/demo.config.js",
"build:demo": "webpack --mode production --config ./webpack/demo.config.js",
"build:plugin": "webpack --mode production --config ./webpack/plugin.config.js && tsc",
"test": "jest --silent"
},
"repository": {
"type": "git",
@@ -21,9 +24,22 @@
},
"homepage": "https://github.com/y-takey/chartjs-plugin-stacked100#readme",
"dependencies": {
"chart.js": "^2.4.0"
"chart.js": "^3.0.0"
},
"devDependencies": {
"gh-pages": "^1.0.0"
"@typescript-eslint/eslint-plugin": "^4.29.2",
"@typescript-eslint/parser": "^4.29.2",
"eslint": "^7.32.0",
"gh-pages": "^1.0.0",
"html-webpack-plugin": "^5.3.2",
"jest": "^27.0.6",
"prettier": "^2.3.2",
"prettier-webpack-plugin": "^1.2.0",
"terser-webpack-plugin": "^5.1.4",
"ts-loader": "^9.2.5",
"typescript": "^4.3.5",
"webpack": "^5.51.1",
"webpack-cli": "^4.8.0",
"webpack-dev-server": "^4.0.0"
}
}
-153
View File
@@ -1,153 +0,0 @@
(function(Chart) {
var isObject = function(obj) {
var type = typeof obj;
return type === 'object' && !!obj;
}
var dataValue = function(dataPoint, isHorizontal) {
if (isObject(dataPoint)) {
return isHorizontal ? dataPoint.x : dataPoint.y;
}
return dataPoint;
}
var cloneArray = function(srcAry) {
var dstAry = [];
var length = srcAry.length;
for (var i = 0; i < length; i++) {
dstAry.push(srcAry[i]);
}
return dstAry;
};
var setOriginalData = function(data) {
data.originalData = data.datasets.map(function(dataset) {
return cloneArray(dataset.data);
});
};
// set calculated rate (xx%) to data.calculatedData
var calculateRate = function(data, isHorizontal, precision) {
var visibles = data.datasets.map(function(dataset) {
if (!dataset._meta) return true;
for (var i in dataset._meta) {
return !dataset._meta[i].hidden;
}
});
var datasetDataLength = 0;
if (data && data.datasets && data.datasets[0] && data.datasets[0].data) {
datasetDataLength = data.datasets[0].data.length;
}
var totals = Array.apply(null, new Array(datasetDataLength)).map(function(el, i) {
return data.datasets.reduce(function(sum, dataset, j) {
var key = dataset.stack;
if (!sum[key]) sum[key] = 0;
sum[key] += Math.abs(dataValue(dataset.data[i], isHorizontal)) * visibles[j];
return sum;
}, {});
});
data.calculatedData = data.datasets.map(function(dataset, i) {
return dataset.data.map(function(val, i) {
var total = totals[i][dataset.stack];
var dv = dataValue(val, isHorizontal);
return dv && total ? round(dv / total, precision) : 0;
});
});
};
var getPrecision = function(pluginOptions) {
// return the (validated) configured precision from pluginOptions or default 1
var defaultPrecision = 1;
if (!pluginOptions.hasOwnProperty("precision")) return defaultPrecision;
if (!pluginOptions.precision) return defaultPrecision;
var optionsPrecision = Math.floor(pluginOptions.precision);
if (isNaN(optionsPrecision)) return defaultPrecision;
if (optionsPrecision < 0 || optionsPrecision > 16) return defaultPrecision;
return optionsPrecision;
};
var round = function(value, precision) {
var multiplicator = Math.pow(10, precision);
return Math.round(value * 100 * multiplicator) / multiplicator;
};
var tooltipLabel = function(isHorizontal) {
return function(tooltipItem, data) {
var datasetIndex = tooltipItem.datasetIndex;
var index = tooltipItem.index;
var datasetLabel = data.datasets[datasetIndex].label || "";
var originalValue = data.originalData[datasetIndex][index];
var rateValue = data.calculatedData[datasetIndex][index];
return "" + datasetLabel + ": " + rateValue + "% (" + dataValue(originalValue, isHorizontal) + ")";
}
};
var reflectData = function(srcData, datasets) {
if (!srcData) return;
srcData.forEach(function(data, i) {
datasets[i].data = data;
});
};
var isHorizontalChart = function(chartInstance) {
return chartInstance.config.type === "horizontalBar";
}
var Stacked100Plugin = {
id: "stacked100",
beforeInit: function(chartInstance, pluginOptions) {
if (!pluginOptions.enable) return;
var xAxes = chartInstance.options.scales.xAxes;
var yAxes = chartInstance.options.scales.yAxes;
var isVertical = chartInstance.config.type === "bar" || chartInstance.config.type === "line";
[xAxes, yAxes].forEach(function(axes) {
axes.forEach(function(hash) {
hash.stacked = true;
});
});
(isVertical ? yAxes : xAxes).forEach(function(hash) {
if (!hash.ticks.min) {
var hasNegative = chartInstance.data.datasets.some(function(dataset) {
return dataset.data.some(function(value) {
return value < 0;
});
});
hash.ticks.min = hasNegative ? -100 : 0;
}
if (!hash.ticks.max) hash.ticks.max = 100;
});
// Replace tooltips
if (pluginOptions.hasOwnProperty("replaceTooltipLabel") && !pluginOptions.replaceTooltipLabel) return;
chartInstance.options.tooltips.callbacks.label = tooltipLabel(isHorizontalChart(chartInstance));
},
beforeDatasetsUpdate: function(chartInstance, pluginOptions) {
if (!pluginOptions.enable) return;
setOriginalData(chartInstance.data);
var precision = getPrecision(pluginOptions);
calculateRate(chartInstance.data, isHorizontalChart(chartInstance), precision);
reflectData(chartInstance.data.calculatedData, chartInstance.data.datasets);
},
afterDatasetsUpdate: function(chartInstance, pluginOptions) {
if (!pluginOptions.enable) return;
reflectData(chartInstance.data.originalData, chartInstance.data.datasets);
}
};
Chart.pluginService.register(Stacked100Plugin);
}.call(this, Chart));
-47
View File
@@ -1,47 +0,0 @@
<html>
<head>
<meta charset="UTF-8">
<style type="text/css">
.my-chart-container {
max-width: 600px;
max-height: 400px;
}
</style>
</head>
<body>
<h3>Case.1 basic pattern</h1>
<div class="my-chart-container">
<canvas id="my-chart-1" width="600" height="200"></canvas>
</div>
<h3>Case.2 stack group pattern</h1>
<div class="my-chart-container">
<canvas id="my-chart-2" width="600" height="300"></canvas>
</div>
<h3>Case.3 stacked vertical bar</h1>
<div class="my-chart-container">
<canvas id="my-chart-3" width="600" height="300"></canvas>
</div>
<h3>Case.4 stacked area</h1>
<div class="my-chart-container">
<canvas id="my-chart-4" width="600" height="300"></canvas>
</div>
<h3>Case.5 stacked area with objects as data points</h1>
<div class="my-chart-container">
<canvas id="my-chart-5" width="600" height="300"></canvas>
</div>
<h3>Case.6 horizontal bar chart with objects as data points</h1>
<div class="my-chart-container">
<canvas id="my-chart-6" width="600" height="200"></canvas>
</div>
<script type="text/javascript" src="https://npmcdn.com/chart.js@<3.0.0/dist/Chart.bundle.min.js"></script>
<script type="text/javascript" src="../src/index.js"></script>
<script type="text/javascript" src="./index.js"></script>
</body>
</html>
-120
View File
@@ -1,120 +0,0 @@
const chart = new Chart(document.getElementById("my-chart-1"), {
type: "horizontalBar",
data: {
labels: ["Foo", "Bar"],
datasets: [
{ label: "bad", data: [5, 25], backgroundColor: "rgba(244, 143, 177, 0.6)" },
{ label: "better", data: [15, 10], backgroundColor: "rgba(255, 235, 59, 0.6)" },
{ label: "good", data: [10, 8], backgroundColor: "rgba(100, 181, 246, 0.6)" }
]
},
options: {
plugins: {
stacked100: { enable: true }
}
}
});
// setTimeout(() => {
// chart.data.labels.push("hoge");
// chart.data.datasets.forEach((dataset, i) => {
// dataset.data.push(10 + i * 3);
// });
// chart.update();
// }, 3000);
new Chart(document.getElementById("my-chart-2"), {
type: "horizontalBar",
data: {
labels: ["Foo", "Bar"],
datasets: [
{ label: "L1", stack: "Stack 0", data: [3, 2], backgroundColor: "rgba(244, 143, 177, 0.6)" },
{ label: "L2", stack: "Stack 0", data: [1, 1], backgroundColor: "rgba(255, 235, 59, 0.6)" },
{ label: "L1", stack: "Stack 1", data: [0, 3], backgroundColor: "rgba(100, 181, 246, 0.6)" },
{ label: "L2", stack: "Stack 1", data: [1, 4], backgroundColor: "rgba(51, 255, 74, 0.4)" }
]
},
options: {
plugins: {
stacked100: { enable: true }
}
}
});
new Chart(document.getElementById("my-chart-3"), {
type: "bar",
data: {
labels: ["Hoge", "Fuga"],
datasets: [
{ label: "L1", data: [10, 9], backgroundColor: "rgba(244, 143, 177, 0.6)" },
{ label: "L2", data: [20, 6], backgroundColor: "rgba(255, 235, 59, 0.6)" },
{ label: "L3", data: [30, 3], backgroundColor: "rgba(100, 181, 246, 0.6)" }
]
},
options: {
plugins: {
stacked100: { enable: true }
}
}
});
new Chart(document.getElementById("my-chart-4"), {
type: "line",
data: {
labels: ["2017-10-18", "2017-10-19", "2017-10-20"],
datasets: [
{ label: "L1", fill: true, data: [1, 2, 0], backgroundColor: "rgba(244, 143, 177, 0.6)" },
{ label: "L2", fill: true, data: [1, 1, 3], backgroundColor: "rgba(255, 235, 59, 0.6)" },
{ label: "L3", fill: true, data: [1, 1, 2], backgroundColor: "rgba(100, 181, 246, 0.6)" },
{ label: "L4", fill: true, data: [1, 3, 1], backgroundColor: "rgba(51, 255, 74, 0.4)" }
]
},
options: {
scales: {
xAxes: [{ stacked: true }],
yAxes: [{ stacked: true }]
},
plugins: {
stacked100: { enable: true }
}
}
});
new Chart(document.getElementById("my-chart-5"), {
type: "line",
data: {
labels: ["2017-10-18", "2017-10-19", "2017-10-20"],
datasets: [
{ label: "L1", fill: true, data: [{ y: 1 }, { y: 2 }, { y: 0 }], backgroundColor: "rgba(244, 143, 177, 0.6)" },
{ label: "L2", fill: true, data: [{ y: 1 }, { y: 1 }, { y: 3 }], backgroundColor: "rgba(255, 235, 59, 0.6)" },
{ label: "L3", fill: true, data: [{ y: 1 }, { y: 1 }, { y: 2 }], backgroundColor: "rgba(100, 181, 246, 0.6)" },
{ label: "L4", fill: true, data: [{ y: 1 }, { y: 3 }, { y: 1 }], backgroundColor: "rgba(51, 255, 74, 0.4)" }
]
},
options: {
scales: {
xAxes: [{ stacked: true }],
yAxes: [{ stacked: true }]
},
plugins: {
stacked100: { enable: true }
}
}
});
new Chart(document.getElementById("my-chart-6"), {
type: "horizontalBar",
data: {
labels: ["Foo", "Bar"],
datasets: [
{ label: "bad", data: [{ x: 5 }, { x: 25 }], backgroundColor: "rgba(244, 143, 177, 0.6)" },
{ label: "better", data: [{ x: 15 }, { x: 10 }], backgroundColor: "rgba(255, 235, 59, 0.6)" },
{ label: "good", data: [{ x: 10 }, { x: 8 }], backgroundColor: "rgba(100, 181, 246, 0.6)" }
]
},
options: {
plugins: {
stacked100: { enable: true }
}
}
});
+17
View File
@@ -0,0 +1,17 @@
{
"compilerOptions": {
"noImplicitAny": true,
"outDir": "build/types",
"module": "esnext",
"target": "es5",
"allowJs": true,
"sourceMap": true,
"declaration": true,
"emitDeclarationOnly": true,
"suppressImplicitAnyIndexErrors": true,
"lib": ["es2018", "dom"],
"moduleResolution": "node",
},
"include": ["src"],
// "exclude": ["src/**/tests"],
}
+22
View File
@@ -0,0 +1,22 @@
module.exports = {
module: {
rules: [
{
test: /\.(js|ts)$/,
exclude: /node_modules/,
use: [
{
loader: "ts-loader",
options: {
transpileOnly: true,
silent: true,
},
},
],
},
]
},
resolve: {
extensions: ['.ts', '.js', '.json']
}
};
+32
View File
@@ -0,0 +1,32 @@
const path = require("path");
const HtmlWebpackPlugin = require('html-webpack-plugin');
const commonConfig = require("./common.config");
module.exports = (env, args) => {
const isProduction = args && args.mode === "production";
return {
...commonConfig,
devtool: isProduction && "source-map",
entry: "./src/demo/index.ts",
output: {
path: path.resolve("./demo"),
filename: "index.js"
},
optimization: {
minimize: isProduction,
},
devServer: {
open: true,
hot: true,
},
plugins: [
new HtmlWebpackPlugin({
template: "./src/demo/index.html",
publicPath: "./",
hash: true,
}),
],
};
};
+28
View File
@@ -0,0 +1,28 @@
const path = require('path');
const PrettierPlugin = require("prettier-webpack-plugin");
const TerserPlugin = require('terser-webpack-plugin');
const commonConfig = require("./common.config");
module.exports = {
...commonConfig,
mode: "production",
devtool: false,
entry: './src/plugin/index.ts',
output: {
filename: 'index.js',
path: path.resolve('./build'),
library: "chartjs-plugin-stacked100",
libraryTarget: 'umd',
clean: true
},
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({ extractComments: false }),
],
},
plugins: [
new PrettierPlugin(),
],
};
+4813 -21
View File
File diff suppressed because it is too large Load Diff