
# Gujido RealMap Linking

This is an example of linking RealGrid2 and [RealMap](https://www.realmap.co.kr/).
Clicking on an area of ​​the old map selects the grid row, and conversely, clicking on a row of the grid selects the area.
You can rotate the map by dragging the mouse.
The gray area is an area without data, and you can apply styles to empty areas in bulk with nullStyle.

```js
const config = {
  title: false,
  map: [{ url: '/data/en/maps/world-low.geo.json' }],
  axis: { grid: true },
  annotations: [
    {
      front: true,
      type: 'shape',
      shape: 'rectangle',
      offsetX: 20,
      offsetY: 20,
      width: 10,
      height: 28,
      style: { fill: '#83A8DC' },
    },
    {
      front: true,
      type: 'text',
      text: 'Globe Map Rotation',
      offsetX: 40,
      offsetY: 20,
      height: 28,
      style: { fontwhenze: '15pt', fontWeight: 700 },
    },
  ],
  body: {
    projection: 'orthographic',
    zoomable: true,
    mapBackground: {},
  },
  series: [
    {
      dataUrl: '/data/en/world-economic2.json',
      useMapData: false,
      allAreas: true,
      idField: 'countryCode',
      mapKeys: ['iso-a3', 'countryCode'],
      tooltipText: '<t style="font-size: 18px; font-weight: 700;"> ${countryName}</t><br/>GDP Growth: <t style="font-weight: 700;">${gdpGrowth}</t>',
      nullStyle: { fill: '#adb5bd' },
      style: { stroke: '#fff', fill: '#B4CBEF', strokeWidth: 0.7 },
      hoverColor: '#83A8DC',
      pointLabel: false,
      onPointClick: (args) => {
        var point = chart.seriesByType('map').pointByProp('rm-id', args.source.countryCode);
        if (window.prevPoint2) {
          window.prevPoint2.setSelected(false);
        }
        chart.body.updateOptions({
          rotationX: -args.area.getCenter()[0],
          rotationY: -args.area.getCenter()[1],
        });
        point.setSelected(true);
        chart.render();
        window.prevPoint2 = point;
        const searchResult = gridView.searchCell({
          value: args.source.countryCode,
          fields: dataProvider.getOrgFieldNames(),
        });
      },
    },
  ],
};

const fields = [
  { fieldName: 'countryCode', dataType: 'text' },
  { fieldName: 'countryName', dataType: 'text' },
  { fieldName: 'gdp', dataType: 'number' },
  { fieldName: 'gdpGrowth', dataType: 'number' },
  { fieldName: 'gdpPerCapita', dataType: 'number' },
  { fieldName: 'currentAccount', dataType: 'number' },
  { fieldName: 'inflation', dataType: 'number' },
  { fieldName: 'unemployment', dataType: 'number' },
  { fieldName: 'industrialProduction', dataType: 'number' },
  { fieldName: 'exports', dataType: 'number' },
  { fieldName: 'imports', dataType: 'number' },
];

const columns = [
  { name: 'countryCode', fieldName: 'countryCode', header: { text: 'Country Code' }, width: 70 },
  { name: 'countryName', fieldName: 'countryName', header: { text: 'Country Name' }, width: 130 },
  { name: 'gdp', fieldName: 'gdp', header: { text: 'GDP' }, width: 130 },
  { name: 'gdpGrowth', fieldName: 'gdpGrowth', header: { text: 'GDP Growth' }, width: 70 },
  { name: 'gdpPerCapita', fieldName: 'gdpPerCapita', header: { text: 'GDP per Capita' }, width: 70 },
  { name: 'currentAccount', fieldName: 'currentAccount', header: { text: 'Current Account Balance' }, width: 70 },
  { name: 'inflation', fieldName: 'inflation', header: { text: 'Inflation Rate' }, width: 70 },
  { name: 'unemployment', fieldName: 'unemployment', header: { text: 'Unemployment Rate' }, width: 70 },
  { name: 'industrialProduction', fieldName: 'industrialProduction', header: { text: 'Industrial Production' }, width: 70 },
  { name: 'exports', fieldName: 'exports', header: { text: 'Export' }, width: 70 },
  { name: 'imports', fieldName: 'imports', header: { text: 'Import' }, width: 70 },
];

var dataProvider, gridView, chart;

async function createGrid(container) {
  chart = await RealMap.createChartAsync(document, 'realmap', config, true);

  dataProvider = new RealGrid.LocalDataProvider();
  gridView = new RealGrid.GridView(container);
  gridView.setDataSource(dataProvider);
  dataProvider.setFields(fields);
  gridView.setColumns(columns);

  gridView.displayOptions.emptyMessage = 'No data to display.';
  gridView.header.height = 40;
  gridView.displayOptions.rowHeight = 36;
  gridView.footer.height = 40;
  gridView.stateBar.width = 16;
  gridView.editOptions.insertable = true;
  gridView.editOptions.appendable = true;
  gridView.displayOptions.fitStyle = 'fill';
  gridView.displayOptions.selectionStyle = 'singleRow';

  fetch('/data/en/world-economic2.json')
    .then(response => response.json())
    .then(data => {
      dataProvider.setRows(data);
      gridView.refresh();
    });

  let prevSelection = null;
  gridView.onCurrentRowChanged = function (grid, oldRow, newRow) {
    var value = dataProvider.getValue(newRow, 'countryCode');
    var point = chart.seriesByType('map').pointByProp('rm-id', value);
    if (point) {
      if (prevSelection) {
        prevSelection.setSelected(false);
      }
      var mapSeries = chart.seriesByType('map');
      var mapSeriesPoint = mapSeries.pointById(value);
      chart.body.rotationX = -mapSeriesPoint.area.getCenter()[0];
      chart.body.rotationY = -mapSeriesPoint.area.getCenter()[1];
      point.setSelected(true);
      prevSelection = point;
    }
  };

  gridView.setEditOptions({
    editable: false,
    commitByCell: true,
  });

  dataProvider.onRowUpdated = (provider, row) => {
    const code = provider.getValue(row, 'countryCode');
    const gdpGrowth = provider.getValue(row, 'gdpGrowth');
    const mapSeries = chart.seriesByType('map');
    const point = mapSeries.pointByProp('iso-a3', code);
    point.updateValues(mapSeries, { value: gdpGrowth });
    chart.render();
  };
}

createGrid('realgrid');
```

```js
const config = { 
title: false, 
map: [{ 
url: 'maps/world-low.geo.json' 
}], 
axis: { 
grid: true 
}, 
annotations: [{ 
front: true, 
type: 'shape', 
shape: 'rectangle', 
offsetX: 20; 
offsetY: 20; 
width: 10, 
height: 28, 
style: { 
fill: '#83A8DC' 
} 
}, 
{ 
front: true, 
type: 'text', 
text: 'Rotate spherical map', 
offsetX: 40; 
offsetY: 20; 
height: 28, 
style: { 
fontSize: '15pt', 
fontWeight: 700 
} 
} 
], 
body: { 
projection: 'orthographic', 
zoomable: true; 
mapBackground: {} 
}, 
series: [{ 
dataUrl: "/data/world-economic2.json", 
useMapData: false; 
allAreas:true; 
idField: "countryCode", 
mapKeys:["iso-a3", "countryCode"], 
tooltipText: '<t style="font-size: 18px; font-weight: 700;"> ${countryName}</t><br/>GDP Growth: <t style="font-weight: 700;">${gdpGrowth}</t>', 
nullStyle:{ 
fill: '#adb5bd' 
}, 
style: { 
stroke: '#fff', 
fill: '#B4CBEF', 
strokeWidth: 0.7 
}, 
hoverColor: '#83A8DC', 
pointLabel: false; 
onPointClick: (args) => { 
var point = chart.seriesByType('map').pointByProp('rm-id', args.source.countryCode); 
if (window.prevPoint2) { 
window.prevPoint2.setSelected(false); 
} 
chart.body.updateOptions({ 
rotationX: -args.area.getCenter()[0]; 
rotationY: -args.area.getCenter()[1] 
}) 

point.setSelected(true); 
chart.render(); 
window.prevPoint2 = point; 

const searchResult = gridView.searchCell({ 
value: args.source.countryCode, 
fields: dataProvider.getOrgFieldNames() 
}); 
} 
}]
};

var dataProvider, gridContainer, gridView, chart; 

async function createGrid(container) { 
chart = await RealMap.createChartAsync(document, 'realmap', config, true); 
...
```