VizPortVisualization Studio
Local-first
DATA TO PORTABLE VISUALIZATION

데이터를 넣으면, 프로젝트에 바로 옮길 수 있는 그래프가 됩니다.

데이터 구조를 로컬에서 읽고 적합한 표현을 추천합니다. 결과는 미리 확인한 뒤 React 코드, LLM 프롬프트 또는 명세로 가져가세요.

처음이라면
샘플로 30초 체험

샘플은 이미 분석되어 있어요. 내 데이터는 STEP 1에 넣고 변경사항을 분석하세요.

  1. 1추천 그래프 선택
  2. 2미리보기 확인
  3. 3React 코드 복사
샘플 추천 보기
STEP 3

미리보기

로컬 데이터 Canvas 12 points
그래프 엔진을 준비하는 중…
monthproductrevenueprofitcustomers
2025-01-01Atlas12400028400820
2025-02-01Atlas13900032600910
2025-03-01Atlas15100035800980
STEP 4

프로젝트로 가져가기

npm install echarts
import { useEffect, useRef } from "react";
import * as echarts from "echarts";

type ChartRow = Record<string, string | number | boolean | null>;

interface VizPortChartProps {
  data: ChartRow[];
  height?: number;
}

export function VizPortChart({ data, height = 360 }: VizPortChartProps) {
  const containerRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (!containerRef.current) return;
    const chart = echarts.init(containerRef.current);
    const option: echarts.EChartsOption = {
    dataset: { source: data },
    tooltip: { trigger: "axis" },
    grid: { left: 24, right: 24, top: 64, bottom: 28 },
    xAxis: { type: "category" },
    yAxis: { type: "value" },
    series: [{
      type: "line",
      encode: { x: "month", y: "revenue" },
      smooth: true
    }],
  };

    chart.setOption({
      title: { text: "revenue 추이" },
      color: ["#3157d5", "#7c5ce7", "#15a38b"],
      ...option,
    });

    const container = containerRef.current;
    let frame = 0;
    let previousWidth = Math.round(container.clientWidth);
    let previousHeight = Math.round(container.clientHeight);
    const observer = new ResizeObserver(([entry]) => {
      const width = Math.round(entry.contentRect.width);
      const height = Math.round(entry.contentRect.height);
      if (!width || !height || (width === previousWidth && height === previousHeight)) return;
      previousWidth = width;
      previousHeight = height;
      cancelAnimationFrame(frame);
      frame = requestAnimationFrame(() => chart.resize({ width, height }));
    });
    observer.observe(container);
    return () => {
      observer.disconnect();
      cancelAnimationFrame(frame);
      chart.dispose();
    };
  }, [data]);

  return <div ref={containerRef} style={{ width: "100%", height }} />;
}