How to Pass Dynamic Variables to Custom Widgets in Appsmith?
Like mentioned earlier. This is the custom widget code:
```
import React, { useEffect, useRef, useState } from 'https://cdn.jsdelivr.net/npm/react@18.2.0/+esm'
import reactDom from 'https://cdn.jsdelivr.net/npm/react-dom@18.2.0/+esm'
import { Button, Card } from 'https://cdn.jsdelivr.net/npm/antd@5.11.1/+esm'
import Markdown from 'https://cdn.jsdelivr.net/npm/react-markdown@9.0.1/+esm';
import * as d3 from 'https://cdn.jsdelivr.net/npm/d3@7.9.0/+esm';
const BubbleMap = () => {
const [indiaGeoData, setIndiaGeoData] = useState(null);
// Fixed dimensions
const width = 740;
const height = 800;
// Sample data for Indian cities
const cities = appsmith.model.dataPins;
useEffect(() => {
// Fetch India GeoJSON data
fetch(appsmith.model.geoMap)
.then(response => response.json())
.then(data => {
setIndiaGeoData(data);
})
.catch(error => console.error('Error loading map data:', error));
}, []);
// Create the projection
const projection = d3.geoMercator()
.center(appsmith.model.geoMapCenter) // Adjusted center for India
.scale(1200)
.translate([width / 2, height / 2]);
// Create path generator
const pathGenerator = d3.geoPath().projection(projection);
// Create scales
const maxValue = 100;
const sizeScale = d3.scaleSqrt()
.domain([0, maxValue])
.range([5, 10]);
const colorScale = d3.scaleSequential().range([" #ff0000 ", "#00ff00"])
.domain([0, maxValue]);
// Project coordinates
const projectedCities = cities.map(city => {
const position = projection([city.lon, city.lat]);
return {
...city,
x: position[0],
y: position[1]
};
});
return (
<div style={{ border: '1px solid #ccc', margin: '20px', padding: '10px' }}>
<svg width={width} height={height} style={{ background: '#f0f0f0' }}>
{/* Background */}
<rect width={width} height={height} fill="#f8fafc" />
{/* India Map */}
{indiaGeoData && (
<g className="states">
{indiaGeoData.features.map((feature, i) => (
<path
key={i}
d={pathGenerator(feature)}
fill="#e5e7eb"
stroke="#cbd5e1"
strokeWidth={0.5}
/>
))}
</g>
)}
{/* Cities */}
{projectedCities.map((city, i) => (
<g key={i}>
{/* Bubble */}
<circle
cx={city.x}
cy={city.y}
r={sizeScale(city.value)}
fill={colorScale(city.value)}
opacity={0.7}
stroke="#fff"
strokeWidth={1}
/>
{/* City name */}
<text
x={city.x}
y={city.y - sizeScale(city.value) - 5}
textAnchor="middle"
fontSize="12px"
fill="#333"
fontWeight="bold"
>
{city.name}
</text>
{/* Value */}
<text
x={city.x}
y={city.y + sizeScale(city.value) + 15}
textAnchor="middle"
fontSize="10px"
fill="#666"
>
{city.value}%
</text>
</g>
))}
{/* Legend */}
<g transform={`translate(${width - 100}, ${height - 120})`}>
<text y={-10} fontSize="12px" fill="#333" fontWeight="bold">
Availability (%)
</text>
{[0, 25, 50, 75, 100].map((value, i) => (
<g key={i} transform={`translate(0,${i * 25})`}>
<circle
r={sizeScale(value)}
fill={colorScale(value)}
opacity={0.7}
stroke="#fff"
strokeWidth={1}
/>
<text x={35} y={5} fontSize="10px" fill="#666">
{value}%
</text>
</g>
))}
</g>
</svg>
</div>
);
};
function App() {
const [currentIndex, setCurrentIndex] = React.useState(0);
const handleNext = () => {
setCurrentIndex((prevIndex) => (prevIndex + 1) % appsmith.model.tips.length);
};
const handleReset = () => {
setCurrentIndex(0);
appsmith.triggerEvent("onResetClick");
};
console.log(1)
return (
<Card className="app">
<BubbleMap />
</Card>
);
}
appsmith.onReady(() => {
/*
* This handler function will get called when parent application is ready.
* Initialize your component here
* more info - https://docs.appsmith.com/reference/widgets/custom#onready
*/
reactDom.render(<App />, document.getElementById("root"));
});
```
Now, in the above case, I have external query which fetch the data for the data pins to be shown to the users. The variable name being dataPins. So, whenever the required filters are selected, the query is run and I want to the data to pass into the graph to plot it accordingly.
I couldn't find any way to do this in the custom widget. Can someone please help? Or should I use a different way to do this?