make dev environment modern
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
build/*
|
||||
demo/*
|
||||
/**/*.d.ts
|
||||
@@ -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
@@ -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
@@ -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
@@ -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));
|
||||
@@ -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
@@ -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 }
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -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"],
|
||||
}
|
||||
@@ -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']
|
||||
}
|
||||
};
|
||||
@@ -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,
|
||||
}),
|
||||
],
|
||||
};
|
||||
};
|
||||
@@ -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(),
|
||||
],
|
||||
};
|
||||
Reference in New Issue
Block a user