Poor amcharts5 map performance when many series added

75 Views Asked by At

I have more than 20 groups and in all group there are few countries (in example below, there are mostly one country per group but it is justan example). The problem is tester regrets that scrolling and moving map is a little bit clumsy and laggy. I do not have much experience in amcharts so I could do something in not efficient way. Is the anyhing I can do to improve my map?

Here is jsfiddle with some example:

/**
 * ---------------------------------------
 * This demo was created using amCharts 5.
 * 
 * For more information visit:
 * https://www.amcharts.com/
 * 
 * Documentation is available at:
 * https://www.amcharts.com/docs/v5/
 * ---------------------------------------
 */
 
// Data
var groupData = [
  {
    "name": "G1",
    "data": [
      { "id": "AT", "joined": "1995"},
      { "id": "IE", "joined": "1973"},
   ]
  }, {
    "name": "G2",
    "data": [
      { "id": "LT", "joined": "2004" },
      { "id": "LV", "joined": "2004" },
      { "id": "CZ", "joined": "2004" },
      { "id": "SK", "joined": "2004" },
      { "id": "SI", "joined": "2004" },
      { "id": "EE", "joined": "2004" },
      { "id": "HU", "joined": "2004" },
      { "id": "CY", "joined": "2004" },
      { "id": "MT", "joined": "2004" },
      { "id": "PL", "joined": "2004" }
    ]
  }, {
    "name": "G3",
    "data": [
      { "id": "RO", "joined": "2007" },
      { "id": "BG", "joined": "2007" }
    ]
  }, {
    "name": "G4",
    "data": [
      { "id": "HR", "joined": "2013" }
    ]
  }, {
    "name": "G5",
    "data": [
      { "id": "DK", "joined": "1973"},
    ]
  }, {
    "name": "G6",
    "data": [
      { "id": "FI", "joined": "1995"},
    ]
  }, {
    "name": "G7",
    "data": [
      { "id": "SE", "joined": "1995"},
    ]
  }, {
    "name": "G8",
    "data": [
      { "id": "GB", "joined": "1973"},
    ]
  }, {
    "name": "G9",
    "data": [
      { "id": "IT", "joined": "1957"},
    ]
  }, {
    "name": "G10",
    "data": [
     { "id": "FR", "joined": "1957"},
    ]
  }, {
    "name": "G11",
    "data": [
      { "id": "ES", "joined": "1986"},
    ]
  }, {
    "name": "G12",
    "data": [
      { "id": "GR", "joined": "1981"},
    ]
  }, {
    "name": "G13",
    "data": [
      { "id": "DE", "joined": "1957"},
    ]
  }, {
    "name": "G14",
    "data": [
      { "id": "BE", "joined": "1957"},
    ]
  }, {
    "name": "G15",
    "data": [
      { "id": "LU", "joined": "1957"},
    ]
  }, {
    "name": "G16",
    "data": [
      { "id": "NL", "joined": "1957"},
    ]
  }, {
    "name": "G17",
    "data": [
      { "id": "PT", "joined": "1986"}
    ]
  }, {
    "name": "G18",
    "data": [
      { "id": "CZ", "joined": "2004" },
    ]
  }, {
    "name": "G19",
    "data": [
      { "id": "SK", "joined": "2004" },
    ]
  }, {
    "name": "G20",
    "data": [
      { "id": "SI", "joined": "2004" },
    ]
  }, {
    "name": "G21",
    "data": [
     { "id": "HU", "joined": "2004" },
    ]
  }, {
    "name": "G22",
    "data": [
     { "id": "CY", "joined": "2004" },
    ]
  }, {
    "name": "G23",
    "data": [
      { "id": "US", "joined": "2004" },
    ]
  }, {
    "name": "G24",
    "data": [
       { "id": "PL", "joined": "2004" }
    ]
  }, {
    "name": "G25",
    "data": [
      { "id": "CA", "joined": "2004" },
    ]
  }, {
    "name": "G26",
    "data": [
      { "id": "CN", "joined": "2004" },
    ]
  }, {
    "name": "G27",
    "data": [
      { "id": "AU", "joined": "2004" },
    ]
  }, {
    "name": "G28",
    "data": [
      { "id": "BR", "joined": "2004" },
    ]
  }
];
 
 
// Create root and chart
var root = am5.Root.new("chartdiv");
 
 
// Set themes
root.setThemes([
  am5themes_Animated.new(root)
]);
 
 
// Create chart
var chart = root.container.children.push(am5map.MapChart.new(root, {
  homeZoomLevel: 0.7,
}));
 
 
// Create world polygon series
var worldSeries = chart.series.push(am5map.MapPolygonSeries.new(root, {
  geoJSON: am5geodata_worldLow,
  exclude: ["AQ"]
}));
 
worldSeries.mapPolygons.template.setAll({
  fill: am5.color(0xaaaaaa)
});

 
worldSeries.events.on("datavalidated", () => {
  chart.goHome();
});
 
 
// Add legend
var legend = chart.children.push(am5.Legend.new(root, {
  useDefaultMarker: true,
  centerX: am5.p50,
  x: am5.p50,
  centerY: am5.p100,
  y: am5.p100,
  dy: -20,
  background: am5.RoundedRectangle.new(root, {
    fill: am5.color(0xffffff),
    fillOpacity: 0.2
  })
}));
 
