I'm attempting to integrate ZingChart as a custom component type in GrapesJs. I've followed some examples and have implemented the following plugin.
blocks.js
import { lineChartRef, chartType } from './consts';
export default (editor, opt = {}) => {
const c = opt;
const bm = editor.BlockManager;
if (c.blocks.indexOf(lineChartRef) >= 0) {
bm.add(lineChartRef, {
label: c.labelLineChart,
content: `
<div data-gjs-type="${chartType}" id="myChart"></div>
`
});
}
};
components.js
import { chartType } from './consts';
export default (editor, opt = {}) => {
const domc = editor.DomComponents;
const defaultType = domc.getType('default');
const defaultModel = defaultType.model;
domc.addType(chartType, {
model: defaultModel.extend(
{
defaults: {
...defaultModel.prototype.defaults,
script: function() {
if (typeof zingchart == 'undefined') {
var script = document.createElement('script');
script.src =
'https://cdn.zingchart.com/zingchart.min.js';
document.body.appendChild(script);
}
}
}
},
{
isComponent: el => {
if (
el.getAttribute &&
el.getAttribute('data-gjs-type') === chartType
) {
return {
type: chartType
};
}
}
}
),
view: {
onRender() {
renderZingChart.bind(this)();
}
}
});
function renderZingChart() {
const data = {
type: 'bar',
title: {
text: 'Data Basics',
fontSize: 24
},
legend: {
draggable: true
},
scaleX: {
// Set scale label
label: { text: 'Days' },
// Convert text on scale indices
labels: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
scaleY: {
label: { text: 'Temperature (°F)' }
},
plot: {
animation: {
effect: 'ANIMATION_EXPAND_BOTTOM',
method: 'ANIMATION_STRONG_EASE_OUT',
sequence: 'ANIMATION_BY_NODE',
speed: 275
}
},
series: [
{
// plot 1 values, linear data
values: [23, 20, 27, 29, 25, 17, 15],
text: 'Week 1'
},
{
// plot 2 values, linear data
values: [35, 42, 33, 49, 35, 47, 35],
text: 'Week 2'
},
{
// plot 2 values, linear data
values: [15, 22, 13, 33, 44, 27, 31],
text: 'Week 3'
}
]
};
const chart = {
id: 'myChart',
data
};
zingchart.render(chart);
}
};
index.js
import grapesjs from 'grapesjs';
import loadBlocks from './blocks';
import loadComponents from './components';
import { lineChartRef } from './consts';
export default grapesjs.plugins.add('fndy-charts', (editor, opts = {}) => {
let c = opts;
let defaults = {
blocks: [lineChartRef],
defaultStyle: 1,
labelLineChart: 'Line Chart'
};
// Load defaults
for (let name in defaults) {
if (!(name in c)) c[name] = defaults[name];
}
loadBlocks(editor, c);
loadComponents(editor, c);
});
consts.js
export const lineChartRef = 'line-chart';
export const chartType = 'chart';
When I add the block to the canvas, it renders, but the ZingChart inside does not. Some things I've tried already:
- Verify that the ZingChart render function is being called.
- Try moving the renderZingChart function call to different component hooks. Specifically, component:mount, view.init(), and view.onRender().
- Move the renderZingChart function call to the script function as a script.onload callback. A similar example can be found here: https://grapesjs.com/docs/modules/Components-js.html#basic-scripts. This does render the ZingChart correctly but doesn't feel correct, and does not allow me to pass in parameters since the script function runs outside the scope of GrapesJs.
I'm running out of ideas so any guidance would be great! Thanks!