Schema Definition
Schema definition for the Chart node type:
{
chart: {
group: 'block',
attrs: {
type: { default: 'bar' },
data: { default: '{}' }
},
}
}Model Representation
Example model representation:
{
type: 'chart',
attrs: {
type: 'bar',
data: JSON.stringify({ labels: ['A', 'B'], values: [1, 2] })
}
}HTML Serialization
Converting model to HTML:
function serializeChart(node) {
return '<div data-type="chart" data-chart-type="' + node.attrs.type + '">' +
escapeHtml(node.attrs.data) + '</div>';
}HTML Deserialization
Parsing HTML to model:
function parseChart(domNode) {
return {
type: 'chart',
attrs: {
type: domNode.getAttribute('data-chart-type') || 'bar',
data: domNode.textContent || '{}'
}
};
}View Integration
View Integration Notes: Pay special attention to contenteditable behavior, selection handling, and event management when implementing this node type in your view layer.
View integration code:
// Rendering chart
const chart = document.createElement('div');
chart.setAttribute('data-type', 'chart');
chart.setAttribute('data-chart-type', node.attrs.type);
chart.contentEditable = 'false'; // Charts are typically rendered
// Render with Chart.js or other chart library
function renderChart(element) {
const type = element.getAttribute('data-chart-type');
const data = JSON.parse(element.textContent || '{}');
if (window.Chart) {
new Chart(element, {
type: type,
data: data
});
}
}Common Issues
Common Pitfalls: These are issues frequently encountered when implementing this node type. Review carefully before implementation.
Common issues and solutions:
// Issue: Chart data validation
// Solution: Validate chart data structure
function validateChartData(data, type) {
try {
const parsed = JSON.parse(data);
// Validate based on chart type
return parsed.labels && parsed.values;
} catch {
return false;
}
}
// Issue: Chart resizing
// Solution: Handle responsive charts
function makeChartResponsive(chart) {
chart.style.width = '100%';
chart.style.height = 'auto';
}Implementation
Complete implementation example:
class ChartNode {
constructor(attrs) {
this.type = 'chart';
this.attrs = {
type: attrs?.type || 'bar',
data: attrs?.data || '{}'
};
}
toDOM() {
const chart = document.createElement('div');
chart.setAttribute('data-type', 'chart');
chart.setAttribute('data-chart-type', this.attrs.type);
chart.textContent = this.attrs.data;
return chart;
}
static fromDOM(domNode) {
return new ChartNode({
type: domNode.getAttribute('data-chart-type') || 'bar',
data: domNode.textContent || '{}'
});
}
}