legend.valueLabels.template.set("forceHidden", true)
 
 
// Create series for each group
var colors = am5.ColorSet.new(root, {
  step: 2
});
colors.next();
 
am5.array.each(groupData, function(group) {
  var countries = [];
  var color = colors.next();
 
  am5.array.each(group.data, function(country) {
    countries.push(country.id)
  });
  
   var polygonSeries = chart.series.push(am5map.MapPolygonSeries.new(root, {
    geoJSON: am5geodata_worldLow,
    include: countries,
    name: group.name,
    fill: color,
  }));
 
  polygonSeries.mapPolygons.template.setAll({
    tooltipText: "[bold]{name}[/]\nMember since {joined}",
    interactive: true,
    fill: color,
    strokeWidth: 2
  });
 
  polygonSeries.mapPolygons.template.states.create("hover", {
    fill: am5.Color.brighten(color, -0.3)
  });
 
  polygonSeries.mapPolygons.template.events.on("pointerover", function(ev) {
    ev.target.series.mapPolygons.each(function(polygon) {
      polygon.states.applyAnimate("hover");
    });
  });
 
  polygonSeries.mapPolygons.template.events.on("pointerout", function(ev) {
    ev.target.series.mapPolygons.each(function(polygon) {
      polygon.states.applyAnimate("default");
    });
  });
  
  
  polygonSeries.data.setAll(group.data);
 
  legend.data.push(polygonSeries);
});
body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
}
 
#chartdiv {
  width: 100%;
  height: 500px;
}
<script src="https://cdn.amcharts.com/lib/5/index.js"></script>
<script src="https://cdn.amcharts.com/lib/5/map.js"></script>
<script src="https://cdn.amcharts.com/lib/5/geodata/worldLow.js"></script>
<script src="https://cdn.amcharts.com/lib/5/geodata/worldLow_simplified.js"></script>
<script src="https://cdn.amcharts.com/lib/5/themes/Animated.js"></script>
<div id="chartdiv"></div>

1

There are 1 best solutions below

1
Naren Murali On

You are creating too many polygons in your code, here is a simplified version which required a lot of effort to get it working, apart from legend everything works!

/**
 * ---------------------------------------
 * This demo was created using amCharts 5.
 * 
 * For more information visit:
 * https://www.amcharts.com/
 * 
 * Documentation is available at:
 * https://www.amcharts.com/docs/v5/
 * ---------------------------------------
 */

// Data
var groupData = [{
  "name": "G1",
  "data": [{
      "id": "AT",
      "joined": "1995"
    },
    {
      "id": "IE",
      "joined": "1973"
    },
  ]
}, {
  "name": "G2",
  "data": [{
      "id": "LT",
      "joined": "2004"
    },
    {
      "id": "LV",
      "joined": "2004"
    },
    {
      "id": "CZ",
      "joined": "2004"
    },
    {
      "id": "SK",
      "joined": "2004"
    },
    {
      "id": "SI",
      "joined": "2004"
    },
    {
      "id": "EE",
      "joined": "2004"
    },
    {
      "id": "HU",
      "joined": "2004"
    },
    {
      "id": "CY",
      "joined": "2004"
    },
    {
      "id": "MT",
      "joined": "2004"
    },
    {
      "id": "PL",
      "joined": "2004"
    }
  ]
}, {
  "name": "G3",
  "data": [{
      "id": "RO",
      "joined": "2007"
    },
    {
      "id": "BG",
      "joined": "2007"
    }
  ]
}, {
  "name": "G4",
  "data": [{
    "id": "HR",
    "joined": "2013"
  }]
}, {
  "name": "G5",
  "data": [{
    "id": "DK",
    "joined": "1973"
  }, ]
}, {
  "name": "G6",
  "data": [{
    "id": "FI",
    "joined": "1995"
  }, ]
}, {
  "name": "G7",
  "data": [{
    "id": "SE",
    "joined": "1995"
  }, ]
}, {
  "name": "G8",
  "data": [{
    "id": "GB",
    "joined": "1973"
  }, ]
}, {
  "name": "G9",
  "data": [{
    "id": "IT",
    "joined": "1957"
  }, ]
}, {
  "name": "G10",
  "data": [{
    "id": "FR",
    "joined": "1957"
  }, ]
}, {
  "name": "G11",
  "data": [{
    "id": "ES",
    "joined": "1986"
  }, ]
}, {
  "name": "G12",
  "data": [{
    "id": "GR",
    "joined": "1981"
  }, ]
}, {
  "name": "G13",
  "data": [{
    "id": "DE",
    "joined": "1957"
  }, ]
}, {
  "name": "G14",
  "data": [{
    "id": "BE",
    "joined": "1957"
  }, ]
}, {
  "name": "G15",
  "data": [{
    "id": "LU",
    "joined": "1957"
  }, ]
}, {
  "name": "G16",
  "data": [{
    "id": "NL",
    "joined": "1957"
  }, ]
}, {
  "name": "G17",
  "data": [{
    "id": "PT",
    "joined": "1986"
  }]
}, {
  "name": "G18",
  "data": [{
    "id": "CZ",
    "joined": "2004"
  }, ]
}, {
  "name": "G19",
  "data": [{
    "id": "SK",
    "joined": "2004"
  }, ]
}, {
  "name": "G20",
  "data": [{
    "id": "SI",
    "joined": "2004"
  }, ]
}, {
  "name": "G21",
  "data": [{
    "id": "HU",
    "joined": "2004"
  }, ]
}, {
  "name": "G22",
  "data": [{
    "id": "CY",
    "joined": "2004"
  }, ]
}, {
  "name": "G23",
  "data": [{
    "id": "US",
    "joined": "2004"
  }, ]
}, {
  "name": "G24",
  "data": [{
    "id": "PL",
    "joined": "2004"
  }]
}, {
  "name": "G25",
  "data": [{
    "id": "CA",
    "joined": "2004"
  }, ]
}, {
  "name": "G26",
  "data": [{
    "id": "CN",
    "joined": "2004"
  }, ]
}, {
  "name": "G27",
  "data": [{
    "id": "AU",
    "joined": "2004"
  }, ]
}, {
  "name": "G28",
  "data": [{
    "id": "BR",
    "joined": "2004"
  }, ]
}];


