diff --git a/app/client/cypress/fixtures/MapChartDsl.json b/app/client/cypress/fixtures/MapChartDsl.json
new file mode 100644
index 0000000000..809c6f0144
--- /dev/null
+++ b/app/client/cypress/fixtures/MapChartDsl.json
@@ -0,0 +1,74 @@
+{
+ "dsl": {
+ "widgetName": "MainContainer",
+ "backgroundColor": "none",
+ "rightColumn": 1206.35,
+ "snapColumns": 64,
+ "detachFromLayout": true,
+ "widgetId": "0",
+ "topRow": 0,
+ "bottomRow": 710,
+ "containerStyle": "none",
+ "snapRows": 125,
+ "parentRowSpace": 1,
+ "type": "CANVAS_WIDGET",
+ "canExtend": true,
+ "version": 46,
+ "minHeight": 690,
+ "parentColumnSpace": 1,
+ "dynamicBindingPathList": [],
+ "leftColumn": 0,
+ "children": [
+ {
+ "widgetName": "MapChart1",
+ "rightColumn": 33,
+ "data": [
+ {
+ "id": "NA",
+ "value": "515"
+ },
+ {
+ "id": "SA",
+ "value": "373"
+ },
+ {
+ "id": "AS",
+ "value": "3875"
+ },
+ {
+ "id": "EU",
+ "value": "727"
+ },
+ {
+ "id": "AF",
+ "value": "885"
+ },
+ {
+ "id": "AU",
+ "value": "32"
+ }
+ ],
+ "isCanvas": false,
+ "displayName": "Map Chart",
+ "iconSVG": "/static/media/icon.87faa91c.svg",
+ "widgetId": "23hfx8apm2",
+ "topRow": 7,
+ "bottomRow": 39,
+ "mapType": "WORLD",
+ "parentRowSpace": 10,
+ "isVisible": true,
+ "type": "MAP_CHART_WIDGET",
+ "version": 1,
+ "hideCard": false,
+ "parentId": "0",
+ "mapTitle": "Global Population",
+ "renderMode": "CANVAS",
+ "isLoading": false,
+ "parentColumnSpace": 18.66171875,
+ "showLabels": true,
+ "leftColumn": 9,
+ "key": "20o6b88hp8"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/MapChart_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/MapChart_spec.js
new file mode 100644
index 0000000000..cfc3cca4da
--- /dev/null
+++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/MapChart_spec.js
@@ -0,0 +1,148 @@
+const commonLocators = require("../../../../locators/commonlocators.json");
+const viewWidgetsPage = require("../../../../locators/ViewWidgets.json");
+const widgetsPage = require("../../../../locators/Widgets.json");
+const modalWidgetPage = require("../../../../locators/ModalWidget.json");
+const dsl = require("../../../../fixtures/MapChartDsl.json");
+
+describe("Map Chart Widget Functionality", function() {
+ before(() => {
+ cy.addDsl(dsl);
+ });
+
+ beforeEach(() => {
+ cy.openPropertyPane("mapchartwidget");
+ });
+
+ afterEach(() => {
+ cy.goToEditFromPublish();
+ });
+
+ it("Change Title", function() {
+ cy.testCodeMirror(this.data.chartIndata);
+ cy.get(viewWidgetsPage.chartInnerText)
+ .contains("App Sign Up")
+ .should("have.text", "App Sign Up");
+ cy.PublishtheApp();
+ });
+
+ it("Show Labels: FALSE", function() {
+ cy.togglebarDisable(commonLocators.mapChartShowLabels);
+ cy.get(viewWidgetsPage.mapChartEntityLabels).should("not.exist");
+ cy.PublishtheApp();
+ });
+
+ it("Show Labels: TRUE", function() {
+ cy.togglebar(commonLocators.mapChartShowLabels);
+ cy.get(viewWidgetsPage.mapChartEntityLabels)
+ .eq(1)
+ .should("exist");
+ cy.PublishtheApp();
+ });
+
+ it("Map type: World with Antarctica", function() {
+ // Change the map type
+ cy.updateMapType("World with Antarctica");
+ // Verify the number of entities
+ cy.get(viewWidgetsPage.mapChartEntityLabels).should("have.length", 7);
+ cy.PublishtheApp();
+ });
+
+ it("Map type: World", function() {
+ // Change the map type
+ cy.updateMapType("World");
+ // Verify the number of entities
+ cy.get(viewWidgetsPage.mapChartEntityLabels).should("have.length", 6);
+ cy.PublishtheApp();
+ });
+
+ it("Map type: Europe", function() {
+ // Change the map type
+ cy.updateMapType("Europe");
+ // Verify the number of entities
+ cy.get(viewWidgetsPage.mapChartEntityLabels).should("have.length", 47);
+ cy.PublishtheApp();
+ });
+
+ it("Map type: North America", function() {
+ // Change the map type
+ cy.updateMapType("North America");
+ // Verify the number of entities
+ cy.get(viewWidgetsPage.mapChartEntityLabels).should("have.length", 26);
+ cy.PublishtheApp();
+ });
+
+ it("Map type: South America", function() {
+ // Change the map type
+ cy.updateMapType("South America");
+ // Verify the number of entities
+ cy.get(viewWidgetsPage.mapChartEntityLabels).should("have.length", 16);
+ cy.PublishtheApp();
+ });
+
+ it("Map type: Asia", function() {
+ // Change the map type
+ cy.updateMapType("Asia");
+ // Verify the number of entities
+ cy.get(viewWidgetsPage.mapChartEntityLabels).should("have.length", 49);
+ cy.PublishtheApp();
+ });
+
+ it("Map type: Oceania", function() {
+ // Change the map type
+ cy.updateMapType("Oceania");
+ // Verify the number of entities
+ cy.get(viewWidgetsPage.mapChartEntityLabels).should("have.length", 15);
+ cy.PublishtheApp();
+ });
+
+ it("Map type: Africa", function() {
+ // Change the map type
+ cy.updateMapType("Africa");
+ // Verify the number of entities
+ cy.get(viewWidgetsPage.mapChartEntityLabels).should("have.length", 56);
+ cy.PublishtheApp();
+ });
+
+ it("Action: onDataPointClick, Open modal", function() {
+ // Create the Alert Modal and verify Modal name
+ cy.createModal(this.data.ModalName);
+ cy.PublishtheApp();
+ cy.get(widgetsPage.mapChartPlot)
+ .children()
+ .first()
+ .click({ force: true });
+ cy.get(modalWidgetPage.modelTextField).should(
+ "have.text",
+ this.data.ModalName,
+ );
+ });
+
+ it("Action: onDataPointClick, Show message using selectedDataPoint", function() {
+ const expectedEntityData = {
+ value: 2.04,
+ label: "South America",
+ shortLabel: "SA",
+ originalId: "SA",
+ id: "sa",
+ };
+ // Set the map type to default
+ cy.updateMapType("World");
+ // Set action details for onDataPointClick
+ const boundMessage = `{{JSON.stringify(MapChart1.selectedDataPoint)}}`;
+ cy.addAction(boundMessage);
+ cy.get(commonLocators.chooseMsgType)
+ .last()
+ .click();
+ cy.get(commonLocators.chooseAction)
+ .children()
+ .contains("Success")
+ .click();
+ // Click on the entity, South America
+ cy.get(widgetsPage.mapChartPlot)
+ .children()
+ .first()
+ .click({ force: true });
+ // Assert
+ cy.validateToastMessage(JSON.stringify(expectedEntityData));
+ });
+});
diff --git a/app/client/cypress/locators/ViewWidgets.json b/app/client/cypress/locators/ViewWidgets.json
index d71bd9d2cc..bb11238d30 100644
--- a/app/client/cypress/locators/ViewWidgets.json
+++ b/app/client/cypress/locators/ViewWidgets.json
@@ -2,6 +2,7 @@
"imageWidget": ".t--draggable-imagewidget",
"chartWidget": ".t--draggable-chartwidget",
"chartType": ".t--property-control-charttype .bp3-popover-target",
+ "mapType": ".t--property-control-maptype .bp3-popover-target",
"destin": ".appsmith_widget_01ewdomru7",
"mapWidget": ".t--draggable-mapwidget",
"dropdownSelectButton": ".t--open-dropdown-Select",
@@ -30,5 +31,6 @@
"defaultImage": ".t--property-control-defaultimage .CodeMirror textarea",
"Chartlabel": ".t--draggable-chartwidget g:nth-child(5) text",
"PieChartLabel": ".t--draggable-chartwidget g g:nth-child(1) g text",
- "pickMyLocation": ".t--draggable-mapwidget div[title='Pick My Location']"
+ "pickMyLocation": ".t--draggable-mapwidget div[title='Pick My Location']",
+ "mapChartEntityLabels": ".t--draggable-mapchartwidget g[class*='-entityLabels'] text"
}
diff --git a/app/client/cypress/locators/Widgets.json b/app/client/cypress/locators/Widgets.json
index c010c3364a..da8f82b84a 100644
--- a/app/client/cypress/locators/Widgets.json
+++ b/app/client/cypress/locators/Widgets.json
@@ -155,6 +155,7 @@
"filterApplyBtn":".t--apply-filter-btn",
"filterCloseBtn":".t--close-filter-btn",
"header":"#header-root",
+ "mapChartPlot": "g[class$='-manager-plot']",
"explorerSwitchId": "#switcher--explorer",
"widgetSwitchId":"#switcher--widgets",
"modalWidget": ".t--modal-widget",
diff --git a/app/client/cypress/locators/commonlocators.json b/app/client/cypress/locators/commonlocators.json
index 31897cded9..e70c21d9f9 100644
--- a/app/client/cypress/locators/commonlocators.json
+++ b/app/client/cypress/locators/commonlocators.json
@@ -149,5 +149,6 @@
"dropdownWidget": ".t--draggable-dropdownwidget",
"textWidget": ".t--draggable-textwidget",
"filepickerv2": ".t--draggable-filepickerwidgetv2",
- "dashboardItemName": ".uppy-Dashboard-Item-name"
+ "dashboardItemName": ".uppy-Dashboard-Item-name",
+ "mapChartShowLabels": ".t--property-control-showlabels input"
}
\ No newline at end of file
diff --git a/app/client/cypress/support/commands.js b/app/client/cypress/support/commands.js
index d62b4e24a7..74d931d7bf 100644
--- a/app/client/cypress/support/commands.js
+++ b/app/client/cypress/support/commands.js
@@ -3154,6 +3154,22 @@ Cypress.Commands.add("createAmazonS3Datasource", () => {
cy.testSaveDatasource();
});
+Cypress.Commands.add("updateMapType", (mapType) => {
+ // Command to change the map chart type if the property pane of the map chart widget is opened.
+ cy.get(viewWidgetsPage.mapType)
+ .last()
+ .click({ force: true });
+ cy.get(commonlocators.dropdownmenu)
+ .children()
+ .contains(mapType)
+ .click({ force: true });
+
+ cy.get(viewWidgetsPage.mapType + " span.cs-text").should(
+ "have.text",
+ mapType,
+ );
+});
+
Cypress.Commands.add("createJSObject", (JSCode) => {
cy.NavigateToJSEditor();
cy.wait(1000);
diff --git a/app/client/package.json b/app/client/package.json
index 310983bf84..520ceb34f2 100644
--- a/app/client/package.json
+++ b/app/client/package.json
@@ -58,7 +58,8 @@
"fast-xml-parser": "^3.17.5",
"flow-bin": "^0.148.0",
"fuse.js": "^3.4.5",
- "fusioncharts": "^3.16.0",
+ "fusioncharts": "^3.18.0",
+ "fusionmaps": "^3.18.0",
"history": "^4.10.1",
"husky": "^3.0.5",
"immer": "^9.0.6",
@@ -104,6 +105,7 @@
"react-documents": "^1.0.4",
"react-dom": "^16.7.0",
"react-full-screen": "^1.1.0",
+ "react-fusioncharts": "^3.1.2",
"react-google-maps": "^9.4.5",
"react-google-recaptcha": "^2.1.0",
"react-helmet": "^5.2.1",
diff --git a/app/client/src/assets/icons/widget/map-chart.svg b/app/client/src/assets/icons/widget/map-chart.svg
new file mode 100755
index 0000000000..df46b76615
--- /dev/null
+++ b/app/client/src/assets/icons/widget/map-chart.svg
@@ -0,0 +1,6 @@
+
diff --git a/app/client/src/constants/HelpConstants.ts b/app/client/src/constants/HelpConstants.ts
index 4393bcf9a4..74527dadb6 100644
--- a/app/client/src/constants/HelpConstants.ts
+++ b/app/client/src/constants/HelpConstants.ts
@@ -175,6 +175,10 @@ export const HelpMap: Record = {
path: "/widget-reference/switch-group",
searchKey: "Switch Group",
},
+ MAP_CHART_WIDGET: {
+ path: "/widget-reference/map-chart",
+ searchKey: "Map Chart",
+ },
};
export const HelpBaseURL = "https://docs.appsmith.com";
diff --git a/app/client/src/icons/WidgetIcons.tsx b/app/client/src/icons/WidgetIcons.tsx
index 3e4839943a..2ddce3b51d 100644
--- a/app/client/src/icons/WidgetIcons.tsx
+++ b/app/client/src/icons/WidgetIcons.tsx
@@ -40,6 +40,7 @@ import { ReactComponent as ButtonGroupIcon } from "assets/icons/widget/button-gr
import { ReactComponent as ProgressBarIcon } from "assets/icons/widget/progressbar-icon.svg";
import { ReactComponent as SwitchGroupIcon } from "assets/icons/widget/switch-group.svg";
import { ReactComponent as CameraIcon } from "assets/icons/widget/camera.svg";
+import { ReactComponent as MapChartIcon } from "assets/icons/widget/map-chart.svg";
/* eslint-disable react/display-name */
@@ -244,6 +245,11 @@ export const WidgetIcons: {
),
+ MAP_CHART_WIDGET: (props: IconProps) => (
+
+
+
+ ),
};
export type WidgetIcon = typeof WidgetIcons[keyof typeof WidgetIcons];
diff --git a/app/client/src/utils/WidgetRegistry.tsx b/app/client/src/utils/WidgetRegistry.tsx
index 3903610ce3..9e2d291f1d 100644
--- a/app/client/src/utils/WidgetRegistry.tsx
+++ b/app/client/src/utils/WidgetRegistry.tsx
@@ -114,12 +114,14 @@ import ProgressBarWidget, {
import SwitchGroupWidget, {
CONFIG as SWITCH_GROUP_WIDGET_CONFIG,
} from "widgets/SwitchGroupWidget";
-
-import log from "loglevel";
-
import CameraWidget, {
CONFIG as CAMERA_WIDGET_CONFIG,
} from "widgets/CameraWidget";
+import MapChartWidget, {
+ CONFIG as MAP_CHART_WIDGET_CONFIG,
+} from "widgets/MapChartWidget";
+
+import log from "loglevel";
export const registerWidgets = () => {
const start = performance.now();
@@ -167,6 +169,7 @@ export const registerWidgets = () => {
registerWidget(AudioWidget, AUDIO_WIDGET_CONFIG);
registerWidget(ProgressBarWidget, PROGRESSBAR_WIDGET_CONFIG);
registerWidget(CameraWidget, CAMERA_WIDGET_CONFIG);
+ registerWidget(MapChartWidget, MAP_CHART_WIDGET_CONFIG);
log.debug("Widget registration took: ", performance.now() - start, "ms");
};
diff --git a/app/client/src/utils/autocomplete/EntityDefinitions.ts b/app/client/src/utils/autocomplete/EntityDefinitions.ts
index 17f7f6227f..6d2229939c 100644
--- a/app/client/src/utils/autocomplete/EntityDefinitions.ts
+++ b/app/client/src/utils/autocomplete/EntityDefinitions.ts
@@ -449,6 +449,13 @@ export const entityDefinitions: Record = {
videoDataURL: "string",
videoRawBinary: "string",
},
+ MAP_CHART_WIDGET: {
+ "!doc":
+ "Map Chart widget shows the graphical representation of your data on the map.",
+ "!url": "https://docs.appsmith.com/widget-reference/map-chart",
+ isVisible: isVisible,
+ selectedDataPoint: "mapChartDataPoint",
+ },
};
export const GLOBAL_DEFS = {
@@ -483,6 +490,13 @@ export const GLOBAL_DEFS = {
name: "text",
type: "file",
},
+ mapChartDataPoint: {
+ id: "string",
+ label: "string",
+ originalId: "string",
+ shortLabel: "string",
+ value: "number",
+ },
};
export const GLOBAL_FUNCTIONS = {
diff --git a/app/client/src/widgets/MapChartWidget/CustomMapConstants.ts b/app/client/src/widgets/MapChartWidget/CustomMapConstants.ts
new file mode 100644
index 0000000000..727968c4c5
--- /dev/null
+++ b/app/client/src/widgets/MapChartWidget/CustomMapConstants.ts
@@ -0,0 +1,14 @@
+export const CUSTOM_MAP_PLUGINS: Record = {
+ world: require(`fusionmaps/maps/fusioncharts.world.js`),
+ worldwithantarctica: require(`fusionmaps/maps/fusioncharts.worldwithantarctica.js`),
+ europe: require(`fusionmaps/maps/fusioncharts.europe.js`),
+ northamerica: require(`fusionmaps/maps/fusioncharts.northamerica.js`),
+ southamerica: require(`fusionmaps/maps/fusioncharts.southamerica.js`),
+ asia: require(`fusionmaps/maps/fusioncharts.asia.js`),
+ oceania: require(`fusionmaps/maps/fusioncharts.oceania.js`),
+ africa: require(`fusionmaps/maps/fusioncharts.africa.js`),
+};
+
+export const CUSTOM_MAP_TYPES = Object.keys(CUSTOM_MAP_PLUGINS).map(
+ (each) => `maps/${each}`,
+);
diff --git a/app/client/src/widgets/MapChartWidget/component/index.tsx b/app/client/src/widgets/MapChartWidget/component/index.tsx
new file mode 100644
index 0000000000..c5a867490d
--- /dev/null
+++ b/app/client/src/widgets/MapChartWidget/component/index.tsx
@@ -0,0 +1,217 @@
+import React, { useEffect, useState } from "react";
+import styled from "styled-components";
+// Include the react-fusioncharts component
+import ReactFC from "react-fusioncharts";
+// Include the fusioncharts library
+import FusionCharts, { ChartObject } from "fusioncharts";
+
+// Import FusionMaps
+import FusionMaps from "fusioncharts/fusioncharts.maps";
+import World from "fusioncharts/maps/fusioncharts.world";
+
+// Include the theme as fusion
+import FusionTheme from "fusioncharts/themes/fusioncharts.theme.fusion";
+
+// Import the dataset and the colorRange of the map
+import { dataSetForWorld, MapTypes, MapColorObject } from "../constants";
+import { CUSTOM_MAP_PLUGINS } from "../CustomMapConstants";
+
+// Adding the chart and theme as dependency to the core fusioncharts
+ReactFC.fcRoot(FusionCharts, FusionMaps, World, FusionTheme);
+
+const MapChartContainer = styled.div`
+ display: flex;
+ height: 100%;
+ width: 100%;
+ background: white;
+
+ & > div {
+ width: 100%;
+ }
+`;
+
+export interface MapData {
+ value?: string;
+ displayValue?: string;
+ toolText?: string;
+ color?: string;
+ alpha?: number;
+ link?: string;
+ font?: string;
+ fontSize?: string;
+ fontColor?: string;
+ fontBold?: boolean;
+ showLabel?: boolean;
+ showToolTip?: boolean;
+ labelConnectorColor?: string;
+ labelConnectorAlpha?: number;
+ useHoverColor?: boolean;
+}
+
+export type MapType = keyof typeof MapTypes;
+
+export interface EntityData {
+ id: string;
+ label: string;
+ originalId: string;
+ shortLabel: string;
+ value: number;
+}
+
+function MapChartComponent(props: MapChartComponentProps) {
+ const {
+ caption,
+ colorRange,
+ data,
+ onDataPointClick,
+ showLabels,
+ type,
+ } = props;
+
+ // Creating the JSON object to store the chart configurations
+ const defaultChartConfigs: ChartObject = {
+ type: "maps/world", // The chart type
+ width: "100%", // Width of the chart
+ height: "100%", // Height of the chart
+ dataFormat: "json", // Data type
+ dataSource: {
+ // Map Configuration
+ chart: {
+ caption: "Average Annual Population Growth",
+ // subcaption: " 1955-2015",
+ // numbersuffix: "%",
+ includevalueinlabels: "1",
+ labelsepchar: ": ",
+ entityFillHoverColor: "#FFF9C4",
+ theme: "fusion",
+ },
+ // Aesthetics; ranges synced with the slider
+ colorRange: {
+ gradient: "0",
+ },
+ // Source data as JSON --> id represents countries of the world.
+ data: dataSetForWorld,
+ },
+ events: {},
+ };
+
+ const [chartConfigs, setChartConfigs] = useState(defaultChartConfigs);
+ const [chart, setChart] = useState(new FusionCharts(defaultChartConfigs));
+
+ useEffect(() => {
+ // Attach event handlers
+ const newChartConfigs: any = {
+ ...chartConfigs,
+ };
+ newChartConfigs["events"]["entityClick"] = onDataPointClick;
+ setChartConfigs(newChartConfigs);
+
+ return () => {
+ chart.removeEventListener("entityClick", onDataPointClick);
+ };
+ }, [onDataPointClick]);
+
+ useEffect(() => {
+ const newChartConfigs: any = {
+ ...chartConfigs,
+ };
+ newChartConfigs["dataSource"]["chart"]["caption"] = caption;
+ setChartConfigs(newChartConfigs);
+ }, [caption]);
+
+ useEffect(() => {
+ const targetValue = showLabels ? "1" : "0";
+
+ const newChartConfigs: any = {
+ ...chartConfigs,
+ };
+ newChartConfigs["dataSource"]["chart"]["showLabels"] = targetValue;
+ setChartConfigs(newChartConfigs);
+ }, [showLabels]);
+
+ useEffect(() => {
+ const newChartConfigs: any = {
+ ...chartConfigs,
+ };
+ newChartConfigs["dataSource"]["colorRange"]["color"] = colorRange;
+ chart.setChartData(newChartConfigs.dataSource, "json");
+ }, [JSON.stringify(colorRange)]);
+
+ useEffect(() => {
+ const newChartConfigs = {
+ ...chartConfigs,
+ dataSource: {
+ ...(chartConfigs.dataSource || {}),
+ data,
+ },
+ };
+
+ switch (type) {
+ case MapTypes.WORLD_WITH_ANTARCTICA:
+ newChartConfigs.type = "maps/worldwithantarctica";
+ break;
+ case MapTypes.EUROPE:
+ newChartConfigs.type = "maps/europe";
+ break;
+ case MapTypes.NORTH_AMERICA:
+ newChartConfigs.type = "maps/northamerica";
+ break;
+ case MapTypes.SOURTH_AMERICA:
+ newChartConfigs.type = "maps/southamerica";
+ break;
+ case MapTypes.ASIA:
+ newChartConfigs.type = "maps/asia";
+ break;
+ case MapTypes.OCEANIA:
+ newChartConfigs.type = "maps/oceania";
+ break;
+ case MapTypes.AFRICA:
+ newChartConfigs.type = "maps/africa";
+ break;
+
+ default:
+ newChartConfigs.type = "maps/world";
+ break;
+ }
+
+ if (type === MapTypes.WORLD) {
+ setChartConfigs(newChartConfigs);
+ return;
+ }
+
+ initializeMap(newChartConfigs);
+ }, [JSON.stringify(data), type]);
+
+ // Called by FC-React component to return the rendered chart
+ const renderComplete = (chart: FusionCharts.FusionCharts) => {
+ setChart(chart);
+ };
+
+ const initializeMap = (configs: ChartObject) => {
+ const { type: mapType } = configs;
+ if (mapType) {
+ const alias = mapType.substring(5);
+ const mapDefinition = CUSTOM_MAP_PLUGINS[alias];
+ ReactFC.fcRoot(FusionCharts, FusionMaps, mapDefinition, FusionTheme);
+ setChartConfigs(configs);
+ }
+ };
+
+ return (
+
+
+
+ );
+}
+
+export interface MapChartComponentProps {
+ caption: string;
+ colorRange: MapColorObject[];
+ data: MapData[];
+ isVisible: boolean;
+ onDataPointClick: (evt: any) => void;
+ showLabels: boolean;
+ type: MapType;
+}
+
+export default MapChartComponent;
diff --git a/app/client/src/widgets/MapChartWidget/constants.ts b/app/client/src/widgets/MapChartWidget/constants.ts
new file mode 100644
index 0000000000..454f999053
--- /dev/null
+++ b/app/client/src/widgets/MapChartWidget/constants.ts
@@ -0,0 +1,988 @@
+// This file contains common constants which can be used across the widget configuration file (index.ts), widget and component folders.
+
+export enum MapTypes {
+ WORLD = "WORLD",
+ WORLD_WITH_ANTARCTICA = "WORLD_WITH_ANTARCTICA",
+ EUROPE = "EUROPE",
+ NORTH_AMERICA = "NORTH_AMERICA",
+ SOURTH_AMERICA = "SOURTH_AMERICA",
+ ASIA = "ASIA",
+ OCEANIA = "OCEANIA",
+ AFRICA = "AFRICA",
+}
+
+export interface MapColorObject {
+ minValue: number;
+ maxValue: number;
+ displayValue: string;
+ code: string;
+ alpha: number;
+}
+
+// Define the dataset and the colorRange of the map
+export const dataSetForWorld = [
+ {
+ id: "NA",
+ value: ".82",
+ },
+ {
+ id: "SA",
+ value: "2.04",
+ },
+ {
+ id: "AS",
+ value: "1.78",
+ },
+ {
+ id: "EU",
+ value: ".40",
+ },
+ {
+ id: "AF",
+ value: "2.58",
+ },
+ {
+ id: "AU",
+ value: "1.30",
+ },
+];
+
+export const dataSetForWorldWithAntarctica = [
+ {
+ id: "NA",
+ value: ".82",
+ },
+ {
+ id: "SA",
+ value: "2.04",
+ },
+ {
+ id: "AS",
+ value: "1.78",
+ },
+ {
+ id: "EU",
+ value: ".40",
+ },
+ {
+ id: "AF",
+ value: "2.58",
+ },
+ {
+ id: "AU",
+ value: "1.30",
+ },
+ {
+ id: "AT",
+ value: "1",
+ },
+];
+
+export const dataSetForEurope = [
+ {
+ id: "001",
+ value: ".82",
+ },
+ {
+ id: "002",
+ value: "2.04",
+ },
+ {
+ id: "003",
+ value: "1.78",
+ },
+ {
+ id: "004",
+ value: ".40",
+ },
+ {
+ id: "005",
+ value: "2.58",
+ },
+ {
+ id: "006",
+ value: "1.30",
+ },
+ {
+ id: "007",
+ value: ".82",
+ },
+ {
+ id: "008",
+ value: "2.04",
+ },
+ {
+ id: "009",
+ value: "1.78",
+ },
+ {
+ id: "010",
+ value: ".40",
+ },
+ {
+ id: "011",
+ value: "2.58",
+ },
+ {
+ id: "012",
+ value: "1.30",
+ },
+ {
+ id: "013",
+ value: ".82",
+ },
+ {
+ id: "014",
+ value: "2.04",
+ },
+ {
+ id: "015",
+ value: "1.78",
+ },
+ {
+ id: "016",
+ value: ".40",
+ },
+ {
+ id: "017",
+ value: "2.58",
+ },
+ {
+ id: "018",
+ value: "1.30",
+ },
+
+ {
+ id: "019",
+ value: ".82",
+ },
+ {
+ id: "020",
+ value: "2.04",
+ },
+ {
+ id: "021",
+ value: "1.78",
+ },
+ {
+ id: "022",
+ value: ".40",
+ },
+ {
+ id: "023",
+ value: "2.58",
+ },
+ {
+ id: "024",
+ value: "1.30",
+ },
+ {
+ id: "025",
+ value: ".82",
+ },
+ {
+ id: "026",
+ value: "2.04",
+ },
+ {
+ id: "027",
+ value: "1.78",
+ },
+ {
+ id: "028",
+ value: ".40",
+ },
+ {
+ id: "029",
+ value: "2.58",
+ },
+ {
+ id: "030",
+ value: "1.30",
+ },
+ {
+ id: "031",
+ value: ".82",
+ },
+ {
+ id: "032",
+ value: "2.04",
+ },
+ {
+ id: "033",
+ value: "1.78",
+ },
+ {
+ id: "034",
+ value: ".40",
+ },
+ {
+ id: "035",
+ value: "2.58",
+ },
+ {
+ id: "036",
+ value: "1.30",
+ },
+ {
+ id: "037",
+ value: ".82",
+ },
+ {
+ id: "038",
+ value: "2.04",
+ },
+ {
+ id: "039",
+ value: "1.78",
+ },
+ {
+ id: "040",
+ value: ".40",
+ },
+ {
+ id: "041",
+ value: "2.58",
+ },
+ {
+ id: "042",
+ value: "1.30",
+ },
+
+ {
+ id: "043",
+ value: ".82",
+ },
+ {
+ id: "044",
+ value: "2.04",
+ },
+ {
+ id: "045",
+ value: "1.78",
+ },
+ {
+ id: "046",
+ value: ".40",
+ },
+ {
+ id: "047",
+ value: "2.58",
+ },
+];
+
+export const dataSetForNorthAmerica = [
+ {
+ id: "001",
+ value: ".82",
+ },
+ {
+ id: "002",
+ value: "2.04",
+ },
+ {
+ id: "003",
+ value: "1.78",
+ },
+ {
+ id: "004",
+ value: ".40",
+ },
+ {
+ id: "005",
+ value: "2.58",
+ },
+ {
+ id: "006",
+ value: "1.30",
+ },
+ {
+ id: "007",
+ value: ".82",
+ },
+ {
+ id: "008",
+ value: "2.04",
+ },
+ {
+ id: "009",
+ value: "1.78",
+ },
+ {
+ id: "010",
+ value: ".40",
+ },
+ {
+ id: "011",
+ value: "2.58",
+ },
+ {
+ id: "012",
+ value: "1.30",
+ },
+ {
+ id: "013",
+ value: ".82",
+ },
+ {
+ id: "014",
+ value: "2.04",
+ },
+ {
+ id: "015",
+ value: "1.78",
+ },
+ {
+ id: "016",
+ value: ".40",
+ },
+ {
+ id: "017",
+ value: "2.58",
+ },
+ {
+ id: "018",
+ value: "1.30",
+ },
+
+ {
+ id: "019",
+ value: ".82",
+ },
+ {
+ id: "020",
+ value: "2.04",
+ },
+ {
+ id: "021",
+ value: "1.78",
+ },
+ {
+ id: "022",
+ value: ".40",
+ },
+ {
+ id: "023",
+ value: "2.58",
+ },
+];
+
+export const dataSetForSouthAmerica = [
+ {
+ id: "001",
+ value: ".82",
+ },
+ {
+ id: "002",
+ value: "2.04",
+ },
+ {
+ id: "003",
+ value: "1.78",
+ },
+ {
+ id: "004",
+ value: ".40",
+ },
+ {
+ id: "005",
+ value: "2.58",
+ },
+ {
+ id: "006",
+ value: "1.30",
+ },
+ {
+ id: "007",
+ value: ".82",
+ },
+ {
+ id: "008",
+ value: "2.04",
+ },
+ {
+ id: "009",
+ value: "1.78",
+ },
+ {
+ id: "010",
+ value: ".40",
+ },
+ {
+ id: "011",
+ value: "2.58",
+ },
+ {
+ id: "012",
+ value: "1.30",
+ },
+ {
+ id: "013",
+ value: ".82",
+ },
+];
+
+export const dataSetForAsia = [
+ {
+ id: "001",
+ value: ".82",
+ },
+ {
+ id: "002",
+ value: "2.04",
+ },
+ {
+ id: "003",
+ value: "1.78",
+ },
+ {
+ id: "004",
+ value: ".40",
+ },
+ {
+ id: "005",
+ value: "2.58",
+ },
+ {
+ id: "006",
+ value: "1.30",
+ },
+ {
+ id: "007",
+ value: ".82",
+ },
+ {
+ id: "008",
+ value: "2.04",
+ },
+ {
+ id: "009",
+ value: "1.78",
+ },
+ {
+ id: "010",
+ value: ".40",
+ },
+ {
+ id: "011",
+ value: "2.58",
+ },
+ {
+ id: "012",
+ value: "1.30",
+ },
+ {
+ id: "013",
+ value: ".82",
+ },
+ {
+ id: "014",
+ value: "2.04",
+ },
+ {
+ id: "015",
+ value: "1.78",
+ },
+ {
+ id: "016",
+ value: ".40",
+ },
+ {
+ id: "017",
+ value: "2.58",
+ },
+ {
+ id: "018",
+ value: "1.30",
+ },
+
+ {
+ id: "019",
+ value: ".82",
+ },
+ {
+ id: "020",
+ value: "2.04",
+ },
+ {
+ id: "021",
+ value: "1.78",
+ },
+ {
+ id: "022",
+ value: ".40",
+ },
+ {
+ id: "023",
+ value: "2.58",
+ },
+ {
+ id: "024",
+ value: "1.30",
+ },
+ {
+ id: "025",
+ value: ".82",
+ },
+ {
+ id: "026",
+ value: "2.04",
+ },
+ {
+ id: "027",
+ value: "1.78",
+ },
+ {
+ id: "028",
+ value: ".40",
+ },
+ {
+ id: "029",
+ value: "2.58",
+ },
+ {
+ id: "030",
+ value: "1.30",
+ },
+ {
+ id: "031",
+ value: ".82",
+ },
+ {
+ id: "032",
+ value: "2.04",
+ },
+ {
+ id: "033",
+ value: "1.78",
+ },
+ {
+ id: "034",
+ value: ".40",
+ },
+ {
+ id: "035",
+ value: "2.58",
+ },
+ {
+ id: "036",
+ value: "1.30",
+ },
+ {
+ id: "037",
+ value: ".82",
+ },
+ {
+ id: "038",
+ value: "2.04",
+ },
+ {
+ id: "039",
+ value: "1.78",
+ },
+ {
+ id: "040",
+ value: ".40",
+ },
+ {
+ id: "041",
+ value: "2.58",
+ },
+ {
+ id: "042",
+ value: "1.30",
+ },
+
+ {
+ id: "043",
+ value: ".82",
+ },
+ {
+ id: "044",
+ value: "2.04",
+ },
+ {
+ id: "045",
+ value: "1.78",
+ },
+ {
+ id: "046",
+ value: ".40",
+ },
+ {
+ id: "047",
+ value: "2.58",
+ },
+ {
+ id: "048",
+ value: ".82",
+ },
+ {
+ id: "049",
+ value: "2.04",
+ },
+ {
+ id: "050",
+ value: "1.78",
+ },
+ {
+ id: "051",
+ value: ".40",
+ },
+ {
+ id: "052",
+ value: "2.58",
+ },
+ {
+ id: "053",
+ value: "1.30",
+ },
+ {
+ id: "054",
+ value: ".82",
+ },
+ {
+ id: "055",
+ value: "2.04",
+ },
+ {
+ id: "056",
+ value: "1.78",
+ },
+ {
+ id: "057",
+ value: ".40",
+ },
+ {
+ id: "058",
+ value: "2.58",
+ },
+ {
+ id: "059",
+ value: "1.30",
+ },
+ {
+ id: "060",
+ value: ".82",
+ },
+ {
+ id: "061",
+ value: "2.04",
+ },
+ {
+ id: "062",
+ value: "1.78",
+ },
+ {
+ id: "063",
+ value: ".40",
+ },
+ {
+ id: "064",
+ value: "2.58",
+ },
+];
+
+export const dataSetForOceania = [
+ {
+ id: "001",
+ value: ".82",
+ },
+ {
+ id: "002",
+ value: "2.04",
+ },
+ {
+ id: "003",
+ value: "1.78",
+ },
+ {
+ id: "004",
+ value: ".40",
+ },
+ {
+ id: "005",
+ value: "2.58",
+ },
+ {
+ id: "006",
+ value: "1.30",
+ },
+ {
+ id: "007",
+ value: ".82",
+ },
+ {
+ id: "008",
+ value: "2.04",
+ },
+ {
+ id: "009",
+ value: "1.78",
+ },
+ {
+ id: "010",
+ value: ".40",
+ },
+ {
+ id: "011",
+ value: "2.58",
+ },
+ {
+ id: "012",
+ value: "1.30",
+ },
+ {
+ id: "013",
+ value: ".82",
+ },
+ {
+ id: "014",
+ value: "2.04",
+ },
+];
+
+export const dataSetForAfrica = [
+ {
+ id: "001",
+ value: ".82",
+ },
+ {
+ id: "002",
+ value: "2.04",
+ },
+ {
+ id: "003",
+ value: "1.78",
+ },
+ {
+ id: "004",
+ value: ".40",
+ },
+ {
+ id: "005",
+ value: "2.58",
+ },
+ {
+ id: "006",
+ value: "1.30",
+ },
+ {
+ id: "007",
+ value: ".82",
+ },
+ {
+ id: "008",
+ value: "2.04",
+ },
+ {
+ id: "009",
+ value: "1.78",
+ },
+ {
+ id: "010",
+ value: ".40",
+ },
+ {
+ id: "011",
+ value: "2.58",
+ },
+ {
+ id: "012",
+ value: "1.30",
+ },
+ {
+ id: "013",
+ value: ".82",
+ },
+ {
+ id: "014",
+ value: "2.04",
+ },
+ {
+ id: "015",
+ value: "1.78",
+ },
+ {
+ id: "016",
+ value: ".40",
+ },
+ {
+ id: "017",
+ value: "2.58",
+ },
+ {
+ id: "018",
+ value: "1.30",
+ },
+
+ {
+ id: "019",
+ value: ".82",
+ },
+ {
+ id: "020",
+ value: "2.04",
+ },
+ {
+ id: "021",
+ value: "1.78",
+ },
+ {
+ id: "022",
+ value: ".40",
+ },
+ {
+ id: "023",
+ value: "2.58",
+ },
+ {
+ id: "024",
+ value: "1.30",
+ },
+ {
+ id: "025",
+ value: ".82",
+ },
+ {
+ id: "026",
+ value: "2.04",
+ },
+ {
+ id: "027",
+ value: "1.78",
+ },
+ {
+ id: "028",
+ value: ".40",
+ },
+ {
+ id: "029",
+ value: "2.58",
+ },
+ {
+ id: "030",
+ value: "1.30",
+ },
+ {
+ id: "031",
+ value: ".82",
+ },
+ {
+ id: "032",
+ value: "2.04",
+ },
+ {
+ id: "033",
+ value: "1.78",
+ },
+ {
+ id: "034",
+ value: ".40",
+ },
+ {
+ id: "035",
+ value: "2.58",
+ },
+ {
+ id: "036",
+ value: "1.30",
+ },
+ {
+ id: "037",
+ value: ".82",
+ },
+ {
+ id: "038",
+ value: "2.04",
+ },
+ {
+ id: "039",
+ value: "1.78",
+ },
+ {
+ id: "040",
+ value: ".40",
+ },
+ {
+ id: "041",
+ value: "2.58",
+ },
+ {
+ id: "042",
+ value: "1.30",
+ },
+
+ {
+ id: "043",
+ value: ".82",
+ },
+ {
+ id: "044",
+ value: "2.04",
+ },
+ {
+ id: "045",
+ value: "1.78",
+ },
+ {
+ id: "046",
+ value: ".40",
+ },
+ {
+ id: "047",
+ value: "2.58",
+ },
+ {
+ id: "048",
+ value: ".82",
+ },
+ {
+ id: "049",
+ value: "2.04",
+ },
+ {
+ id: "050",
+ value: "1.78",
+ },
+ {
+ id: "051",
+ value: ".40",
+ },
+ {
+ id: "052",
+ value: "2.58",
+ },
+ {
+ id: "053",
+ value: "1.30",
+ },
+ {
+ id: "054",
+ value: ".82",
+ },
+ {
+ id: "055",
+ value: "2.04",
+ },
+ {
+ id: "056",
+ value: "1.78",
+ },
+ {
+ id: "057",
+ value: ".40",
+ },
+ {
+ id: "058",
+ value: "2.58",
+ },
+ {
+ id: "059",
+ value: "1.30",
+ },
+ {
+ id: "060",
+ value: ".82",
+ },
+];
diff --git a/app/client/src/widgets/MapChartWidget/icon.svg b/app/client/src/widgets/MapChartWidget/icon.svg
new file mode 100755
index 0000000000..df46b76615
--- /dev/null
+++ b/app/client/src/widgets/MapChartWidget/icon.svg
@@ -0,0 +1,6 @@
+
diff --git a/app/client/src/widgets/MapChartWidget/index.ts b/app/client/src/widgets/MapChartWidget/index.ts
new file mode 100644
index 0000000000..10d42ee3d3
--- /dev/null
+++ b/app/client/src/widgets/MapChartWidget/index.ts
@@ -0,0 +1,46 @@
+import Widget from "./widget";
+import IconSVG from "./icon.svg";
+import { dataSetForWorld, MapTypes } from "./constants";
+
+export const CONFIG = {
+ type: Widget.getWidgetType(),
+ name: "Map Chart", // The display name which will be made in uppercase and show in the widgets panel ( can have spaces )
+ iconSVG: IconSVG,
+ needsMeta: true, // Defines if this widget adds any meta properties
+ isCanvas: false, // Defines if this widget has a canvas within in which we can drop other widgets
+ defaults: {
+ rows: 32,
+ columns: 24,
+ widgetName: "MapChart",
+ version: 1,
+ mapType: MapTypes.WORLD,
+ mapTitle: "Global Population",
+ showLabels: true,
+ data: dataSetForWorld,
+ colorRange: [
+ {
+ minValue: 0.5,
+ maxValue: 1.0,
+ code: "#FFD74D",
+ },
+ {
+ minValue: 1.0,
+ maxValue: 2.0,
+ code: "#FB8C00",
+ },
+ {
+ minValue: 2.0,
+ maxValue: 3.0,
+ code: "#E65100",
+ },
+ ],
+ },
+ properties: {
+ derived: Widget.getDerivedPropertiesMap(),
+ default: Widget.getDefaultPropertiesMap(),
+ meta: Widget.getMetaPropertiesMap(),
+ config: Widget.getPropertyPaneConfig(),
+ },
+};
+
+export default Widget;
diff --git a/app/client/src/widgets/MapChartWidget/widget/index.tsx b/app/client/src/widgets/MapChartWidget/widget/index.tsx
new file mode 100644
index 0000000000..9a5fdf53ae
--- /dev/null
+++ b/app/client/src/widgets/MapChartWidget/widget/index.tsx
@@ -0,0 +1,341 @@
+import React, { lazy, Suspense } from "react";
+
+import BaseWidget, { WidgetProps, WidgetState } from "widgets/BaseWidget";
+import { WidgetType } from "constants/WidgetConstants";
+import Skeleton from "components/utils/Skeleton";
+import { retryPromise } from "utils/AppsmithUtils";
+import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
+import { ValidationTypes } from "constants/WidgetValidation";
+import { EvaluationSubstitutionType } from "entities/DataTree/dataTreeFactory";
+import {
+ dataSetForAfrica,
+ dataSetForAsia,
+ dataSetForEurope,
+ dataSetForNorthAmerica,
+ dataSetForOceania,
+ dataSetForSouthAmerica,
+ dataSetForWorld,
+ dataSetForWorldWithAntarctica,
+ MapColorObject,
+ MapTypes,
+} from "../constants";
+import { MapType } from "../component";
+import { AutocompleteDataType } from "utils/autocomplete/TernServer";
+
+const MapChartComponent = lazy(() =>
+ retryPromise(() =>
+ import(/* webpackChunkName: "mapCharts" */ "../component"),
+ ),
+);
+
+const dataSetMapping: Record = {
+ [MapTypes.WORLD]: dataSetForWorld,
+ [MapTypes.WORLD_WITH_ANTARCTICA]: dataSetForWorldWithAntarctica,
+ [MapTypes.EUROPE]: dataSetForEurope,
+ [MapTypes.NORTH_AMERICA]: dataSetForNorthAmerica,
+ [MapTypes.SOURTH_AMERICA]: dataSetForSouthAmerica,
+ [MapTypes.ASIA]: dataSetForAsia,
+ [MapTypes.OCEANIA]: dataSetForOceania,
+ [MapTypes.AFRICA]: dataSetForAfrica,
+};
+
+// A hook to update the corresponding dataset when map type is changed
+const updateDataSet = (
+ props: MapChartWidgetProps,
+ propertyPath: string,
+ propertyValue: MapType,
+) => {
+ const propertiesToUpdate = [
+ { propertyPath, propertyValue },
+ {
+ propertyPath: "data",
+ propertyValue: dataSetMapping[propertyValue],
+ },
+ ];
+
+ return propertiesToUpdate;
+};
+
+class MapChartWidget extends BaseWidget {
+ static getPropertyPaneConfig() {
+ return [
+ {
+ sectionName: "General",
+ children: [
+ {
+ helpText: "Sets the map type",
+ propertyName: "mapType",
+ label: "Map Type",
+ controlType: "DROP_DOWN",
+ options: [
+ {
+ label: "World",
+ value: MapTypes.WORLD,
+ },
+ {
+ label: "World with Antarctica",
+ value: MapTypes.WORLD_WITH_ANTARCTICA,
+ },
+ {
+ label: "Europe",
+ value: MapTypes.EUROPE,
+ },
+ {
+ label: "North America",
+ value: MapTypes.NORTH_AMERICA,
+ },
+ {
+ label: "South America",
+ value: MapTypes.SOURTH_AMERICA,
+ },
+ {
+ label: "Asia",
+ value: MapTypes.ASIA,
+ },
+ {
+ label: "Oceania",
+ value: MapTypes.OCEANIA,
+ },
+ {
+ label: "Africa",
+ value: MapTypes.AFRICA,
+ },
+ ],
+ isJSconvertible: true,
+ isBindProperty: true,
+ isTriggerProperty: false,
+ updateHook: updateDataSet,
+ validation: {
+ type: ValidationTypes.TEXT,
+ params: {
+ allowedValues: [
+ MapTypes.WORLD,
+ MapTypes.WORLD_WITH_ANTARCTICA,
+ MapTypes.EUROPE,
+ MapTypes.NORTH_AMERICA,
+ MapTypes.SOURTH_AMERICA,
+ MapTypes.ASIA,
+ MapTypes.OCEANIA,
+ MapTypes.AFRICA,
+ ],
+ },
+ },
+ },
+ {
+ helpText: "Sets the map title",
+ placeholderText: "Enter title",
+ propertyName: "mapTitle",
+ label: "Title",
+ controlType: "INPUT_TEXT",
+ isBindProperty: true,
+ isTriggerProperty: false,
+ validation: { type: ValidationTypes.TEXT },
+ },
+ {
+ propertyName: "isVisible",
+ label: "Visible",
+ helpText: "Controls the visibility of the widget",
+ controlType: "SWITCH",
+ isJSConvertible: true,
+ isBindProperty: true,
+ isTriggerProperty: false,
+ validation: { type: ValidationTypes.BOOLEAN },
+ },
+ ],
+ },
+ {
+ sectionName: "Map Chart Data",
+ children: [
+ {
+ helpText: "Populates the map with the data",
+ propertyName: "data",
+ label: "Data",
+ controlType: "INPUT_TEXT",
+ isBindProperty: true,
+ isTriggerProperty: false,
+ validation: {
+ type: ValidationTypes.ARRAY,
+ params: {
+ unique: true,
+ children: {
+ type: ValidationTypes.OBJECT,
+ params: {
+ required: true,
+ allowedKeys: [
+ {
+ name: "id",
+ type: ValidationTypes.TEXT,
+ params: {
+ unique: true,
+ required: true,
+ },
+ },
+ {
+ name: "value",
+ type: ValidationTypes.TEXT,
+ params: {
+ required: true,
+ },
+ },
+ ],
+ },
+ },
+ },
+ },
+ evaluationSubstitutionType:
+ EvaluationSubstitutionType.SMART_SUBSTITUTE,
+ },
+ {
+ propertyName: "showLabels",
+ label: "Show Labels",
+ helpText: "Sets whether entity labels will be shown or hidden",
+ controlType: "SWITCH",
+ isJSConvertible: true,
+ isBindProperty: true,
+ isTriggerProperty: false,
+ validation: { type: ValidationTypes.BOOLEAN },
+ },
+ ],
+ },
+ {
+ sectionName: "Styles",
+ children: [
+ {
+ helpText:
+ "Defines ranges for categorizing entities on a map based on their data values.",
+ propertyName: "colorRange",
+ label: "Color Range",
+ controlType: "INPUT_TEXT",
+ placeholderText: "Color range object",
+ isBindProperty: true,
+ isTriggerProperty: false,
+ validation: {
+ type: ValidationTypes.ARRAY,
+ params: {
+ unique: true,
+ children: {
+ type: ValidationTypes.OBJECT,
+ params: {
+ allowedKeys: [
+ {
+ name: "minValue",
+ type: ValidationTypes.NUMBER,
+ params: {
+ required: true,
+ },
+ },
+ {
+ name: "maxValue",
+ type: ValidationTypes.NUMBER,
+ params: {
+ required: true,
+ },
+ },
+ {
+ name: "displayValue",
+ type: ValidationTypes.TEXT,
+ },
+ {
+ name: "code",
+ type: ValidationTypes.TEXT,
+ params: {
+ expected: {
+ type: "Hex color (6-digit)",
+ example: "#FF04D7",
+ autocompleteDataType: AutocompleteDataType.STRING,
+ },
+ },
+ },
+ {
+ name: "alpha",
+ type: ValidationTypes.NUMBER,
+ params: {
+ min: 0,
+ max: 100,
+ },
+ },
+ ],
+ },
+ },
+ },
+ },
+ evaluationSubstitutionType:
+ EvaluationSubstitutionType.SMART_SUBSTITUTE,
+ },
+ ],
+ },
+ {
+ sectionName: "Actions",
+ children: [
+ {
+ helpText:
+ "Triggers an action when the map chart data point is clicked",
+ propertyName: "onDataPointClick",
+ label: "onDataPointClick",
+ controlType: "ACTION_SELECTOR",
+ isJSConvertible: true,
+ isBindProperty: true,
+ isTriggerProperty: true,
+ },
+ ],
+ },
+ ];
+ }
+
+ static getMetaPropertiesMap(): Record {
+ return {
+ selectedDataPoint: undefined,
+ };
+ }
+
+ static getWidgetType(): WidgetType {
+ return "MAP_CHART_WIDGET";
+ }
+
+ handleDataPointClick = (evt: any) => {
+ const { onDataPointClick } = this.props;
+
+ this.props.updateWidgetMetaProperty("selectedDataPoint", evt.data, {
+ triggerPropertyName: "onDataPointClick",
+ dynamicString: onDataPointClick,
+ event: {
+ type: EventType.ON_DATA_POINT_CLICK,
+ },
+ });
+ };
+
+ getPageView() {
+ const {
+ colorRange,
+ data,
+ isVisible,
+ mapTitle,
+ mapType,
+ showLabels,
+ } = this.props;
+
+ return (
+ }>
+
+
+ );
+ }
+}
+
+export interface MapChartWidgetProps extends WidgetProps {
+ mapTitle?: string;
+ mapType: MapType;
+ onDataPointClick?: string;
+ showLabels: boolean;
+ colorRange: MapColorObject[];
+}
+
+export default MapChartWidget;
diff --git a/app/client/yarn.lock b/app/client/yarn.lock
index 6687a59519..2cae1642d8 100644
--- a/app/client/yarn.lock
+++ b/app/client/yarn.lock
@@ -1879,6 +1879,11 @@
minimatch "^3.0.4"
strip-json-comments "^3.1.1"
+"@fusioncharts/accessibility@^1.5.0":
+ version "1.5.0"
+ resolved "https://registry.yarnpkg.com/@fusioncharts/accessibility/-/accessibility-1.5.0.tgz#542ae397f0957e2dc7cf5850ce5045d9aed93803"
+ integrity sha512-4O0DmNR8D0WL5KYx6b9V/N0H24cmPseICPstXvkLpxjFuzsZz5BoS3IEiCf/KjVe3kGmUFDa6Q4Hz5v9pLi1wg==
+
"@fusioncharts/charts@^3.16.0":
version "3.16.0"
resolved "https://registry.npmjs.org/@fusioncharts/charts/-/charts-3.16.0.tgz"
@@ -1888,13 +1893,24 @@
"@fusioncharts/features" "^1.2.0"
"@fusioncharts/utils" "^1.2.0"
-"@fusioncharts/constructor@^1.2.0":
- version "1.2.0"
- resolved "https://registry.npmjs.org/@fusioncharts/constructor/-/constructor-1.2.0.tgz"
+"@fusioncharts/charts@^3.18.0":
+ version "3.18.0"
+ resolved "https://registry.yarnpkg.com/@fusioncharts/charts/-/charts-3.18.0.tgz#6c52c80bc3c9af65111270faa3a2c1e8db06f64e"
+ integrity sha512-WsNQTUKWVPxYUkxUHdxodvGsJF/vFSwm/zYVbQj2WGpA74B3hAETw8lKrqk943loImoPdB2c4JsnaNE1XmkpyQ==
dependencies:
"@babel/runtime" "^7.9.2"
- "@fusioncharts/core" "^1.2.0"
- "@fusioncharts/maps" "^3.16.0"
+ "@fusioncharts/core" "^1.5.0"
+ "@fusioncharts/features" "^1.5.0"
+ "@fusioncharts/utils" "^1.5.0"
+
+"@fusioncharts/constructor@^1.5.0":
+ version "1.5.0"
+ resolved "https://registry.yarnpkg.com/@fusioncharts/constructor/-/constructor-1.5.0.tgz#8781ad22f9ea7c2d28cd706c13b9e6872ff663a7"
+ integrity sha512-oIWGtLhRjllZDsKXHDahegaUOP6uC26UT9EHHQ+W7tL9v7xxZMM1bPMg79eOg/l4ZBoc/G/YJkEEfO5tMXiDSA==
+ dependencies:
+ "@babel/runtime" "^7.9.2"
+ "@fusioncharts/core" "^1.5.0"
+ "@fusioncharts/maps" "^3.18.0"
"@fusioncharts/core@^1.2.0":
version "1.2.0"
@@ -1905,12 +1921,23 @@
core-js "^3.0.1"
ramda "^0.25.0"
-"@fusioncharts/datatable@^1.2.0":
- version "1.2.0"
- resolved "https://registry.npmjs.org/@fusioncharts/datatable/-/datatable-1.2.0.tgz"
+"@fusioncharts/core@^1.5.0":
+ version "1.5.0"
+ resolved "https://registry.yarnpkg.com/@fusioncharts/core/-/core-1.5.0.tgz#a260bbd204fc8af715c3169df071003cca00765c"
+ integrity sha512-3JT9U0BtVBHMkgUfFH0aCfoZkxPFaWyTa7dLnFEvYF255d2hdnyd3B/ZWYrEK1sQ679bMjvs4q6pMsnbNEuDqw==
dependencies:
"@babel/runtime" "^7.9.2"
- "@fusioncharts/utils" "^1.2.0"
+ "@fusioncharts/utils" "^1.5.0"
+ core-js "^3.0.1"
+ ramda "^0.25.0"
+
+"@fusioncharts/datatable@^1.5.0":
+ version "1.5.0"
+ resolved "https://registry.yarnpkg.com/@fusioncharts/datatable/-/datatable-1.5.0.tgz#397f845ddcc8f502948b9a162ac94a0a4b4943ce"
+ integrity sha512-BRxgfEAXNAr8TZToNinLjBNeTmR4MqC2ao16rTZclhIQPxtR4KkHrjTR1dMYr6tsxXQnpCmsjkV+ibssn/dDlw==
+ dependencies:
+ "@babel/runtime" "^7.9.2"
+ "@fusioncharts/utils" "^1.5.0"
"@fusioncharts/features@^1.2.0":
version "1.2.0"
@@ -1920,25 +1947,36 @@
"@fusioncharts/core" "^1.2.0"
"@fusioncharts/utils" "^1.2.0"
-"@fusioncharts/fusiontime@^2.4.0":
- version "2.4.0"
- resolved "https://registry.npmjs.org/@fusioncharts/fusiontime/-/fusiontime-2.4.0.tgz"
+"@fusioncharts/features@^1.5.0":
+ version "1.5.0"
+ resolved "https://registry.yarnpkg.com/@fusioncharts/features/-/features-1.5.0.tgz#cf919260b3fed272fddc4967d7e64a53c077081d"
+ integrity sha512-p6nxoAJFzXEeYQHgKRQI5/ciwXLb8L60faHqre6vDABUKDvPMicI9tR7yNR7AWWmvBDxhkzXOV2v2sqWCNWRFw==
dependencies:
"@babel/runtime" "^7.9.2"
- "@fusioncharts/charts" "^3.16.0"
- "@fusioncharts/core" "^1.2.0"
- "@fusioncharts/datatable" "^1.2.0"
- "@fusioncharts/utils" "^1.2.0"
+ "@fusioncharts/core" "^1.5.0"
+ "@fusioncharts/utils" "^1.5.0"
+
+"@fusioncharts/fusiontime@^2.6.0":
+ version "2.6.0"
+ resolved "https://registry.yarnpkg.com/@fusioncharts/fusiontime/-/fusiontime-2.6.0.tgz#8d7a6aab6561c7e63c44bda7218c62adea228f0c"
+ integrity sha512-un9g122BkPToSUFehD5AHluyv/gOL1TiDSp0kdO42IgtsX1UwJh3X3JVhkMagggICCKl/AM+dyuu5ids9yDN2w==
+ dependencies:
+ "@babel/runtime" "^7.9.2"
+ "@fusioncharts/charts" "^3.18.0"
+ "@fusioncharts/core" "^1.5.0"
+ "@fusioncharts/datatable" "^1.5.0"
+ "@fusioncharts/utils" "^1.5.0"
ramda "^0.25.0"
-"@fusioncharts/maps@^3.16.0":
- version "3.16.0"
- resolved "https://registry.npmjs.org/@fusioncharts/maps/-/maps-3.16.0.tgz"
+"@fusioncharts/maps@^3.18.0":
+ version "3.18.0"
+ resolved "https://registry.yarnpkg.com/@fusioncharts/maps/-/maps-3.18.0.tgz#46002bd70ee73c0085392cb4e109938b38e55c5f"
+ integrity sha512-ElzPX1fAWbT8wJuvdDFVfJHRCKRxy3Ub/B22upt8la7RuKSIfDMRRwFF7IWxrW5opJDxJY1IQNwjZVTnm0NuFA==
dependencies:
"@babel/runtime" "^7.9.2"
- "@fusioncharts/charts" "^3.16.0"
- "@fusioncharts/core" "^1.2.0"
- "@fusioncharts/features" "^1.2.0"
+ "@fusioncharts/charts" "^3.18.0"
+ "@fusioncharts/core" "^1.5.0"
+ "@fusioncharts/features" "^1.5.0"
"@fusioncharts/powercharts@^3.16.0":
version "3.16.0"
@@ -1949,6 +1987,16 @@
"@fusioncharts/core" "^1.2.0"
"@fusioncharts/utils" "^1.2.0"
+"@fusioncharts/powercharts@^3.18.0":
+ version "3.18.0"
+ resolved "https://registry.yarnpkg.com/@fusioncharts/powercharts/-/powercharts-3.18.0.tgz#ad54b12b3be3e754930b3aa3f093d06f99b4acef"
+ integrity sha512-z0q3ssKvzEyIl/C1IPCmPcPZ0X+Q4ntPAP8B/xe+E1mTXd5AYVFI2fGqXHlUCUgHvr9MYNRpjYzwIOa3YEK38Q==
+ dependencies:
+ "@babel/runtime" "^7.9.2"
+ "@fusioncharts/charts" "^3.18.0"
+ "@fusioncharts/core" "^1.5.0"
+ "@fusioncharts/utils" "^1.5.0"
+
"@fusioncharts/utils@^1.2.0":
version "1.2.0"
resolved "https://registry.npmjs.org/@fusioncharts/utils/-/utils-1.2.0.tgz"
@@ -1956,16 +2004,25 @@
"@babel/runtime" "^7.9.2"
ramda "^0.25.0"
-"@fusioncharts/widgets@^3.16.0":
- version "3.16.0"
- resolved "https://registry.npmjs.org/@fusioncharts/widgets/-/widgets-3.16.0.tgz"
+"@fusioncharts/utils@^1.5.0":
+ version "1.5.0"
+ resolved "https://registry.yarnpkg.com/@fusioncharts/utils/-/utils-1.5.0.tgz#9a3d2701f7eb5445ed26d3c21e423ff958ed8314"
+ integrity sha512-faUHPGO29jiP/RvfCXxl57snWUm7+8RHbU/0x3BAQN8wq6U7bylj8rWKmu1flFrq8vH6Kup0eR07meJzNvNaBw==
dependencies:
"@babel/runtime" "^7.9.2"
- "@fusioncharts/charts" "^3.16.0"
- "@fusioncharts/constructor" "^1.2.0"
- "@fusioncharts/core" "^1.2.0"
- "@fusioncharts/features" "^1.2.0"
- "@fusioncharts/utils" "^1.2.0"
+ ramda "^0.25.0"
+
+"@fusioncharts/widgets@^3.18.0":
+ version "3.18.0"
+ resolved "https://registry.yarnpkg.com/@fusioncharts/widgets/-/widgets-3.18.0.tgz#c967a3402e20259357fb35925686fddd991e4c11"
+ integrity sha512-FphluEdI3EYW9ERYKgfzJyAu4ipw8RJA+eJgjoAqB6dodK4SafTY5YpwyeG5V1VnIKrjFmrfk5iw3jOiFLYk5Q==
+ dependencies:
+ "@babel/runtime" "^7.9.2"
+ "@fusioncharts/charts" "^3.18.0"
+ "@fusioncharts/constructor" "^1.5.0"
+ "@fusioncharts/core" "^1.5.0"
+ "@fusioncharts/features" "^1.5.0"
+ "@fusioncharts/utils" "^1.5.0"
"@github/g-emoji-element@^1.1.5":
version "1.1.5"
@@ -3001,8 +3058,9 @@
resolved "https://registry.npmjs.org/@types/node/-/node-10.17.39.tgz"
"@types/node@^14.14.31":
- version "14.17.12"
- resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.12.tgz#7a31f720b85a617e54e42d24c4ace136601656c7"
+ version "14.17.14"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.14.tgz#6fda9785b41570eb628bac27be4b602769a3f938"
+ integrity sha512-rsAj2u8Xkqfc332iXV12SqIsjVi07H479bOP4q94NAcjzmAvapumEhuVIt53koEf7JFrpjgNKjBga5Pnn/GL8A==
"@types/normalize-package-data@^2.4.0":
version "2.4.0"
@@ -8116,21 +8174,43 @@ fuse.js@^3.4.5:
version "3.6.1"
resolved "https://registry.npmjs.org/fuse.js/-/fuse.js-3.6.1.tgz"
-fusioncharts@^3.16.0:
- version "3.16.0"
- resolved "https://registry.npmjs.org/fusioncharts/-/fusioncharts-3.16.0.tgz"
+fusioncharts@^3.18.0:
+ version "3.18.0"
+ resolved "https://registry.yarnpkg.com/fusioncharts/-/fusioncharts-3.18.0.tgz#c3fa552f69fa3d396a746fd6f6f813ebecbd5f1e"
+ integrity sha512-PmBNI8RIDHT+xwm3mSquusnLEpKWNDyvyBkMqkMbTuYEHmGVnRmrwQDw8VutIBE+/vyLmfuZ+Ptlg7RiFMrE7w==
dependencies:
"@babel/runtime" "^7.9.2"
- "@fusioncharts/charts" "^3.16.0"
- "@fusioncharts/constructor" "^1.2.0"
- "@fusioncharts/core" "^1.2.0"
- "@fusioncharts/datatable" "^1.2.0"
- "@fusioncharts/features" "^1.2.0"
- "@fusioncharts/fusiontime" "^2.4.0"
- "@fusioncharts/maps" "^3.16.0"
- "@fusioncharts/powercharts" "^3.16.0"
- "@fusioncharts/utils" "^1.2.0"
- "@fusioncharts/widgets" "^3.16.0"
+ "@fusioncharts/accessibility" "^1.5.0"
+ "@fusioncharts/charts" "^3.18.0"
+ "@fusioncharts/constructor" "^1.5.0"
+ "@fusioncharts/core" "^1.5.0"
+ "@fusioncharts/datatable" "^1.5.0"
+ "@fusioncharts/features" "^1.5.0"
+ "@fusioncharts/fusiontime" "^2.6.0"
+ "@fusioncharts/maps" "^3.18.0"
+ "@fusioncharts/powercharts" "^3.18.0"
+ "@fusioncharts/utils" "^1.5.0"
+ "@fusioncharts/widgets" "^3.18.0"
+ mutationobserver-shim "^0.3.5"
+ promise-polyfill "^8.1.3"
+
+fusionmaps@^3.18.0:
+ version "3.18.0"
+ resolved "https://registry.yarnpkg.com/fusionmaps/-/fusionmaps-3.18.0.tgz#46556cd3925f0590eba14dc7ae137b9e7c53265f"
+ integrity sha512-vOOubfGVY3fIf6ub3wVedrIgb9wBZu+VHp/lkL4gWtaYWwBDitu2EdYfQSOLJqHEz75XuvBM+RyZlIouVfEjZA==
+ dependencies:
+ "@babel/runtime" "^7.9.2"
+ "@fusioncharts/accessibility" "^1.5.0"
+ "@fusioncharts/charts" "^3.18.0"
+ "@fusioncharts/constructor" "^1.5.0"
+ "@fusioncharts/core" "^1.5.0"
+ "@fusioncharts/datatable" "^1.5.0"
+ "@fusioncharts/features" "^1.5.0"
+ "@fusioncharts/fusiontime" "^2.6.0"
+ "@fusioncharts/maps" "^3.18.0"
+ "@fusioncharts/powercharts" "^3.18.0"
+ "@fusioncharts/utils" "^1.5.0"
+ "@fusioncharts/widgets" "^3.18.0"
mutationobserver-shim "^0.3.5"
promise-polyfill "^8.1.3"
@@ -10454,8 +10534,9 @@ listr-verbose-renderer@^0.5.0:
figures "^2.0.0"
listr2@^3.8.3:
- version "3.11.0"
- resolved "https://registry.yarnpkg.com/listr2/-/listr2-3.11.0.tgz#9771b02407875aa78e73d6e0ff6541bbec0aaee9"
+ version "3.11.1"
+ resolved "https://registry.yarnpkg.com/listr2/-/listr2-3.11.1.tgz#a9bab5cd5874fd3cb7827118dbea6fedefbcb43f"
+ integrity sha512-ZXQvQfmH9iWLlb4n3hh31yicXDxlzB0pE7MM1zu6kgbVL4ivEsO4H8IPh4E682sC8RjnYO9anose+zT52rrpyg==
dependencies:
cli-truncate "^2.1.0"
colorette "^1.2.2"
@@ -13700,6 +13781,13 @@ react-full-screen@^1.1.0:
dependencies:
fscreen "^1.0.2"
+react-fusioncharts@^3.1.2:
+ version "3.1.2"
+ resolved "https://registry.yarnpkg.com/react-fusioncharts/-/react-fusioncharts-3.1.2.tgz#add3f23e1ca819f1d6f9b58547cfcb85b50c6972"
+ integrity sha512-ilmR7gfUJL5yed0soSHKlBpq2qCPyWiSc7gyFlT2vbPQS8eN6fAWMmLHy8H2kFP/XELItoAMqgUXyrjgK82bXA==
+ dependencies:
+ uuid "^3.2.1"
+
react-google-maps@^9.4.5:
version "9.4.5"
resolved "https://registry.npmjs.org/react-google-maps/-/react-google-maps-9.4.5.tgz"
@@ -16497,7 +16585,7 @@ utils-merge@1.0.1:
version "1.0.1"
resolved "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz"
-uuid@^3.1.0, uuid@^3.3.2, uuid@^3.4.0:
+uuid@^3.1.0, uuid@^3.2.1, uuid@^3.3.2, uuid@^3.4.0:
version "3.4.0"
resolved "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz"