Chart Node Type

Category: Custom • Detailed implementation guide with view integration notes

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 || '{}'
    });
  }
}