// Create root and chart
var root = am5.Root.new("chartdiv");


// Set themes
root.setThemes([
  am5themes_Animated.new(root)
]);


// Create chart
var chart = root.container.children.push(am5map.MapChart.new(root, {
  homeZoomLevel: 0.7,
}));



// Add legend
var legend = chart.children.push(am5.Legend.new(root, {
  useDefaultMarker: true,
  centerX: am5.p50,
  x: am5.p50,
  centerY: am5.p100,
  y: am5.p100,
  dy: -20,
  background: am5.RoundedRectangle.new(root, {
    fill: am5.color(0xffffff),
    fillOpacity: 0.2
  })
}));

legend.valueLabels.template.set("forceHidden", true)

// Create series for each group
var colors = am5.ColorSet.new(root, {
  step: 2
});
colors.next();

var output = [],
  hashMap = {}, legendData = [];
am5.array.each(groupData, function(group) {
  var color = colors.next();
  legendData.push({
    name: group.name,
    color: color,
  });
  am5.array.each(group.data, function(item) {
    hashMap[item.id] = true;
    output.push({
      id: item.id,
      name: group.name,
      joined: item.joined,
      polygonSettings: {
        fill: color,
        name: group.name,
        joined: item.joined,
      }
    });
  });
});


var polygonSeries = chart.series.push(
  am5map.MapPolygonSeries.new(root, {
    geoJSON: am5geodata_worldLow,
    exclude: ["AQ"],
    fill: am5.color(0xaaaaaa)
  })
);

polygonSeries.mapPolygons.template.setAll({
  templateField: "polygonSettings",
  interactive: true,
});



polygonSeries.mapPolygons.template.adapters.add("strokeWidth", function(strokeWidth, target) {
  const id = target.dataItem.dataContext.id;
  if (hashMap[id]) {
    return 2;
  } else {
    return strokeWidth;
  }
});

polygonSeries.mapPolygons.template.adapters.add("tooltipText", function(tooltipText, target) {
  const id = target.dataItem.dataContext.id;
  if (hashMap[id]) {
    return `[bold]{name}[/]\nMember since {joined}`;
  } else {
    return tooltipText;
  }
});


polygonSeries.mapPolygons.template.events.on("pointerover", function(ev) {
  var clickedCountry = ev.target.dataItem.get("id");
  console.log(clickedCountry);
  var clickedData = ev.target.series.getDataItemById(clickedCountry);
  const polygon = clickedData._settings.mapPolygon;
  if (hashMap[clickedCountry]) {
    polygon.states.remove("hover");
    polygon.states.create("hover", {
      fill: am5.Color.brighten(am5.Color.fromHex(clickedData._settings.mapPolygon._settings.fill.hex), -0.3)
    });
    polygon.states.applyAnimate("hover");
  }
});

polygonSeries.mapPolygons.template.events.on("pointerout", function(ev) {
  ev.target.series.mapPolygons.each(function(polygon) {
    polygon.states.applyAnimate("default");
  });
});

polygonSeries.data.setAll(output)


legend.data.push(...legendData);
body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
}

#chartdiv {
  width: 100%;
  height: 500px;
}
<script src="https://cdn.amcharts.com/lib/5/index.js"></script>
<script src="https://cdn.amcharts.com/lib/5/map.js"></script>
<script src="https://cdn.amcharts.com/lib/5/geodata/worldLow.js"></script>
<script src="https://cdn.amcharts.com/lib/5/geodata/worldLow_simplified.js"></script>
<script src="https://cdn.amcharts.com/lib/5/themes/Animated.js"></script>
<div id="chartdiv"></div>