"
πŸš€ DataGridXL3 Out Now! See what's newβ†’

DataGridXL β€” Demos

DataGridXL & Charts

DataGridXL is the ideal component to make your charts, maps & infographics interactive. That's why famous SaaS software Piktochart (10 million users) chooses DataGridXL as their data grid.

DataGridXL works with any JavaScript chart component. Our favorite is amCharts.

Listen to DataGridXL setcellvaluesbatch event, then use amCharts data.setIndex method to trigger an animation.

Try changing any value inside the Value column. Setting a cell to a non-numeric value will change its state to invalid.

Code

// Set data
const data = [{
  country: "USA",
  value: 2025
}, {
  country: "China",
  value: 1882
}, {
  country: "Japan",
  value: 1809
}, {
  country: "Germany",
  value: 1322
}, {
  country: "UK",
  value: 1122
}, {
  country: "France",
  value: 1114
}, {
  country: "India",
  value: 984
}, {
  country: "Spain",
  value: 711
}, {
  country: "Netherlands",
  value: 665
}, {
  country: "South Korea",
  value: 443
}, {
  country: "Canada",
  value: 441
}];

let series;

am5.ready(function() {

  // Create root element
  // https://www.amcharts.com/docs/v5/getting-started/#Root_element
  const root = am5.Root.new("chart");
  
  // Set themes
  // https://www.amcharts.com/docs/v5/concepts/themes/
  root.setThemes([
    am5themes_Animated.new(root)
  ]);
  
  // Create chart
  // https://www.amcharts.com/docs/v5/charts/xy-chart/
  const chart = root.container.children.push(am5xy.XYChart.new(root, {
    panX: true,
    panY: true,
    wheelX: "panX",
    wheelY: "zoomX",
    pinchZoomX: true,
    paddingLeft:0,
    paddingRight:1
  }));
  
  // Add cursor
  // https://www.amcharts.com/docs/v5/charts/xy-chart/cursor/
  const cursor = chart.set("cursor", am5xy.XYCursor.new(root, {}));
  cursor.lineY.set("visible", false);
  
  // Create axes
  // https://www.amcharts.com/docs/v5/charts/xy-chart/axes/
  const xRenderer = am5xy.AxisRendererX.new(root, { 
    minGridDistance: 30, 
    minorGridEnabled: true
  });
  
  xRenderer.labels.template.setAll({
    rotation: -90,
    centerY: am5.p50,
    centerX: am5.p100,
    paddingRight: 15
  });
  
  xRenderer.grid.template.setAll({
    location: 1
  })
  
  const xAxis = chart.xAxes.push(am5xy.CategoryAxis.new(root, {
    maxDeviation: 0.3,
    categoryField: "country",
    renderer: xRenderer,
    tooltip: am5.Tooltip.new(root, {})
  }));
  
  const yRenderer = am5xy.AxisRendererY.new(root, {
    strokeOpacity: 0.1
  })
  
  const yAxis = chart.yAxes.push(am5xy.ValueAxis.new(root, {
    maxDeviation: 0.3,
    renderer: yRenderer
  }));
  
  // Create series
  // https://www.amcharts.com/docs/v5/charts/xy-chart/series/
  series = chart.series.push(am5xy.ColumnSeries.new(root, {
    name: "Series 1",
    xAxis: xAxis,
    yAxis: yAxis,
    valueYField: "value",
    sequencedInterpolation: true,
    categoryXField: "country",
    tooltip: am5.Tooltip.new(root, {
      labelText: "{valueY}"
    })
  }));
  
  series.columns.template.setAll({ cornerRadiusTL: 5, cornerRadiusTR: 5, strokeOpacity: 0 });
  series.columns.template.adapters.add("fill", function (fill, target) {
    return chart.get("colors").getIndex(series.columns.indexOf(target));
  });
  
  series.columns.template.adapters.add("stroke", function (stroke, target) {
    return chart.get("colors").getIndex(series.columns.indexOf(target));
  });
  
  xAxis.data.setAll(data);
  series.data.setAll(data);
  
  // Make stuff animate on load
  // https://www.amcharts.com/docs/v5/concepts/animations/
  series.appear(1000);
  chart.appear(1000, 100);
  
});

// create grid
const grid = new DataGridXL("grid", {
  licenseKey: "your_license_key",
  data,
  columns: [{
    source: "country",
    title: "Country",
    readOnly: true
  }, {
    source: "value",
    title: "Value",
    validateFunction(cell){
      return !isNaN(cell.value);
    }
  }],
  allowMoveRows: false,
  allowInsertRows: false,
  allowDeleteRows: false,
  allowHideRows: false,
  allowInsertCols: false,
  allowDeleteCols: false,
  allowMoveCols: false,
  allowHideCols: false,
  allowSort: false,
  bottomBar: []
});

grid.events.on('$setcellvaluesbatch', (event) => {

  event.rowIds.forEach((rowId,index) => {

    // skip if NaN
    if(isNaN(event.values[index][0])) return;

    series.data.setIndex(rowId-1, {
      country: data[rowId-1].country,
      value: Number(event.values[index][0])
    });

  });

});