Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 73 additions & 9 deletions modules/noodl-chartjs/module/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion modules/noodl-chartjs/module/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@
"license": "ISC",
"dependencies": {
"@noodl/noodl-sdk": "github:noodlapp/noodl-sdk#feature/typescript",
"chart.js": "^3.7.1"
"chart.js": "^4.4.3",
"chartjs-adapter-dayjs-4": "^1.0.4",
"chartjs-plugin-annotation": "^3.0.1",
"dayjs": "^1.11.11"
},
"devDependencies": {
"@babel/core": "^7.2.2",
Expand Down
2 changes: 2 additions & 0 deletions modules/noodl-chartjs/module/src/helpers/defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,8 @@ export const chart_changed = {
...generateInputsChanged(interactionOptions),

customPlugins(value) {
this.inputs.customPlugins = value;

if (!this.chart) return;

if (typeof value === 'object') {
Expand Down
56 changes: 38 additions & 18 deletions modules/noodl-chartjs/module/src/helpers/define.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as Noodl from "@noodl/noodl-sdk";
import { useCallback, useEffect, useRef } from "react";
import { Chart, ChartConfiguration, ChartTypeRegistry } from "chart.js";
import * as ChartHelpers from 'chart.js/helpers';
import * as ChartHelpers from "chart.js/helpers";
import { generateInputs, generateInputsChanged, Input } from "./boilerplate";
import { chart_changed, chart_inputs, chart_options } from "./defaults";

Expand All @@ -19,7 +19,7 @@ function Canvas(props: any): JSX.Element {
const ref = useCallback((node: HTMLCanvasElement) => {
props.onCanvasChanged(node);
}, []);

const sizerRef = useRef(null);
const fixedSizeRef = useRef(null);

Expand Down Expand Up @@ -63,7 +63,7 @@ export function defineChartReactNode(args: ChartNodeOptions) {

// Expose the Helper so we can get the Click data etc
this.setOutputs({ helpers: ChartHelpers });

this.props.onCanvasChanged = (node: HTMLCanvasElement) => {
if (this.chart) {
this.chart.destroy();
Expand Down Expand Up @@ -139,12 +139,15 @@ export function defineChartReactNode(args: ChartNodeOptions) {
data(value) {
if (!this.chart) return;
this.chart.data = value;
const animate = typeof this.inputs.animateOnDataUpdate === 'undefined' ? true : this.inputs.animateOnDataUpdate;
const animate =
typeof this.inputs.animateOnDataUpdate === "undefined"
? true
: this.inputs.animateOnDataUpdate;
// With initialDataSet, it will animate the first time.
if (animate || !this.initialDataSet) {
this.chart.update();
} else {
this.chart.update('none');
this.chart.update("none");
}
this.initialDataSet = true;
},
Expand Down Expand Up @@ -187,7 +190,7 @@ export function defineChartReactNode(args: ChartNodeOptions) {
});
},
initChart(canvas: HTMLCanvasElement) {
const options = {
const options: any = {
onClick: (e) => {
this.setOutputs({ clickEventData: e });
this.sendSignalOnOutput("onClick");
Expand All @@ -201,10 +204,7 @@ export function defineChartReactNode(args: ChartNodeOptions) {
this.setOptions(options, element);
}

// @ts-expect-error
options.animations = this.inputs.animations;

// @ts-expect-error
options.scales = this.inputs.scales;

// @ts-expect-error
Expand All @@ -215,20 +215,24 @@ export function defineChartReactNode(args: ChartNodeOptions) {
});

const haveConnection = (portName: string) => {
return this.model.component.connections.findIndex((x) =>
x.sourceId === this.id && x.sourcePort === portName ||
x.targetId === this.id && x.targetPort === portName
) !== -1;
}
return (
this.model.component.connections.findIndex(
(x) =>
(x.sourceId === this.id && x.sourcePort === portName) ||
(x.targetId === this.id && x.targetPort === portName)
) !== -1
);
};

const chartConfig: ChartConfiguration<any, any, any> = {
type: args.type,
options,
// Only use default data if there is no connection
data: this.inputs.data || haveConnection('data') ? {} : args.defaultData,
data:
this.inputs.data || haveConnection("data") ? {} : args.defaultData,
plugins: [
{
id: 'noodlEventCatcher',
id: "noodlEventCatcher",
beforeEvent: (chart, args, pluginOptions) => {
try {
this.setOutputs({
Expand All @@ -240,14 +244,30 @@ export function defineChartReactNode(args: ChartNodeOptions) {
/* noop */
}
},
}
]
},
],
};

this.chart = new Chart(canvas, chartConfig);
if (this.inputs.data) {
this.chart.data = this.inputs.data;
}

// Add the plugins
// NOTE: Adding for example the annotations plugins before,
// makes the chart not responsive.
// Adding it like this solves that issue.
if (this.inputs.customPlugins) {
if (!options.plugins) {
options.plugins = {};
}

Object.entries(this.inputs.customPlugins).forEach(([key, value]) => {
this.chart.options.plugins[key] = value;
});
}

this.chart.update();
},
},
});
Expand Down
9 changes: 8 additions & 1 deletion modules/noodl-chartjs/module/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import * as Noodl from "@noodl/noodl-sdk";
import { Chart, registerables } from "chart.js";
import annotationPlugin from 'chartjs-plugin-annotation';

// Install date adapter https://github.com/bolstycjw/chartjs-adapter-dayjs-4
import 'chartjs-adapter-dayjs-4/dist/chartjs-adapter-dayjs-4.esm';

import { barNode } from "./reactNodes/bar";
import { bubbleNode } from "./reactNodes/bubble";
Expand All @@ -11,7 +15,10 @@ import { radarNode } from "./reactNodes/radar";
import { scatterNode } from "./reactNodes/scatter";
import { chartNode } from "./reactNodes/chart";

Chart.register(...registerables);
Chart.register(
...registerables,
annotationPlugin
);

// module
Noodl.defineModule({
Expand Down
63 changes: 37 additions & 26 deletions modules/noodl-chartjs/module/webpack.config.js
Original file line number Diff line number Diff line change
@@ -1,43 +1,54 @@
const path = require('path');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const path = require("path");
const CopyWebpackPlugin = require("copy-webpack-plugin");

const pjson = require('./package.json');
// var outputPath = path.resolve(__dirname, '../noodl_modules/' + pjson.name);
// var outputPath = `/Users/eric/Library/Application Support/Noodl/projects/af203093-14cd-428a-8900-10282137e92c/noodl_modules/` + pjson.name;
var outputPath = `C:\\Users\\Eric\\AppData\\Roaming\\Noodl\\projects\\155e4849-bfae-4c1d-9102-58c8e4bd92c3\\noodl_modules\\` + pjson.name;
const pjson = require("./package.json");
const outputPath = path.resolve(
__dirname,
"../project/noodl_modules/" + pjson.name
);

// TODO: This will be replaced when the SDK is updated.
const noodlSdkPath = path.resolve(__dirname, '..', '..', 'noodl-sdk', "build/dist/index.js");
const noodlSdkPath = path.resolve(
__dirname,
"..",
"..",
"noodl-sdk",
"build/dist/index.js"
);

module.exports = {
entry: './src/index.ts',
mode: 'production',
devtool: 'source-map',
entry: "./src/index.ts",
mode: "production",
devtool: "source-map",
output: {
filename: 'index.js',
filename: "index.js",
path: outputPath,
clean: true,
},
externals: {
'react': 'React',
'react-dom': 'reactDom',
react: "React",
"react-dom": "reactDom",
},
resolve: {
extensions: [".ts", ".tsx", ".js", ".json", ".css"]
extensions: [".ts", ".tsx", ".js", ".json", ".css"],
},
plugins: [
new CopyWebpackPlugin({
patterns: [{
from: 'assets/**/*',
to: '[name][ext]'
}, ]
})
patterns: [
{
from: "assets/**/*",
to: "[name][ext]",
},
],
}),
],
module: {
rules: [{
test: /\.(ts|tsx)$/,
use: 'ts-loader',
exclude: /node_modules/,
}, ]
}
};
rules: [
{
test: /\.(ts|tsx)$/,
use: "ts-loader",
exclude: /node_modules/,
},
],
},
};
Loading