getChartData.ts 2.2 KB
export interface ValueItem {
  value: number;
  itemStyle?: {
    color: string;
  };
}

export interface ChartData {
  categories: string[];
  values: Array<number | ValueItem>;
}

export interface ChartComponentProps {
  data: {
    categories: string[];
    values: Array<number | ValueItem>;
  };
}

export function extractDataFromText(text: string): ChartComponentProps | null {
  const startMarkers = ["```javascript", "```json", "```typescript"];
  let dataStartIndex = -1;
  let markerLength = 0;

  for (const marker of startMarkers) {
    const index = text.indexOf(marker);
    if (index !== -1) {
      dataStartIndex = index;
      markerLength = marker.length;
      break;
    }
  }

  let parsedData: any = null;

  if (dataStartIndex !== -1) {
    const dataEndIndex = text.indexOf("```", dataStartIndex + markerLength);
    if (dataEndIndex !== -1) {
      const dataBlock = text
        .slice(dataStartIndex + markerLength, dataEndIndex)
        .trim()
        .replace(/'/g, '"')
        .replace(/(\w+)(?=\s*:)/g, '"$1"');

      try {
        parsedData = JSON.parse(dataBlock);
      } catch (error) {
        return null;
      }
    }
  }

  if (!parsedData) {
    try {
      const potentialData: any = JSON.parse(text);
      if (
        potentialData &&
        Array.isArray(potentialData.categories) &&
        potentialData.categories.every((c: any) => typeof c === "string") &&
        Array.isArray(potentialData.values) &&
        potentialData.values.every(
          (v: any) =>
            typeof v === "number" ||
            (typeof v?.value === "number" &&
              (v.itemStyle === undefined ||
                typeof v.itemStyle?.color === "string")),
        )
      ) {
        parsedData = potentialData;
      }
    } catch (error) {
      return null;
    }
  }

  if (
    parsedData &&
    Array.isArray(parsedData.categories) &&
    Array.isArray(parsedData.values) &&
    parsedData.values.every(
      (v: any) =>
        typeof v === "number" ||
        (typeof v?.value === "number" &&
          (v.itemStyle === undefined ||
            typeof v.itemStyle?.color === "string")),
    )
  ) {
    return { data: parsedData as ChartData };
  }

  return null;
}