Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions src/components/generator/DataInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,9 @@ const DataInput: React.FC<DataInputProps> = ({
};

const addManualRow = () => {
const base = selectedType === 'map'
? { label: '', lat: '', lng: '', value: '' }
: { label: '', value: '', secondaryValue: '' };
const base: ManualInputRow = selectedType === 'map'
? { id: crypto.randomUUID(), label: '', lat: '', lng: '', value: '' }
: { id: crypto.randomUUID(), label: '', value: '', secondaryValue: '' };

onManualRowsChange([...manualRows, base]);
};
Expand Down Expand Up @@ -263,7 +263,7 @@ const DataInput: React.FC<DataInputProps> = ({
</thead>
<tbody>
{manualRows.map((row, index) => (
<tr key={index} className="border-b border-gray-100 dark:border-[#1F2937]">
<tr key={row.id} className="border-b border-gray-100 dark:border-[#1F2937]">
<td className="py-2 pr-2">
<input
value={row.label}
Expand Down Expand Up @@ -358,10 +358,10 @@ const DataInput: React.FC<DataInputProps> = ({

function getDefaultManualRows(selectedType: string): ManualInputRow[] {
if (selectedType === 'map') {
return [{ label: '', lat: '', lng: '', value: '' }];
return [{ id: crypto.randomUUID(), label: '', lat: '', lng: '', value: '' }];
}

return [{ label: '', value: '', secondaryValue: '' }];
return [{ id: crypto.randomUUID(), label: '', value: '', secondaryValue: '' }];
}

export default DataInput;
9 changes: 8 additions & 1 deletion src/components/generator/previews/D3Preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,12 @@ const D3Preview: React.FC<D3PreviewProps> = ({
const script = document.createElement('script');
script.src = 'https://d3js.org/d3.v7.min.js';

script.onerror = () => {
if (containerRef.current) {
containerRef.current.innerHTML = '<p style="color:red;text-align:center;">Failed to load D3.js library</p>';
}
};

script.onload = () => {
// Re-run the chart creation after D3 loads
if (containerRef.current && typeof (window as any).d3 !== 'undefined') {
Expand Down Expand Up @@ -539,7 +545,8 @@ const D3Preview: React.FC<D3PreviewProps> = ({
}

return () => {
// Clear the container on cleanup
// Don't remove script element — D3 stays on window and subsequent
// renders take the fast path without re-adding the script tag.
if (containerRef.current) {
containerRef.current.innerHTML = '';
}
Expand Down
6 changes: 6 additions & 0 deletions src/components/generator/previews/EChartsPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ const EChartsPreview: React.FC<EChartsPreviewProps> = ({
const script = document.createElement('script');
script.src = 'https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js';

script.onerror = () => {
if (containerRef.current) {
containerRef.current.innerHTML = '<p style="color:red;text-align:center;">Failed to load ECharts library</p>';
}
};

script.onload = () => {
if (typeof (window as any).echarts !== 'undefined') {
const echarts = (window as any).echarts;
Expand Down
6 changes: 6 additions & 0 deletions src/components/generator/previews/HighchartsPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ const HighchartsPreview: React.FC<HighchartsPreviewProps> = ({
const script = document.createElement('script');
script.src = 'https://code.highcharts.com/highcharts.js';

script.onerror = () => {
if (containerRef.current) {
containerRef.current.innerHTML = '<p style="color:red;text-align:center;">Failed to load Highcharts library</p>';
}
};

script.onload = () => {
if (typeof (window as any).Highcharts !== 'undefined') {
const Highcharts = (window as any).Highcharts;
Expand Down
6 changes: 6 additions & 0 deletions src/components/generator/previews/LeafletPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,12 @@ const LeafletPreview: React.FC<LeafletPreviewProps> = ({
link.rel = 'stylesheet';
link.href = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.css';

script.onerror = () => {
if (containerRef.current) {
containerRef.current.innerHTML = '<p style="color:red;text-align:center;">Failed to load Leaflet library</p>';
}
};

script.onload = () => {
if (typeof (window as any).L !== 'undefined') {
const L = (window as any).L;
Expand Down
9 changes: 8 additions & 1 deletion src/components/generator/previews/OpenLayersPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,12 @@ const OpenLayersPreview: React.FC<OpenLayersPreviewProps> = ({
link.rel = 'stylesheet';
link.href = 'https://cdn.jsdelivr.net/npm/ol@7.4.0/ol.css';

script.onerror = () => {
if (containerRef.current) {
containerRef.current.innerHTML = '<p style="color:red;text-align:center;">Failed to load OpenLayers library</p>';
}
};

script.onload = () => {
// Re-run the map creation after OpenLayers loads
if (containerRef.current && typeof (window as any).ol !== 'undefined') {
Expand Down Expand Up @@ -286,7 +292,8 @@ const OpenLayersPreview: React.FC<OpenLayersPreviewProps> = ({
}

return () => {
// Clear the container on cleanup
// Don't remove script/link elements — OpenLayers stays on window and
// subsequent renders take the fast path without re-adding the CSS link.
if (containerRef.current) {
containerRef.current.innerHTML = '';
}
Expand Down
8 changes: 6 additions & 2 deletions src/pages/Generator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ const STATUS_TIMEOUT_MS = 2500;

const getDefaultManualRows = (selectedType: string): ManualInputRow[] => {
if (selectedType === 'map') {
return [{ label: '', lat: '', lng: '', value: '' }];
return [{ id: crypto.randomUUID(), label: '', lat: '', lng: '', value: '' }];
}

return [{ label: '', value: '', secondaryValue: '' }];
return [{ id: crypto.randomUUID(), label: '', value: '', secondaryValue: '' }];
};

const toNumber = (value: string | number | undefined): number | null => {
Expand Down Expand Up @@ -109,6 +109,10 @@ const normalizeMapRows = (rows: TabularRow[]): GeoPoint[] => {
return null;
}

if (lat < -90 || lat > 90 || lng < -180 || lng > 180) {
return null;
}

return {
lat,
lng,
Expand Down
1 change: 1 addition & 0 deletions src/types/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export interface GeoPoint {
}

export interface ManualInputRow {
id: string;
label: string;
value: string;
secondaryValue?: string;
Expand Down