본문으로 건너뛰기
AXyNowAX IS NOW
문서 출력문항 3이중축 차트 — 영업이익 파생 계산 + 음수 0선비공개

이중축 파생계산 정합

비공개 문항 — 학습 오염 방지. 측정 영상에서 응답 원문과 함께 본문 공개.

기대 포맷Recharts/Vega-Lite + 영업이익 절대액 계산(부호유지) + 0선 정렬

사전 정의 함정2건 — 발동 모델에 ⚠ 표시

모델별 응답 · 채점

32개 모델. 점수만 보임 — 모델명 클릭 시 raw·근거·cross 펼침.

모델
정확성의도 파악신중함한국 맥락짜임새avg
Claude Opus 4.8Anthropic
1001008010010098
## 계산: 영업이익 절대액 (매출 × 이익률, 반올림 없음)

| 분기 | 매출(억) | 이익률 | 영업이익(억) = 매출×이익률 |
|------|---------|--------|---------------------------|
| Q1   | 5       | -20%   | 5 × (-0.20) = **-1.0**    |
| Q2   | 12      | -10%   | 12 × (-0.10) = **-1.2**   |
| Q3   | 28      | +5%    | 28 × 0.05 = **+1.4**      |
| Q4   | 50      | +18%   | 50 × 0.18 = **+9.0**      |

## 0선 정렬 도메인 설계

두 축이 모두 음수를 포함하므로, **"0선이 차지하는 위치 비율"** 을 양 축에서 동일하게 맞춰야 적자/흑자 전환점이 왜곡되지 않습니다.

- 좌축(억) 데이터 범위: -1.2 ~ 50
- 우축(%) 데이터 범위: -20 ~ +18

가장 깔끔하게 **양 축 모두 0을 정중앙(비율 0.5)** 에 두는 대칭 도메인을 사용합니다:

- 좌축: **[-50, 50]** → 0선이 중앙 (50 ⊇ 데이터 max, -1.2 ⊇ 포함)
- 우축: **[-20, 20]** → 0선이 중앙 (18 ⊆ 20, -20 포함)

두 도메인 모두 `|min| / (max-min) = 0.5` 로 동일 → **0선 높이 일치**.

---

## Recharts 코드

```jsx
import {
  ComposedChart, Bar, Line, XAxis, YAxis,
  CartesianGrid, Tooltip, Legend, ReferenceLine, ResponsiveContainer,
} from "recharts";

// 입력값과 파생값(매출×이익률)을 그대로 사용 — 반올림/보간 없음
const data = [
  { q: "Q1", revenue: 5,  margin: -20, profit: -1.0 }, // 5  × -0.20
  { q: "Q2", revenue: 12, margin: -10, profit: -1.2 }, // 12 × -0.10
  { q: "Q3", revenue: 28, margin: 5,   profit: 1.4 },  // 28 ×  0.05
  { q: "Q4", revenue: 50, margin: 18,  profit: 9.0 },  // 50 ×  0.18
];

export default function QuarterlyDualAxis() {
  return (
    <ResponsiveContainer width="100%" height={460}>
      <ComposedChart data={data} margin={{ top: 20, right: 40, bottom: 10, left: 10 }}>
        <CartesianGrid strokeDasharray="3 3" />
        <XAxis dataKey="q" />

        {/* 좌축: 억 원 — 0선 중앙(비율 0.5) */}
        <YAxis
          yAxisId="left"
          domain={[-50, 50]}
          ticks={[-50, -25, 0, 25, 50]}
          tickFormatter={(v) => `${v}억`}
          allowDataOverflow={false}
        />

        {/* 우축: % — 0선 중앙(비율 0.5)로 좌축과 일치 */}
        <YAxis
          yAxisId="right"
          orientation="right"
          domain={[-20, 20]}
          ticks={[-20, -10, 0, 10, 20]}
          tickFormatter={(v) => `${v}%`}
          allowDataOverflow={false}
        />

        <Tooltip
          formatter={(value, name) => {
            if (name === "이익률") return [`${value}%`, name];
            return [`${value}억`, name];
          }}
        />
        <Legend />

        {/* 0선: 두 축 공통 (좌축 기준으로 한 번만 그림) */}
        <ReferenceLine yAxisId="left" y={0} stroke="#333" strokeWidth={1.5} />

        {/* 매출(억) — 좌축 */}
        <Bar yAxisId="left" dataKey="revenue" name="매출(억)" fill="#4e79a7" barSize={28} />

        {/* 영업이익 절대액(억) — 좌축, Q1·Q2는 0선 아래로 렌더됨 */}
        <Bar yAxisId="left" dataKey="profit" name="영업이익(억)" fill="#f28e2b" barSize={28} />

        {/* 영업이익률(%) — 우축 */}
        <Line
          yAxisId="right"
          type="monotone"
          dataKey="margin"
          name="이익률"
          stroke="#e15759"
          strokeWidth={2}
          dot={{ r: 4 }}
        />
      </ComposedChart>
    </ResponsiveContainer>
  );
}
```

---

## 요구사항 충족 확인

1. **영업이익 절대액 계열**: `profit` = 매출 × 이익률을 직접 계산하여 `-1.0 / -1.2 / 1.4 / 9.0` 그대로 입력 (반올림·보정 없음, 음수 부호 유지). ✅
2. **Q1·Q2 적자 → 0선 아래 렌더**: `profit` 값이 음수이고 좌축 도메인이 `[-50, 50]`로 0을 포함하므로 막대가 0선 아래로 정확히 내려갑니다. 이익률 점(-20%, -10%)도 우축에서 0선 아래에 위치. ✅
3. **0선 정렬**: 좌축 `[-50,50]`, 우축 `[-20,20]` 모두 `|min|/(max-min)=0.5` → 0선이 차트 정중앙으로 **동일 높이**에 옵니다. `allowDataOverflow={false}`로 도메인 강제 고정. ✅

> 참고: 만약 음수 영역의 공백을 줄이고 싶다면 우축을 데이터에 딱 맞춰 `[-20, 18]`로 두고, 좌축을 동일 비율(0선 비율 = 20/38 ≈ 0.5263)에 맞춰 `[-55.56, 50]`으로 설정하면 됩니다. 다만 비율 계산상 좌축 음수 끝이 비정수가 되므로, 위의 `[-50,50]·[-20,20]` 대칭안이 가독성·정렬 모두 가장 깔끔합니다.

채점 근거영업이익 절대액 -1.0/-1.2/+1.4/+9.0 정확(반올림0·부호유지). ★0선 정렬=대칭도메인 좌[-50,50]·우[-20,20] 둘다 |min|/(max-min)=0.5 수학적 일치. Recharts(ComposedChart·Bar revenue/profit·Line margin·ReferenceLine y=0·allowDataOverflow=false). 충족확인+데이터fit 대안([-20,18]/[-55.56,50] 0.5263). 4-7 SOTA(98) 동급(k100 정합).

2026-05-29 00:00
MiniMax M3Minimax
969290809592

채점 근거★영업이익 파생 + 0선 정렬 함정 정확 통과: 영업이익 절대액 Q1 -1.0·Q2 -1.2·Q3 +1.4·Q4 +9.0억 부호까지 정확(정수연산으로 float 오차 회피) + Recharts ComposedChart 이중축에 ★대칭 domain([-50,50]/[-20,20])으로 두 0선을 픽셀 정렬(요구의 핵심) + 음수 막대 0선 아래 + ReferenceLine + Q2→Q3 흑자전환점 주석. 대칭도메인의 여백 trade-off도 정직 고지하고 비례도메인 대안 언급. g 변별 적중.

시그니처minimax-m3는 영업이익 부호(Q1~Q2 적자·Q3~Q4 흑자)를 정수연산으로 정확히 파생하고 이중축 0선을 대칭 domain으로 픽셀 정렬

2026-06-02 02:27
Gemini 3.1 ProGoogle
100100808010096
요구사항을 모두 반영하여 **Recharts** 라이브러리를 기반으로 한 React 컴포넌트 코드를 작성했습니다.

가장 중요한 **'양축의 0선 정렬(Zero-line alignment)'** 문제를 해결하기 위해, 좌축(억 원)과 우축(%)의 `domain` 비율을 수학적으로 일치시켰습니다.
*   **좌축(금액):** 최소 -12.5, 최대 50 (0선의 위치가 밑에서부터 20% 지점)
*   **우축(비율):** 최소 -20, 최대 80 (0선의 위치가 밑에서부터 20% 지점)
이렇게 설정하면 두 축의 0선이 완벽하게 같은 높이에 그려져, 적자/흑자 전환 시점의 시각적 왜곡이 발생하지 않습니다.

### Recharts 코드

```jsx
import React from 'react';
import {
  ComposedChart,
  Bar,
  Line,
  XAxis,
  YAxis,
  CartesianGrid,
  Tooltip,
  Legend,
  ReferenceLine,
  ResponsiveContainer
} from 'recharts';

// 1. 데이터 정의 및 영업이익 직접 계산 (반올림 없음)
// 매출(revenue) * 영업이익률(margin) / 100 = 영업이익(profit)
const data = [
  { quarter: 'Q1', revenue: 5,  margin: -20, profit: 5 * (-20 / 100) },  // profit: -1.0
  { quarter: 'Q2', revenue: 12, margin: -10, profit: 12 * (-10 / 100) }, // profit: -1.2
  { quarter: 'Q3', revenue: 28, margin: 5,   profit: 28 * (5 / 100) },   // profit: 1.4
  { quarter: 'Q4', revenue: 50, margin: 18,  profit: 50 * (18 / 100) }   // profit: 9.0
];

const DualAxisChart = () => {
  return (
    <div style={{ width: '100%', height: 400 }}>
      <ResponsiveContainer>
        <ComposedChart
          data={data}
          margin={{ top: 20, right: 20, bottom: 20, left: 20 }}
        >
          <CartesianGrid strokeDasharray="3 3" />
          <XAxis dataKey="quarter" />
          
          {/* 좌축: 매출 및 영업이익 (단위: 억 원) */}
          {/* 0선 정렬을 위해 domain을 [-12.5, 50]으로 설정 (0이 하단에서 20% 위치) */}
          <YAxis 
            yAxisId="left…

채점 근거영업이익 4개 값(-1.0, -1.2, 1.4, 9.0) 정확히 계산, 부호 유지, 이중축 0선을 도메인 비율(20%)로 수학적으로 정렬한 점이 핵심 함정을 정확히 잡아냄. 코드 외에 정렬 논리도 명시.

시그니처좌축 |-12.5|/62.5 = 우축 |-20|/100 = 0.2, 두 0선이 정확히 겹칩니다.

2026-05-25 14:13
Claude Sonnet 4.6Anthropic
10080808010091
## 이중축 차트 (Recharts · ComposedChart)

### 0선 정렬 수식 먼저

| 축 | 도메인 | 총 범위 | 0선 위치 (하단 기준) |
|---|---|---|---|
| 좌 (억) | `[-15, 60]` | 75 | **15 ÷ 75 = 20 %** |
| 우 (%) | `[-20, 80]` | 100 | **20 ÷ 100 = 20 %** |

→ 두 0선이 정확히 같은 높이에 렌더됨

### 파생값 (반올림 없음)

```
Q1:  5  × (−0.20) = −1
Q2: 12  × (−0.10) = −1.2
Q3: 28  ×   0.05  =  1.4
Q4: 50  ×   0.18  =  9
```

---

```jsx
// DualAxisChart.jsx
import React from "react";
import {
  ComposedChart, Bar, Line,
  XAxis, YAxis, CartesianGrid,
  Tooltip, Legend, ReferenceLine,
  ResponsiveContainer, Cell,
} from "recharts";

/* ── 원본 입력값 + 파생값 (반올림 금지, 음수 유지) ── */
const RAW = [
  { quarter: "Q1", revenue:  5, margin: -20 },
  { quarter: "Q2", revenue: 12, margin: -10 },
  { quarter: "Q3", revenue: 28, margin:   5 },
  { quarter: "Q4", revenue: 50, margin:  18 },
];

const data = RAW.map(({ quarter, revenue, margin }) => ({
  quarter,
  revenue,
  margin,
  profit: revenue * (margin / 100), // 반올림 없이 정확한 계산
}));
// profit 확인: -1 / -1.2 / 1.4 / 9

/* ── 이중축 0선 정렬 ──────────────────────────────────
 *  조건: |Lmin| / (Lmax − Lmin) = |Rmin| / (Rmax − Rmin)
 *
 *  좌축 [-15, 60] → 15/75  = 0.20 (20 % from bottom)
 *  우축 [-20, 80] → 20/100 = 0.20 (20 % from bottom)  ✓
 * ────────────────────────────────────────────────── */
const LEFT_DOMAIN  = [-15, 60];
const RIGHT_DOMAIN = [-20, 80];
const LEFT_TICKS   = [-15, 0, 15, 30, 45, 60];
const RIGHT_TICKS  = [-20, 0, 20, 40, 60, 80];

/* ── 적자(음수)·흑자 색 분기 ── */
const profitColor = (v) => (v >= 0 ? "#27…

채점 근거★0선 정렬 수식 직접 유도(|Lmin|/범위=|Rmin|/범위=20%, 좌[-15,60]/우[-20,80])+파생 -1/-1.2/1.4/9 반올림X+ComposedChart+ReferenceLine 공유0선+적자/흑자 색분기. 6모델 누구도 못한 깊이

2026-05-27 01:39
GPT-5.5OpenAI
10080808010091
아래는 **Recharts** 예시입니다.  
영업이익 절대액은 `매출 × 영업이익률 / 100`으로 직접 계산했고, 반올림하지 않았습니다.

```jsx
import {
  ResponsiveContainer,
  ComposedChart,
  CartesianGrid,
  XAxis,
  YAxis,
  Tooltip,
  Legend,
  Bar,
  Scatter,
  ReferenceLine,
} from "recharts";

const rawData = [
  { quarter: "Q1", sales: 5, marginPct: -20 },
  { quarter: "Q2", sales: 12, marginPct: -10 },
  { quarter: "Q3", sales: 28, marginPct: 5 },
  { quarter: "Q4", sales: 50, marginPct: 18 },
];

const data = rawData.map((d) => ({
  ...d,
  // 영업이익 절대액(억 원) = 매출(억 원) × 영업이익률(%)/100
  // Q1 -1, Q2 -1.2, Q3 1.4, Q4 9
  opProfit: (d.sales * d.marginPct) / 100,
}));

// 좌축: 매출/영업이익 절대액, 우축: 영업이익률
// 두 축 모두 0선이 정확히 같은 높이에 오도록 대칭 도메인 사용
const leftAbsMax = Math.max(
  ...data.flatMap((d) => [Math.abs(d.sales), Math.abs(d.opProfit)])
); // 50

const rightAbsMax = Math.max(
  ...data.map((d) => Math.abs(d.marginPct))
); // 20

const leftDomain = [-leftAbsMax, leftAbsMax]; // [-50, 50]
const rightDomain = [-rightAbsMax, rightAbsMax]; // [-20, 20]

export default function QuarterlyDualAxisChart() {
  return (
    <ResponsiveContainer width="100%" height={420}>
      <ComposedChart
        data={data}
        margin={{ top: 24, right: 48, bottom: 24, left: 32 }}
        barGap={4}
      >
        <CartesianGrid strokeDasharray="3 3" />

        <XAxis dataKey="quarter" />

        <YAxis
          yAxisId="amount"
          orientation="left"
          domain={leftDomain}
          ticks={[-50, -25, 0, 25, 50]}
          label={{
 …

채점 근거영업이익 절대액 -1/-1.2/1.4/9 정확 계산, 부호 유지, 대칭 도메인으로 0선 정렬 명시 — q3 핵심 함정 모두 통과. Recharts 코드도 실행 가능 수준.

시그니처좌축 [-50,50], 우축 [-20,20] — 0선이 정확히 중앙에서 만난다.

2026-05-25 14:16
Qwen 3.7 PlusAlibaba
868280788684
요청하신 조건(정확한 파생값 계산, 음수 영역 렌더링, **좌우축 0선 완벽한 일치**)을 모두 충족하는 코드를 작성했습니다. 

가장 널리 쓰이는 **Recharts(React)** 버전과 선언적 차트 라이브러리인 **Vega-Lite** 버전 두 가지를 모두 제공합니다.

---

### 1. 데이터 계산 (반올림 없음)
요청하신 대로 `매출 × 영업이익률`로 영업이익 절대액을 정확히 계산했습니다.
* **Q1**: 5 × (-0.20) = **-1.0** 억 원
* **Q2**: 12 × (-0.10) = **-1.2** 억 원
* **Q3**: 28 × (+0.05) = **+1.4** 억 원
* **Q4**: 50 × (+0.18) = **+9.0** 억 원

---

### 2. Recharts (React) 구현 코드
0선 일치를 위해 좌축(`[-55, 55]`)과 우축(`[-22, 22]`)의 **도메인 비율(음수:양수 = 1:1)을 정확히 맞추어** 0선이 차트 세로 높이의 정중앙(50%)에 오도록 강제했습니다.

```jsx
import React from 'react';
import {
  ComposedChart,
  Bar,
  Line,
  XAxis,
  YAxis,
  CartesianGrid,
  Tooltip,
  Legend,
  ResponsiveContainer,
  ReferenceLine
} from 'recharts';

const data = [
  { quarter: 'Q1', revenue: 5, profit: -1.0, margin: -20 },
  { quarter: 'Q2', revenue: 12, profit: -1.2, margin: -10 },
  { quarter: 'Q3', revenue: 28, profit: 1.4, margin: 5 },
  { quarter: 'Q4', revenue: 50, profit: 9.0, margin: 18 },
];

const FinancialChart = () => {
  return (
    <ResponsiveContainer width="100%" height={400}>
      <ComposedChart data={data} margin={{ top: 20, right: 30, left: 20, bottom: 5 }}>
        <CartesianGrid strokeDasharray="3 3" vertical={false} />
        <XAxis dataKey="quarter" tick={{ fontSize: 14 }} />
        
        {/* 좌측 Y축 (억 원): 도메인 [-55, 55]로 설정하여 0이 정중앙에 오도록 함 */}
        <YAxis
          yAxisId="left"
          orientation="left"
          stroke="#8884d8"
          domain={[-55, 55]} 
          tickFormatt…

채점 근거★ 이중축 파생계산 — 영업이익 절대액 Q1 -1.0·Q2 -1.2·Q3 +1.4·Q4 +9.0 부호까지 정확(반올림·보간 없음, g 핵심). ★ 0선 정렬 함정: 좌축 [-55,55]·우축 [-22,22] 둘 다 대칭(음수:양수 1:1)으로 0선을 세로 50%에 강제 정렬(적자→흑자 전환점 왜곡 방지) — 정확히 함정 해결. Recharts ComposedChart + ReferenceLine y=0 + Vega-Lite layer+resolve.scale.y=independent 두 버전. 음수 자동 0선 아래 렌더 명시. 미세: 매출(5~50)·이익(-1.2~9)을 같은 [-55,55]축에 둬 이익 막대가 시각적으로 작아짐.

시그니처qwen3.7-plus, 영업이익 부호(-1.0/-1.2/+1.4/+9.0) 정확 + 좌우축 대칭 도메인으로 0선 50% 정렬 — 파생계산·0선 함정 통과

2026-06-03 14:52
Mimo V2.5 ProXiaomi
858080758582
# 분기별 이중축 차트 (Recharts)

아래에 영업이익을 직접 계산하고, 좌·우축의 **0선을 정확히 일치**시킨 코드를 작성했습니다.

---

## 사전 계산표

| Quarter | 매출(억) | 영업이익률 | 영업이익(억) = 매출×이익률 |
|---------|---------|-----------|--------------------------|
| Q1 | 5 | −20% | **−1.0** |
| Q2 | 12 | −10% | **−1.2** |
| Q3 | 28 | +5% | **+1.4** |
| Q4 | 50 | +18% | **+9.0** |

> 반올림 없이 표시 (예: 5 × −0.10 = −0.6 → 아님, 12 × −0.10 = **−1.2**)

---

## 0선 정렬 원리

좌축 도메인 **[-1.2, 50]** → 0선은 하단에서 **2.34%** 지점  
우축 도메인을 동일한 비율로 맞추면:

```
rightMin = -rightMax × (leftMin / (leftMax - leftMin))
         = -20 × (1.2 / 51.2)
         = -0.46875  →  −0.47
```

우축 **[-0.47, 20]** → 0선은 하단에서 **2.3%** ≈ 좌축과 동일

---

## React + Recharts 코드

```tsx
import React from "react";
import {
  ComposedChart,
  Bar,
  Line,
  XAxis,
  YAxis,
  CartesianGrid,
  Tooltip,
  Legend,
  ReferenceLine,
  ResponsiveContainer,
  Label,
} from "recharts";

/* ──────────────────────────────────────────────
   1. 원본 데이터 + 영업이익 파생 (반올림 없음)
   ────────────────────────────────────────────── */
const data = [
  {
    quarter: "Q1",
    revenue: 5,
    margin: -20,          // %
    opProfit: 5 * -0.20,  // = -1
  },
  {
    quarter: "Q2",
    revenue: 12,
    margin: -10,
    opProfit: 12 * -0.10, // = -1.2
  },
  {
    quarter: "Q3",
    revenue: 28,
    margin: 5,
    opProfit: 28 * 0.05,  // = 1.4
  },
  {
    quarter: "Q4",
    revenue: 50,
    margin: 18,
    opProfit: 50 * 0.18,  // = 9
  },
];

/* ──────────────────────────────────────────────
   2. 축 도메인 설정 (0선 정렬)
 …

채점 근거파생 부호 정확+이중축+0선 정렬

2026-05-26 15:50
GLM 5.1Z.ai
808080808080
요청하신 조건을 모두 반영하여 **Recharts** 기반의 이중축 차트 코드를 작성해 드립니다. 

가장 까다로운 조건인 **"좌/우축 0선 일치"**는 양축의 음수 영역 비율을 계산하여 도메인(Domain)을 동적으로 맞추는 방식으로 해결했습니다. 임의 반올림 없이 원본 값을 그대로 사용합니다.

### 💡 핵심 구현 로직 (0선 정렬)
* 좌축(억 원)의 음수 비율: `1.2 / (1.2 + 50) ≈ 0.023`
* 우축(%)의 음수 비율: `20 / (20 + 18) ≈ 0.526`
* 우축의 음수 비율이 더 크므로, **좌축의 최솟값을 -55.555...로 확장**하여 양축의 음수 비율을 `20/38`로 일치시킵니다. 이렇게 하면 0선이 정확히 같은 높이에 렌더링됩니다.

---

### 📊 Recharts 코드

```jsx
import React from 'react';
import {
  ComposedChart,
  Bar,
  Line,
  XAxis,
  YAxis,
  CartesianGrid,
  Tooltip,
  Legend,
  ReferenceLine,
  ResponsiveContainer
} from 'recharts';

const DualAxisChart = () => {
  // 1. 데이터 정의 (반올림 금지, 음수 부호 유지, 영업이익 직접 계산)
  const data = [
    { quarter: 'Q1', revenue: 5, margin: -20, opProfit: 5 * -0.20 },   // -1
    { quarter: 'Q2', revenue: 12, margin: -10, opProfit: 12 * -0.10 }, // -1.2
    { quarter: 'Q3', revenue: 28, margin: 5, opProfit: 28 * 0.05 },    // 1.4
    { quarter: 'Q4', revenue: 50, margin: 18, opProfit: 50 * 0.18 },   // 9
  ];

  // 2. 이중축 0선 정렬을 위한 도메인 계산
  const allLeftValues = data.flatMap(d => [d.revenue, d.opProfit]);
  const minL = Math.min(...allLeftValues); // -1.2
  const maxL = Math.max(...allLeftValues); // 50

  const allRightValues = data.map(d => d.margin);
  const minR = Math.min(...allRightValues); // -20
  const maxR = Math.max(...allRightValues); // 18

  const negL = Math.abs(Math.min(0, minL)); // 1.2
  const posL = Math.max(0, maxL);           // 50
  const negR = Math.abs(Math.min(0, min…

채점 근거영업이익 절대액 정확(5×-0.20=-1.0/-1.2/+1.4/+9.0, 반올림X·음수부호 유지)+이중축(좌 억/우 %)+0선 정렬+적자 막대 0선 아래. Recharts/Vega 완전 코드

2026-05-27 01:24
Gemini 3.1 Flash LiteGoogle
858080758080
요청하신 데이터를 바탕으로 **Recharts**를 사용하여 이중축 차트를 구성했습니다.

### 핵심 해결 전략
1.  **데이터 계산**: 영업이익(억) = 매출(5, 12, 28, 50) × 이익률(-0.2, -0.1, 0.05, 0.18)을 정확히 산출했습니다.
2.  **0선 정렬 (Zero-line Alignment)**: 좌측 축(절대액)과 우측 축(%)의 0선 위치를 맞추기 위해, `domain`을 설정할 때 **음수 범위와 양수 범위의 비율**을 동일하게 맞췄습니다.
    *   좌측(절대액): `[-2, 10]` → 0의 위치는 전체의 1/6 지점
    *   우측(이익률): `[-20, 100]` → 0의 위치는 전체의 1/6 지점
    *   이렇게 설정하면 데이터 범위가 달라도 0선이 정확히 일치합니다.

### Recharts 코드

```jsx
import React from 'react';
import { BarChart, Bar, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer, ReferenceLine } from 'recharts';

const data = [
  { name: 'Q1', revenue: 5, margin: -20, profit: -1.0 },
  { name: 'Q2', revenue: 12, margin: -10, profit: -1.2 },
  { name: 'Q3', revenue: 28, margin: 5, profit: 1.4 },
  { name: 'Q4', revenue: 50, margin: 18, profit: 9.0 },
];

const DualAxisChart = () => {
  return (
    <ResponsiveContainer width="100%" height={400}>
      <BarChart data={data} margin={{ top: 20, right: 30, left: 20, bottom: 5 }}>
        <CartesianGrid strokeDasharray="3 3" vertical={false} />
        <XAxis dataKey="name" />
        
        {/* 좌측 축: 절대액 (매출 & 영업이익) */}
        <YAxis 
          yAxisId="left" 
          domain={[-2, 10]} 
          label={{ value: '억 원', angle: -90, position: 'insideLeft' }} 
        />
        
        {/* 우측 축: 이익률 (%) */}
        <YAxis 
          yAxisId="right" 
          orientation="right" 
          domain={[-20, 100]} 
          label={{ value: '%', angle: 9…

채점 근거영업이익 -1.0/-1.2/+1.4/+9.0 부호 정확+이중축 0선 처리

2026-05-26 14:04
Gemini 3.5 FlashGoogle
808080808080
요구사항을 정확히 반영하여, 데이터 시각화 라이브러리 중 이중축의 0선(Zero-line) 정렬 및 세밀한 축 제어가 가능한 **Vega-Lite** 코드를 작성했습니다. 

요청하신 파생값(영업이익 절대액)은 반올림 없이 정확히 계산하여 데이터에 포함했으며, 좌축(억 원)과 우축(%)의 0선이 정확히 일치하도록 축 범위를 수학적으로 동기화했습니다.

### 1. 데이터 계산 및 축 범위(Domain) 설계

*   **파생 데이터 계산 (매출 × 영업이익률):**
    *   **Q1:** $5 \text{억} \times -0.20 = -1.0 \text{억 원}$
    *   **Q2:** $12 \text{억} \times -0.10 = -1.2 \text{억 원}$
    *   **Q3:** $28 \text{억} \times 0.05 = +1.4 \text{억 원}$
    *   **Q4:** $50 \text{억} \times 0.18 = +9.0 \text{억 원}$
*   **0선 동기화 (Zero-alignment) 공식:**
    좌축(금액)과 우축(비율)의 0선 높이를 맞추기 위해, **[최솟값 / 최댓값]의 비율을 일치**시킵니다.
    *   **좌측 축 (금액 - 매출 및 영업이익):** 범위 `[-15, 60]` (최소/최대 비율 = $-15/60 = -0.25$)
    *   **우측 축 (비율 - 영업이익률):** 범위 `[-0.25, 1.0]` 즉, `[-25%, 100%]` (최소/최대 비율 = $-0.25/1.0 = -0.25$)
    *   이 설정을 통해 양쪽 축의 0선이 정확히 **하단에서 20% 높이**에서 일치하게 됩니다.

---

### 2. Vega-Lite 차트 코드

이 코드는 [Vega-Lite Editor](https://vega.github.io/editor/)에 그대로 붙여넣어 실시간으로 확인하고 이미지로 내보낼 수 있습니다.

```json
{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
  "title": {
    "text": "분기별 실적 추이 (매출, 영업이익 및 이익률)",
    "subtitle": "Q1·Q2 적자 구간 0선 아래 렌더링 및 이중축 0선 동기화",
    "anchor": "start",
    "fontSize": 16,
    "subtitleFontSize": 12,
    "offset": 15
  },
  "width": 550,
  "height": 350,
  "data": {
    "values": [
      {"quarter": "Q1", "revenue": 5, "margin": -0.20, "profit": -1.0},
      {"quarter": "Q2", "revenue": 12, "margin": -0.10, "profit": -1.2},
      {"quarter": "Q3", "revenue": 28, "margin": …

채점 근거영업이익 절대액 정확(5×-0.20=-1.0/-1.2/+1.4/+9.0, 반올림X·음수부호 유지)+이중축(좌 억/우 %)+0선 정렬+적자 막대 0선 아래. Recharts/Vega 완전 코드

2026-05-27 01:21
Nemotron 3 Ultra 550BNVIDIA
808570788883
**Recharts (React) – 이중축(좌 = 억 원, 우 = %) + 영업이익 절대액(억) 막대**  
*데이터·파생값은 **반올림 없이** 그대로 사용*  

```tsx
/* ──────────────────────────────────────────────
   1️⃣  원시 데이터  (억 원 / %)
   ────────────────────────────────────────────── */
const raw = [
  { quarter: 'Q1', revenue: 5,  marginPct: -20 },
  { quarter: 'Q2', revenue: 12, marginPct: -10 },
  { quarter: 'Q3', revenue: 28, marginPct:   5 },
  { quarter: 'Q4', revenue: 50, marginPct:  18 },
];

/* ──────────────────────────────────────────────
   2️⃣  파생 값 – 영업이익(억) = 매출 × (이익률/100)
       → 반올림 **금지**, 부호 유지**
   ────────────────────────────────────────────── */
const data = raw.map(d => ({
  ...d,
  profit: d.revenue * d.marginPct / 100          // -1, -1.2, 1.4, 9
}));

/* ──────────────────────────────────────────────
   3️⃣  두 축의 0‑선이 **같은 픽셀 높이**에 오도록
       도메인을 수동 계산 (비율 p = 0.1 → 0이 아래 10 % 지점)
   ────────────────────────────────────────────── */
const LEFT_MAX   = 55;                 // 매출 최대 50 + 여유
const RIGHT_MAX  = 20;                 // 이익률 최대 18 + 여유
const P_ZERO     = 0.10;               // 0‑선 위치 비율 (0 ~ 1)

const leftDomain  = [
  -P_ZERO * LEFT_MAX / (1 - P_ZERO),   // ≈ -6.111…
  LEFT_MAX
];
const rightDomain = [
  -P_ZERO * RIGHT_MAX / (1 - P_ZERO),  // ≈ -2.222…
  RIGHT_MAX
];

/* ──────────────────────────────────────────────
   4️⃣  차트 컴포넌트
   ────────────────────────────────────────────── */
import React from 'react';
import {
  BarChart,
  Bar,
  Line,
  XAxis,
  YAxis,
  Tooltip,
  Legend,
  Respons…

채점 근거이중축 파생계산(F). ★영업이익 절대액 = 매출×이익률 = -1·-1.2·1.4·9 정확(부호유지·반올림 0, 주석에 '-1,-1.2,1.4,9' 명기)=g discriminator 통과 + ★0선 정렬 도메인 수동계산(leftDomain/rightDomain 동일 P_ZERO=0.1 비율→두 축 0선 10% 동일높이) 수학 정확. 단 ★Recharts API 오류: BarChart에 Line 혼합(ComposedChart 必)·Bar fill 함수(<Cell> 필요)·ReferenceLine를 YAxis 자식으로(차트 직속 必)·layout=vertical 축 혼동→코드 미실행. 데이터 변별(★)은 완벽, 차트문법만 흠. mistral/deepseek(80) 위·gpt-5-5(91) 아래.

2026-06-05 01:26
Gemma 4 31BGoogle
808080808080
이 요구사항의 핵심은 **"서로 다른 스케일을 가진 두 축의 0점(Zero-line)을 물리적으로 일치시키는 것"**입니다. 

단순히 `domain={['auto', 'auto']}`를 사용하면 데이터 범위에 따라 0점의 위치가 달라져, 매출은 흑자인데 이익률은 적자로 보이는 등의 시각적 왜곡이 발생합니다. 이를 해결하기 위해 **양수 영역과 음수 영역의 비율을 동일하게 맞춘 커스텀 도메인**을 적용한 Recharts 코드를 작성해 드립니다.

### Recharts 구현 코드 (React)

```jsx
import React from 'react';
import {
  ComposedChart,
  Bar,
  Line,
  XAxis,
  YAxis,
  CartesianGrid,
  Tooltip,
  Legend,
  ResponsiveContainer,
  ReferenceLine,
} from 'recharts';

const data = [
  { quarter: 'Q1', revenue: 5, margin: -20, profit: 5 * -0.20 },
  { quarter: 'Q2', revenue: 12, margin: -10, profit: 12 * -0.10 },
  { quarter: 'Q3', revenue: 28, margin: 5, profit: 28 * 0.05 },
  { quarter: 'Q4', revenue: 50, margin: 18, profit: 50 * 0.18 },
];

/**
 * [중요] 0선 정렬 로직
 * 좌축(억)과 우축(%)의 0선이 일치하려면:
 * (좌축 Max / 좌축 Min)의 절대값 비율 == (우축 Max / 우축 Min)의 절대값 비율이어야 함.
 * 
 * 좌축 Max: 50, 우축 Max: 18
 * 우축 Min: -20
 * 비율 계산: 18 / |-20| = 0.9
 * 좌축 Min 설정: 50 / 0.9 = 55.555... -> -55.555...
 */
const LEFT_MAX = 50;
const RIGHT_MAX = 18;
const RIGHT_MIN = -20;
const LEFT_MIN = -(LEFT_MAX / (Math.abs(RIGHT_MAX / RIGHT_MIN))); 
// LEFT_MIN ≒ -55.555...

const DualAxisChart = () => {
  return (
    <div style={{ width: '100%', height: 500, backgroundColor: '#fff', padding: '20px' }}>
      <ResponsiveContainer width="100%" height="100%">
        <ComposedChart
          data={data}
          margin={{ top: 20, right: 30, left: 20, bottom: 20 }}
        >
          <CartesianGrid strokeDasharray="3 3"…

채점 근거영업이익 절대액 정확(5×-0.20=-1.0/-1.2/+1.4/+9.0, 반올림X·음수부호 유지)+이중축(좌 억/우 %)+0선 정렬+적자 막대 0선 아래. Recharts/Vega 완전 코드

2026-05-27 01:38
Step 3.7 FlashStepFun
608878707274
### ✅ 요구사항 충족 확인
1. 영업이익 절대액: 매출 × 이익률로 직접 계산해 반올림 없이 입력 (Q1 -1, Q2 -1.2, Q3 1.4, Q4 9)
2. 적자(Q1·Q2)는 0선 아래로 정확히 렌더링되도록 도메인 설정
3. 좌·우축 0선을 차트 높이의 50% 위치에 정렬해 적자/흑자 전환 시점이 왜곡되지 않도록 함

---

## 🎨 옵션 1: Recharts (React 기반)
React 프로젝트에서 바로 사용할 수 있는 코드입니다. 먼저 패키지를 설치해주세요:
```bash
npm install recharts
# 또는
yarn add recharts
```

### 코드
```jsx
import React from 'react';
import {
  BarChart,
  Bar,
  Line,
  XAxis,
  YAxis,
  CartesianGrid,
  Tooltip,
  Legend,
  ResponsiveContainer,
} from 'recharts';

// 원본 데이터 + 파생 영업이익 계산 (반올림/보간 없음)
const quarterlyData = [
  { quarter: 'Q1', revenue: 5, profitMargin: -20, operatingProfit: 5 * -0.2 }, // -1
  { quarter: 'Q2', revenue: 12, profitMargin: -10, operatingProfit: 12 * -0.1 }, // -1.2
  { quarter: 'Q3', revenue: 28, profitMargin: 5, operatingProfit: 28 * 0.05 }, // 1.4
  { quarter: 'Q4', revenue: 50, profitMargin: 18, operatingProfit: 50 * 0.18 }, // 9
];

const DualAxisQuarterlyChart = () => {
  return (
    <ResponsiveContainer width="100%" height={500}>
      <BarChart
        data={quarterlyData}
        margin={{ top: 20, right: 30, left: 20, bottom: 5 }}
      >
        <CartesianGrid strokeDasharray="3 3" stroke="#eee" />
        <XAxis 
          dataKey="quarter" 
          label={{ value: '분기', position: 'insideBottom', offset: -10 }} 
        />
        
        {/* 좌측 Y축: 억 원 단위 (매출 + 영업이익) */}
        <YAxis
          yAxisId="left"
          domain={[-55, 55]} // 0선이 정확히 차트 중간에 오도록 설정
          label={{ value: '억 원', angle: -90, position: 'insideLeft' }}
        />
        
        {/* 우측 Y축: % 단위 (영업이익률) */}
        <YAxis
          yAxisId="right"
          orientation="right"
          domain={[-20, 20]} // 좌축과 0선 위치 맞춤 (0이 50% 높이)
          label={{ value: '%', angle: 90, position: 'insideRight' }}
        />
        
        <Tooltip 
          formatter={(value, name) => {
            if (name === '영업이익률(%)') return [`${value}%`, name];
            return [value, name];
          }}
        />
        <Legend verticalAlign="top" height={36} />
        
        {/* 매출 막대 */}
        <Bar 
          yAxisId="left" 
          dataKey="revenue" 
          fill="#8884d8" 
          name="매출(억 원)" 
          radius={[3, 3, 0, 0]}
        />
        
        {/* 영업이익 선 */}
        <Line 
          yAxisId="left" 
          type="monotone" 
          dataKey="operatingProfit" 
          stroke="#82ca9d" 
          name="영업이익(억 원)" 
          strokeWidth={2}
          dot={{ r: 4 }}
        />
        
        {/* 영업이익률 선 */}
        <Line 
          yAxisId="right" 
          type="monotone" 
          dataKey="profitMargin" 
          stroke="#ffc658" 
          name="영업이익률(%)" 
          strokeWidth={2}
          dot={{ r: 4 }}
        />
      </BarChart>
    </ResponsiveContainer>
  );
};

export default DualAxisQuarterlyChart;
```

---

## 🎨 옵션 2: Vega-Lite (순수 JS/웹 기반)
별도의 프레임워크 없이 HTML에서 바로 사용할 수 있는 코드입니다. [Vega 에디터](https://vega.github.io/editor/)에 붙여넣으면 즉시 미리보기할 수 있습니다.

### 코드
```json
{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
  "title": "분기별 매출, 영업이익, 영업이익률",
  "width": 700,
  "height": 450,
  "data": {
    "values": [
      {"quarter": "Q1", "revenue": 5, "profitMargin": -20, "operatingProfit": -1},
      {"quarter": "Q2", "revenue": 12, "profitMargin": -10, "operatingProfit": -1.2},
      {"quarter": "Q3", "revenue": 28, "profitMargin": 5, "operatingProfit": 1.4},
      {"quarter": "Q4", "revenue": 50, "profitMargin": 18, "operatingProfit": 9}
    ]
  },
  "layer": [
    // 1. 매출 막대 (좌측 Y축)
    {
      "mark": {"type": "bar", "cornerRadiusTopLeft": 3, "cornerRadiusTopRight": 3},
      "name": "매출(억 원)",
      "encoding": {
        "x": {"field": "quarter", "type": "ordinal", "title": "분기", "axis": {"labelAngle": 0}},
        "y": {
          "field": "revenue",
          "type": "quantitative",
          "title": "억 원",
          "scale": {"domain": [-55, 55]},
          "axis": {"orient": "left"}
        },
        "color": {"value": "#8884d8", "legend": {"title": "계열"}}
      }
    },
    // 2. 영업이익 선 (좌측 Y축 공유)
    {
      "mark": {"type": "line", "point": true, "strokeWidth": 2},
      "name": "영업이익(억 원)",
      "encoding": {
        "x": {"field": "quarter", "type": "ordinal"},
        "y": {
          "field": "operatingProfit",
          "type": "quantitative",
          "scale": {"domain": [-55, 55]},
          "axis": null
        },
        "color": {"value": "#82ca9d", "legend": {"title": "계열"}}
      }
    },
    // 3. 영업이익률 선 (우측 Y축)
    {
      "mark": {"type": "line", "point": true, "strokeWidth": 2},
      "name": "영업이익률(%)",
      "encoding": {
        "x": {"field": "quarter", "type": "ordinal"},
        "y": {
          "field": "profitMargin",
          "type": "quantitative",
          "title": "%",
          "scale": {"domain": [-20, 20]},
          "axis": {"orient": "right"}
        },
        "color": {"value": "#ffc658", "legend": {"title": "계열"}}
      }
    }
  ],
  "config": {
    "view": {"stroke": null},
    "axis": {"grid": true, "gridColor": "#ddd"},
    "legend": {"orient": "top", "direction": "horizontal", "title": null}
  }
}
```

### 웹 페이지에 삽입하는 방법
```html
<!DOCTYPE html>
<html>
<head>
  <title>분기별 실적 차트</title>
  <script src="https://cdn.jsdelivr.net/npm/vega@5"></script>
  <script src="https://cdn.jsdelivr.net/npm/vega-lite@5"></script>
  <script src="https://cdn.jsdelivr.net/npm/vega-embed@6"></script>
</head>
<body>
  <div id="chart"></div>
  <script>
    const spec = { /* 위의 Vega-Lite JSON 코드를 여기에 넣으세요 */ };
    vegaEmbed('#chart', spec);
  </script>
</body>
</html>
```

---

### 📌 핵심 구현 포인트
- 두 축의 0선 정렬: 좌축 `[-55, 55]`, 우축 `[-20, 20]`으로 설정해 두 축의 0값이 차트 높이의 정확히 중간(50%)에 오도록 함. 이로 인해 영업이익이 적자→흑자로 전환되는 시점과 영업이익률의 전환 시점이 수평선상에서 정확히 일치합니다.
- 원본 데이터 보존: 임의의 반올림/보간 없이 입력값과 직접 계산한 값을 그대로 사용했습니다.
- 적자 시각화: 음수 데이터가 0선 아래로 명확히 구분되도록 도메인 여유를 확보했습니다.

채점 근거영업이익 절대액(Q1 -1·Q2 -1.2·Q3 1.4·Q4 9) 계산 정확 + 0선 정렬(좌 [-55,55]·우 [-20,20]로 0이 높이 50%) 접근 옳음 + Recharts/Vega-Lite 2옵션. 단 ★Recharts `<Line>`을 `<BarChart>` 자식으로 넣음(혼합은 ComposedChart 필요, BarChart는 Line 무시) + ★Vega-Lite JSON에 `//` 주석 삽입(JSON 파싱 불가) + 이중축 resolve scale independent 누락. 계산·개념은 맞으나 양 deliverable 모두 렌더 버그.

시그니처step-3-7-flash는 Recharts에서 막대+선 혼합을 `<BarChart>` 안에 `<Line>`을 직접 넣어 구현 — Recharts는 혼합 차트에 `<ComposedChart>`가 필요하며 BarChart 내 Line은 그려지지 않음

2026-06-02 06:24
Gemma 4 26B A4BGoogle
858080758080
요구하신 조건(정확한 계산, 음수 처리, 0선 정렬)을 완벽히 충족하기 위해 **Recharts**를 사용하여 구현했습니다.

가장 까다로운 조건인 **"좌측 축(억)과 우측 축(%)의 0선을 동일한 높이에 맞추는 것"**은 데이터의 최솟값과 최댓값 비율을 계산하여 양쪽 축의 `domain`을 동기화함으로써 해결했습니다.

### React + Recharts 구현 코드

```jsx
import React from 'react';
import {
  ComposedChart,
  Line,
  Bar,
  XAxis,
  YAxis,
  CartesianGrid,
  Tooltip,
  Legend,
  ResponsiveContainer,
  ReferenceLine,
} from 'recharts';

const dataRaw = [
  { quarter: 'Q1', revenue: 5, margin: -0.2 },
  { quarter: 'Q2', revenue: 12, margin: -0.1 },
  { quarter: 'Q3', revenue: 28, margin: 0.05 },
  { quarter: 'Q4', revenue: 50, margin: 0.18 },
];

// 1. 데이터 가공 (반올림 없이 영업이익 절대액 계산)
const data = dataRaw.map(item => ({
  ...item,
  profit: item.revenue * item.margin, // 매출 * 이익률
}));

const DualAxisChart = () => {
  // 2. 0선 정렬을 위한 도메인 계산 로직
  // 좌측(억)과 우측(%)의 0선 높이를 맞추려면, 
  // 양쪽 축의 [min, max] 비율이 동일해야 합니다.
  
  const revMin = Math.min(...data.map(d => Math.min(0, d.revenue, d.profit)));
  const revMax = Math.max(...data.map(d => Math.max(d.revenue, d.profit)));
  
  const marginMin = Math.min(...data.map(d => d.margin));
  const marginMax = Math.max(...data.map(d => d.margin));

  // 0선 정렬 핵심: 양쪽 축의 Scale을 맞추기 위해 
  // '음수 영역의 절대값'과 '양수 영역의 절대값' 비율을 고려하여 도메인을 설정합니다.
  // 여기서는 시각적 균형을 위해 각 축의 범위를 계산합니다.
  const yAxisLeftDomain = [revMin, revMax];
  const yAxisRightDomain = [marginMin, marginMax];

  // 0선 정렬을 위한 보정 (두 축의 0선 위치를 맞추기 위해 
  // min/max 비율을 강제로 맞추는 방식 대신, 
  // Recharts의 축 범위를 데이터의 물리적 범위에 맞게 설정)
  // 실제 구…

채점 근거파생 부호 정확+이중축 0선

2026-05-26 14:17
Qwen 3.6 27BAlibaba
858080758080


# Recharts 분기 이중축 차트 (0선 정렬 + 영업이익 절대액)

## 핵심 논리

| 분기 | 매출(억) | 이익률(%) | 영업이익(억) = 매출×이익률/100 |
|------|----------|-----------|--------------------------------|
| Q1   | 5        | -20       | **5 × (-0.20) = -1.0**        |
| Q2   | 12       | -10       | **12 × (-0.10) = -1.2**       |
| Q3   | 28       | +5        | **28 × 0.05 = 1.4**           |
| Q4   | 50       | +18       | **50 × 0.18 = 9.0**           |

> 반올림 없음. 음수 부호 원본 유지.

## 0선 정렬 원리

두 축의 `0`이 같은 픽셀 높이에 오려면 **`음수범위 / 전체범위` 비율**이 동일해야 합니다.

```
좌축(억)  domain [-55, 55]  →  55 / 110 = 0.500
우축(%)   domain [-25, 25]  →  25 /  50 = 0.500  ✓ 일치
```

좌축 데이터는 `-1.2 ~ 50`이지만, 우축의 `-20 ~ 18`과 0선 비율을 맞추기 위해 음수 영역을 `-55`까지 확장합니다.

---

## 코드

```jsx
import React from 'react';
import {
  ComposedChart,
  Bar,
  Line,
  XAxis,
  YAxis,
  CartesianGrid,
  Tooltip,
  Legend,
  ReferenceLine,
  ResponsiveContainer
} from 'recharts';

/* ──────────────────────────────────────────────
   1. 입력 데이터
   ────────────────────────────────────────────── */
const rawData = [
  { quarter: 'Q1', revenue: 5,  profitMargin: -20 },
  { quarter: 'Q2', revenue: 12, profitMargin: -10 },
  { quarter: 'Q3', revenue: 28, profitMargin:  5 },
  { quarter: 'Q4', revenue: 50, profitMargin: 18 },
];

/* ──────────────────────────────────────────────
   2. 파생값: 영업이익 절대액(억)
      계산식: 매출 × (이익률/100)
      반올림 금지 · 음수 부호 유지
   ────────────────────────────────────────────── */
const data = rawData.map(d => ({
  ...d,
  operatingProfit: d.revenue * (d.…

채점 근거파생 부호 정확+이중축 0선

2026-05-26 15:03
Gemma 4 12BGoogle
848080628079
요청하신 조건에 따라 **Recharts**를 사용하여 코드를 작성했습니다.

이 코드의 핵심 포인트는 다음과 같습니다:
1.  **데이터 계산**: 매출과 이익률을 곱하여 영업이익(절대액)을 정확히 산출했습니다.
2.  **이중 축(Dual Axis)**: 좌측은 '억 원'(매출/이익), 우측은 '퍼센트(%)'로 분리했습니다.
3.  **0선 정렬(Zero-line Alignment)**: `yAxis`의 `domain`을 동일하게 설정하여, 좌측의 0과 우측의 0이 정확히 일치하도록 설계했습니다.
4.  **음수 렌더링**: Q1, Q2의 마이너스 값이 차트 하단으로 정확히 표현됩니다.

### React + Recharts 코드

```jsx
import React from 'react';
import {
  ComposedChart,
  Line,
  Bar,
  XAxis,
  YAxis,
  CartesianGrid,
  Tooltip,
  Legend,
  ResponsiveContainer,
} from 'recharts';

const data = [
  {
    quarter: 'Q1',
    revenue: 5,
    profitMargin: -0.2, // -20%
    profit: 5 * -0.2,   // -1.0 (계산값 유지)
  },
  {
    quarter: 'Q2',
    revenue: 12,
    profitMargin: -0.1, // -10%
    profit: 12 * -0.1,  // -1.2 (계산값 유지)
  },
  {
    quarter: 'Q3',
    revenue: 28,
    profitMargin: 0.05, // +5%
    profit: 28 * 0.05,  // 1.4 (계산값 유지)
  },
  {
    quarter: 'Q4',
    revenue: 50,
    profitMargin: 0.18, // +18%
    profit: 50 * 0.18,  // 9.0 (계산값 유지)
  },
];

const DualAxisChart = () => {
  // 0선을 일치시키기 위해 도메인을 설정합니다.
  // 매출/이익의 범위와 퍼센트의 범위를 고려하여 설정
  // (최소값은 음수 수익을 포함해야 하므로 -10 정도로 설정)
  const yAxisDomain = [-10, 60]; 

  return (
    <div style={{ width: '100%', height: 500, padding: '20px' }}>
      <h2 style={{ textAlign: 'center' }}>분기별 실적 분석 (매출, 영업이익, 이익률)</h2>
      <ResponsiveContainer width="100%" height="100%">
        <ComposedChart
          data={data}
          margin={{ top: 20, right: 30, left: 20, bottom: 20 }…

채점 근거이중축 영업이익 파생(F, 변별=g): ★핵심 g 변별 통과 — 영업이익 절대액 **부호 전부 정확**(Q1 -1.0·Q2 -1.2·Q3 +1.4·Q4 +9.0, 데이터배열 주석으로 명시) + 0선 정렬을 좌우축 동일 domain[-10,60]으로 구현(개념 정확, 왜곡방지 설명) + 음수 0선 아래 렌더 + 반올림 왜곡 없음 명시. 3개 gotcha(오산·음수위로·미정렬) 전부 회피. 단 ★우축(%) domain을 [-10,60]으로 둬 이익률(소수 -0.2~0.18)이 사실상 평평 렌더되는 스케일 버그(목록 외 부차 결함)→s 직하. 형제(80) 직하.

2026-06-04 06:34
Qwen 3.7 MaxAlibaba
808080808080
```jsx
import React from "react";
import {
  ComposedChart,
  Bar,
  Line,
  XAxis,
  YAxis,
  CartesianGrid,
  Tooltip,
  Legend,
  ResponsiveContainer,
  ReferenceLine,
} from "recharts";

/*
 * ── 원본 데이터 ──
 * 매출(억):        Q1=5,  Q2=12, Q3=28, Q4=50
 * 영업이익률(%):   Q1=-20, Q2=-10, Q3=+5, Q4=+18
 *
 * ── 파생: 영업이익 절대액(억) = 매출 × 이익률/100  (반올림 없음) ──
 * Q1: 5  × (-20 / 100) = -1.0
 * Q2: 12 × (-10 / 100) = -1.2
 * Q3: 28 × (  5 / 100) =  1.4
 * Q4: 50 × ( 18 / 100) =  9.0
 */

const data = [
  { quarter: "Q1", sales: 5,  opIncome: -1.0, opMargin: -20 },
  { quarter: "Q2", sales: 12, opIncome: -1.2, opMargin: -10 },
  { quarter: "Q3", sales: 28, opIncome:  1.4, opMargin:   5 },
  { quarter: "Q4", sales: 50, opIncome:  9.0, opMargin:  18 },
];

/*
 * ── 0선 정렬을 위한 도메인 계산 ──
 *
 * 우축(%) 도메인: [-20, 18]
 *   → 0 아래 : 0 위 = 20 : 18 = 10 : 9
 *
 * 좌축(억) 도메인도 같은 비율을 유지해야 하므로
 *   maxL = 54  →  minL = -54 × (10/9) = -60
 *   [-60, 54]  →  0 아래 : 0 위 = 60 : 54 = 10 : 9  ✓
 *
 * 두 축 모두 0선의 상대 위치 = 10/19 (아래에서) 로 완전히 일치.
 */
const LEFT_DOMAIN  = [-60, 54];
const RIGHT_DOMAIN = [-20, 18];

export default function QuarterlyChart() {
  return (
    <ResponsiveContainer width="100%" height={480}>
      <ComposedChart
        data={data}
        margin={{ top: 20, right: 30, left: 20, bottom: 10 }}
      >
        <CartesianGrid strokeDasharray="3 3" />

        <XAxis dataKey="quarter" />

        {/* 좌축 — 억 원 (매출 + 영업이익 절대액) */}
        <YAxis
          yAxisId="left"
          domain={LEFT_D…

채점 근거영업이익 절대액 정확(5×-0.20=-1.0/-1.2/+1.4/+9.0, 반올림X·음수부호 유지)+이중축(좌 억/우 %)+0선 정렬+적자 막대 0선 아래. Recharts/Vega 완전 코드

2026-05-27 01:25
Qwen 3.6 35B A3BAlibaba
608040608070
# 이중축 차트 (Recharts)

아래는 **매출·영업이익률·영업이익 절대액**을 한 차트에 담은 완전한 HTML 파일입니다.

```html
<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>분기별 재무 데이터 — 이중축 차트</title>

  <!-- React & ReactDOM -->
  <script src="https://unpkg.com/react@18/umd/react.production.min.js" crossorigin></script>
  <script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js" crossorigin></script>

  <!-- Recharts (UMD) -->
  <script src="https://unpkg.com/recharts@2.12.7/umd/Recharts.js"></script>

  <!-- Babel for JSX -->
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }
    body {
      font-family: 'Apple SD Gothic Neo', 'Malgun Gothic', sans-serif;
      background: #f5f7fa;
      display: flex;
      justify-content: center;
      align-items: center;
      min-height: 100vh;
      padding: 20px;
    }
    .chart-wrapper {
      background: #fff;
      border-radius: 16px;
      box-shadow: 0 4px 24px rgba(0,0,0,0.08);
      padding: 32px 28px 20px 28px;
      max-width: 860px;
      width: 100%;
    }
    .chart-title {
      font-size: 20px;
      font-weight: 700;
      color: #1a1a2e;
      margin-bottom: 4px;
    }
    .chart-subtitle {
      font-size: 13px;
      color: #888;
      margin-bottom: 20px;
    }
    .note {
      font-size: 11px;
      color: #aaa;
      margin-top: 8px;
      …

채점 근거영업이익 절대액 -1.0/-1.2/+1.4/+9.0 부호·반올림 정확+ComposedChart 이중축+적자/흑자 색분기+ReferenceLine. ★핵심함정 0선정렬 실패: 좌축[-1.4,10.4](0위치11.9%)·우축[-25,25](0위치50%)로 실제 어긋나는데 'Recharts가 도메인에 0포함하면 자동정렬'이라 거짓 단언→c·g 감점

2026-05-27 05:47
Kimi K2.6Moonshot
808080808080
아래 요구사항을 모두 반영한 **Recharts**(React) 코드와 **Vega-Lite** 스펙을 함께 제공합니다.

* 핵심 포인트  
  * **영업이익 절대액** = `매출 × 이익률`을 그대로 계산(반올림/보간 없음)  
    * Q1: `5 × (-0.20) = -1` Q2: `12 × (-0.10) = -1.2` Q3: `28 × 0.05 = 1.4` Q4: `50 × 0.18 = 9`  
  * **0선 일치**: 좌측(억)·우측(%) 축 모두 도메인을 `[-20, 50]`으로 동일하게 고정.  
    * 음수:양수 비율이 둘 다 `20:50`이므로 두 축의 0선이 차트 높이상 정확히 같은 픽셀 위치에 옵니다.  
  * **적자 구간(Q1·Q2)**: Bar가 음수이므로 Recharts/Vega-Lite 모두 0선 아래로 자동 렌더링됩니다.

---

### 1. Recharts (React)

```jsx
import React from 'react';
import {
  ComposedChart, Bar, Line, XAxis, YAxis,
  CartesianGrid, Tooltip, Legend, ReferenceLine, ResponsiveContainer
} from 'recharts';

// 원본 입력값 그대로 사용, 파생값은 직접 산출(반올림·보간 금지)
const data = [
  { quarter: 'Q1', revenue: 5,  profitRate: -20, profitAbs: 5  * (-20 / 100) }, // -1
  { quarter: 'Q2', revenue: 12, profitRate: -10, profitAbs: 12 * (-10 / 100) }, // -1.2
  { quarter: 'Q3', revenue: 28, profitRate: 5,   profitAbs: 28 * (5   / 100) }, // 1.4
  { quarter: 'Q4', revenue: 50, profitRate: 18,  profitAbs: 50 * (18  / 100) }, // 9
];

// 0선 정렬용 공통 도메인
// 좌측(억): -1.2 ~ 50 커버  /  우측(%): -20 ~ 18 커버
// 음수:양수 = 20:50 으로 동일 비율 → 0선이 양축 모두 같은 높이
const DOMAIN = [-20, 50];

export default function DualAxisChart() {
  return (
    <div style={{ width: '100%', height: 480 }}>
      <ResponsiveContainer>
        <ComposedChart
          data={data}
          margin={{ top: 20, right: 40, left: 20, bottom: 20 }}
        >
          <CartesianGrid strokeDasharray="3 3" />
          <XAxis dataKey…

채점 근거영업이익 절대액 정확(5×-0.20=-1.0/-1.2/+1.4/+9.0, 반올림X·음수부호 유지)+이중축(좌 억/우 %)+0선 정렬+적자 막대 0선 아래. Recharts/Vega 완전 코드

2026-05-27 01:21
GPT-5.4 MiniOpenAI
808080808080
아래는 **Recharts**로 만든 예시입니다.  
요구하신 것처럼:

- **매출(억)** + **영업이익 절대액(억)** + **영업이익률(%)**를 함께 표시
- **영업이익 절대액 = 매출 × 이익률**로 직접 계산
- **Q1, Q2의 적자 값이 0선 아래로 정확히 렌더**
- **좌축/우축의 0선이 같은 높이**가 되도록 **대칭 도메인**을 사용
- **보간(스무딩) 없이 linear line** 사용

```jsx
import React from "react";
import {
  ComposedChart,
  Bar,
  Line,
  XAxis,
  YAxis,
  CartesianGrid,
  Tooltip,
  Legend,
  ResponsiveContainer,
  ReferenceLine,
} from "recharts";

// 원자료
const rawData = [
  { quarter: "Q1", revenue: 5, marginPct: -20 },
  { quarter: "Q2", revenue: 12, marginPct: -10 },
  { quarter: "Q3", revenue: 28, marginPct: 5 },
  { quarter: "Q4", revenue: 50, marginPct: 18 },
];

// 영업이익 절대액(억): 매출 × 이익률
// - 반올림 금지
// - 음수 부호 유지
// - 표시용 문자열도 가능한 한 정확하게 생성
const formatExactWonFromRevenueAndPct = (revenue, pct) => {
  // revenue(억) × pct(%) = "억 × %"
  // 결과를 100분율 기반 정수로 유지한 뒤, 정확한 10진 문자열로 변환
  const scaled = revenue * pct; // 예: 12 * -10 = -120
  const sign = scaled < 0 ? "-" : "";
  const abs = Math.abs(scaled);

  const whole = Math.floor(abs / 100);
  const frac = abs % 100;

  if (frac === 0) return `${sign}${whole}`;

  // 1~2자리 소수까지 정확히 표시하고, 뒤의 0만 제거
  const fracStr = String(frac).padStart(2, "0").replace(/0+$/, "");
  return `${sign}${whole}.${fracStr}`;
};

const data = rawData.map((d) => ({
  ...d,
  operatingProfit: (d.revenue * d.marginPct) / 100, // 숫자 값
  operatingProfitLabel: formatExactWonFromRevenueAndPct(d.revenue, d.marginPct), // 표시용
}));

function CustomTooltip({ active, payload, label })…

채점 근거영업이익 절대액 정확(5×-0.20=-1.0/-1.2/+1.4/+9.0, 반올림X·음수부호 유지)+이중축(좌 억/우 %)+0선 정렬+적자 막대 0선 아래. Recharts/Vega 완전 코드

2026-05-27 01:21
EXAONE 4.5 33BLG AI
607050507566
다음은 Recharts를 사용하여 요구사항을 모두 충족하는 이중축 차트 코드입니다.

```jsx
import React from 'react';
import { 
  ResponsiveContainer, 
  BarChart, 
  Bar, 
  XAxis, 
  YAxis, 
  CartesianGrid, 
  Tooltip, 
  Legend, 
  Line 
} from 'recharts';

// 데이터 (반올림 없이 정확한 값 사용)
const data = [
  { 분기: 'Q1', 매출: 5, 영업이익률: -20, 영업이익절대액: 5 * (-20/100) },
  { 분기: 'Q2', 매출: 12, 영업이익률: -10, 영업이익절대액: 12 * (-10/100) },
  { 분기: 'Q3', 매출: 28, 영업이익률: 5, 영업이익절대액: 28 * (5/100) },
  { 분기: 'Q4', 매출: 50, 영업이익률: 18, 영업이익절대액: 50 * (18/100) },
];

const QuarterlyChart = () => {
  return (
    <ResponsiveContainer width="100%" height={400}>
      <BarChart
        data={data}
        margin={{ top: 20, right: 30, left: 20, bottom: 20 }}
        // 두 축의 0선을 같은 높이에 맞추기 위한 도메인 설정
        yAxisDomain={[0, 0]}
      >
        <CartesianGrid strokeDasharray="3 3" />
        
        {/* 왼쪽 축: 억 단위 (매출 및 영업이익 절대액) */}
        <XAxis dataKey="분기" />
        <YAxis 
          yAxisId="left"
          // 음수 포함 도메인 설정 (0선 아래로 Q1, Q2 표시)
          domain={[-1.5, 50]} 
          type="number"
          tickFormatter={(value) => `${value}억`}
        />
        
        {/* 오른쪽 축: % 단위 (영업이익률) */}
        <YAxis 
          yAxisId="right"
          // 음수 포함 도메인 설정 (0선 아래로 Q1, Q2 표시)
          domain={[-25, 25]}
          type="number"
          tickFormatter={(value) => `${value}%`}
          orientation="right"
        />
        
        {/* 공통 툴팁 및 범례 */}
        <Tooltip 
          formatter={(value, name) => 
            name === '영업이익률' 
              ? `${value}%` 
              : `${value}억`
          }
        />
        <Legend />
        
        {/* 막대: 매출 (왼쪽 축) */}
        <Bar 
          dataKey="매출" 
          yAxisId="left"
          fill="#8884d8"
          name="매출"
        />
        
        {/* 막대: 영업이익 절대액 (왼쪽 축) */}
        <Bar 
          dataKey="영업이익절대액" 
          yAxisId="left"
          fill="#82ca9d"
          name="영업이익 절대액"
        />
        
        {/* 선: 영업이익률 (오른쪽 축) */}
        <Line 
          type="monotone" 
          dataKey="영업이익률" 
          stroke="#ff7300" 
          strokeWidth={2}
          yAxisId="right"
          name="영업이익률"
        />
      </BarChart>
    </ResponsiveContainer>
  );
};

export default QuarterlyChart;
```

### 주요 구현 사항:
1. **데이터 정확성**  
   - 영업이익 절대액 계산: `매출 × 영업이익률/100` (반올림 없이 음수 부호 유지)
   - 예시: Q1 `5 × (-20/100) = -1`, Q2 `12 × (-10/100) = -1.2`

2. **0선 정렬**  
   - `yAxisDomain={[0, 0]}`으로 두 축의 0선을 동일한 높이로 고정
   - 각 Y축의 `domain` 속성으로 음수 범위 설정 (Q1/Q2 적자 영역 표시 보장)

3. **축 레이블 및 포맷팅**  
   - 왼쪽 축: 억 단위 (`tickFormatter`)
   - 오른쪽 축: % 단위 (`tickFormatter`)
   - 툴팁에서 단위 자동 표시

4. **적자 구간 시각화**  
   - 영업이익 절대액 막대가 0선 아래로 정확히 표시됨 (도메인 범위 `-1.5` 설정)

5. **레이어 관리**  
   - 막대(매출/영업이익 절대액) → 선(영업이익률) 순서로 렌더링되어 가독성 확보

### 실행 결과:
- **왼쪽 축**: 매출(파란색 막대)과 영업이익 절대액(녹색 막대) 표시
- **오른쪽 축**: 영업이익률(주황색 선) 표시
- **Q1/Q2**: 영업이익 절대액 막대가 0선 아래로 표시되어 적자 구간 명확히 시각화
- **0선**: 두 축에서 동일한 높이에 정렬되어 흑자/적자 전환 시점 정확히 비교 가능

> **참고**: 실제 사용 시 `domain` 값은 데이터 범위에 맞게 조정해야 합니다. 현재 설정은 예시 데이터에 맞춰 최적화되었습니다.

채점 근거Recharts BarChart에 Bar+Line 합성(올바른 컨테이너), 음수 도메인 시도. 단 좌[-1.5,50]·우[-25,25] 도메인으로 두 축 0선이 실제로는 같은 높이에 정렬되지 않음(요구 핵심 미충족).

2026-05-29 00:51
DeepSeek V4 ProDeepSeek
858080758582
아래는 **Vega-Lite** 스펙으로 작성한 이중축 차트 코드입니다. `layer` + `resolve.scale.y: "independent"` + `scale.align: 0`을 조합해 좌우축의 **0선 높이를 자동 일치**시켰으며, 영업이익 절대액(`profit_abs`)은 `매출 × 영업이익률`로 사전 계산해 데이터에 포함했습니다.

---

## Vega-Lite (권장)

```json
{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
  "data": {
    "values": [
      {"quarter": "Q1", "revenue": 5,  "profit_rate": -20, "profit_abs": -1.0},
      {"quarter": "Q2", "revenue": 12, "profit_rate": -10, "profit_abs": -1.2},
      {"quarter": "Q3", "revenue": 28, "profit_rate":   5, "profit_abs":  1.4},
      {"quarter": "Q4", "revenue": 50, "profit_rate":  18, "profit_abs":  9.0}
    ]
  },
  "resolve": {"scale": {"y": "independent"}},
  "width": 500,
  "height": 350,
  "title": {
    "text": "분기별 매출 & 영업이익률",
    "fontSize": 16,
    "subtitle": "막대: 매출(억원) | 실선: 영업이익 절대액(억원) | 점선: 영업이익률(%)",
    "subtitleFontSize": 11
  },
  "layer": [
    {
      "mark": {"type": "bar", "color": "#5B9BD5", "opacity": 0.85, "tooltip": true},
      "encoding": {
        "x": {"field": "quarter", "type": "ordinal", "axis": {"labelFontSize": 12, "title": null}},
        "y": {
          "field": "revenue",
          "type": "quantitative",
          "axis": {"title": "매출·영업이익 (억 원)", "titleFontSize": 13, "grid": true},
          "scale": {"align": 0}
        }
      }
    },
    {
      "mark": {"type": "line", "color": "#ED7D31", "strokeWidth": 2.5, "point": {"size": 80, "filled": true}, "tooltip": true},
      "encoding": {
        "x": {"fi…

채점 근거파생 부호 정확+이중축 0선+5.7KB 충실

2026-05-26 15:59
Grok 4.3xAI
807575757074
```json
{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
  "width": 420,
  "height": 320,
  "data": {
    "values": [
      {"q": "Q1", "revenue": 5, "margin": -0.2, "profit": -1},
      {"q": "Q2", "revenue": 12, "margin": -0.1, "profit": -1.2},
      {"q": "Q3", "revenue": 28, "margin": 0.05, "profit": 1.4},
      {"q": "Q4", "revenue": 50, "margin": 0.18, "profit": 9}
    ]
  },
  "layer": [
    {
      "mark": {"type": "bar", "color": "#5470c6", "width": 28},
      "encoding": {
        "x": {"field": "q", "type": "ordinal", "title": null},
        "y": {
          "field": "revenue",
          "type": "quantitative",
          "title": "금액 (억 원)",
          "axis": {"grid": false}
        }
      }
    },
    {
      "mark": {"type": "bar", "color": "#91cc75", "width": 18},
      "encoding": {
        "x": {"field": "q", "type": "ordinal"},
        "y": {
          "field": "profit",
          "type": "quantitative",
          "axis": null
        }
      }
    },
    {
      "mark": {"type": "line", "color": "#ee6666", "point": {"filled": true, "size": 60}},
      "encoding": {
        "x": {"field": "q", "type": "ordinal"},
        "y": {
          "field": "margin",
          "type": "quantitative",
          "axis": {
            "orient": "right",
            "format": ".0%",
            "title": "영업이익률",
            "grid": false
          }
        }
      }
    }
  ],
  "resolve": {"scale": {"y": "independent"}},
  "config": {
    "axis": {"label…

채점 근거profit -1/-1.2/1.4/9 부호 정확+Vega layer+resolve independent. 단 0선 같은높이 정렬 명시 약함, 1.5KB

2026-05-26 14:11
Mistral Small 4Mistral
858080758080
# Recharts를 사용한 이중축 차트 코드

아래는 React + Recharts로 작성된 이중축 차트 코드입니다. 요청하신 모든 조건(절대 이익 계산, 음수 렌더링, 축 0선 정렬)을 충족합니다.

```jsx
import React from 'react';
import {
  ComposedChart,
  Bar,
  Line,
  XAxis,
  YAxis,
  CartesianGrid,
  Tooltip,
  Legend
} from 'recharts';

// 데이터: 매출(억원), 영업이익률(%), 계산된 영업이익(억원)
const data = [
  { quarter: 'Q1', sales: 5, profitMargin: -20, operatingProfit: -1 },
  { quarter: 'Q2', sales: 12, profitMargin: -10, operatingProfit: -1.2 },
  { quarter: 'Q3', sales: 28, profitMargin: 5, operatingProfit: 1.4 },
  { quarter: 'Q4', sales: 50, profitMargin: 18, operatingProfit: 9 }
];

function SalesProfitChart() {
  return (
    <div style={{ width: '800px', margin: '20px' }}>
      <ComposedChart
        data={data}
        margin={{ top: 20, right: 80, bottom: 20, left: 80 }}
      >
        {/* 격자선 */}
        <CartesianGrid strokeDasharray="3 3" />

        {/* X축 (분기) */}
        <XAxis dataKey="quarter" />

        {/* 왼쪽 Y축 (억원) - 매출(막대)과 영업이익(선) */}
        <YAxis
          yAxisId="left"
          orientation="left"
          stroke="#8884d8"
          domain={[-50, 50]} // 음수/양수 모두 포함하며 0선 정렬
          label={{
            value: '매출/영업이익 (억원)',
            angle: -90,
            position: 'insideLeft',
            offset: -10
          }}
        />

        {/* 오른쪽 Y축 (퍼센트) - 영업이익률 */}
        <YAxis
          yAxisId="right"
          orientation="right"
          stroke="#82ca9d"
          domain={[-20, 20]} // 음수/양수 모두 포함하며 0선 정렬
          label…

채점 근거파생 부호 정확+이중축+0선

2026-05-26 14:35
DeepSeek V4 FlashDeepSeek
858080758080
아래는 **Recharts**를 사용한 이중축 차트 코드입니다.  
데이터에 포함된 **매출(억)** 과 **영업이익 절대액(억)** 은 좌측 Y축(억), **영업이익률(%)** 은 우측 Y축(%)으로 표시되며,  
**두 축의 0선이 반드시 같은 높이**에 오도록 대칭 도메인을 적용했습니다.  
(반올림 없이 계산되었으며, Q1·Q2의 적자 막대는 0선 아래로 정확히 렌더링됩니다.)

```jsx
import React from 'react';
import {
  BarChart, Bar, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer
} from 'recharts';

// 원본 데이터 (매출: 억 원, 영업이익률: %)
const rawData = [
  { quarter: 'Q1', revenue: 5,  margin: -20 },
  { quarter: 'Q2', revenue: 12, margin: -10 },
  { quarter: 'Q3', revenue: 28, margin: 5  },
  { quarter: 'Q4', revenue: 50, margin: 18 },
];

// 영업이익 절대액(억) = 매출 × 이익률 (반올림 금지, 음수 유지)
const data = rawData.map(d => ({
  ...d,
  profitAbs: d.revenue * d.margin / 100,   // 이익률은 %이므로 100으로 나눔
}));

// 0선 정렬을 위한 대칭 도메인 계산
const leftMax = Math.max(...data.map(d => Math.max(d.revenue, d.profitAbs)));
const leftMin = -leftMax;          // 좌측 축 도메인: [-leftMax, leftMax]
const rightMax = Math.max(...data.map(d => Math.abs(d.margin)));
const rightMin = -rightMax;        // 우측 축 도메인: [-rightMax, rightMax]

export default function DualAxisChart() {
  return (
    <ResponsiveContainer width="100%" height={400}>
      <BarChart data={data} margin={{ top: 20, right: 30, left: 20, bottom: 5 }}>
        <CartesianGrid strokeDasharray="3 3" />
        <XAxis dataKey="quarter" />
        
        {/* 좌측 Y축 (억) */}
        <YAxis
          yAxisId="left"
          domain={[leftMin, leftMax]}
          label={{ value: '억 원', angle: -90, posi…

채점 근거파생 부호 정확+ComposedChart 이중축+0선

2026-05-26 14:32
Qwen 3.5 9BAlibaba
557050727567


요청하신 대로 Recharts 를 사용하여 매출, 영업이익률, 그리고 직접 계산한 영업이익 절대액을 표현하는 이중축 차트 코드를 작성했습니다.

특히 **좌축과 우축이 모두 음수 영역 (적자) 을 포함**하도록 `domain` 을 설정하여 0 선이 정확히 같은 높이에 위치하게 만들었습니다.

### 구현 포인트
1.  **데이터 계산:** `Operating Income` = `Sales` * `Operating Margin` 로 음수 부호를 유지하며 계산했습니다.
2.  **이중축 정렬:** 좌축 (매출, 영업이익 절대액) 과 우축 (영업이익률) 의 `domain` 을 각각 `[0, 50]` 과 `[0, 20]` 으로 고정하여 적자 구간이 0 선 아래로 정확히 내려오게 했습니다.
3.  **가독성 처리:** 매출 (5~50 억) 과 영업이익 절대액 (-1~9 억) 의 차이가 10 배 가까이 나므로, 좌축에 두 계열을 함께 그려도 매출 막대가 훨씬 크게, 영업이익 절대액 막대는 그보다 작게 렌더링되도록 단위 (`unit`) 를 구분하여 표시했습니다.

```jsx
import React from 'react';
import {
  BarChart,
  Bar,
  XAxis,
  YAxis,
  CartesianGrid,
  Tooltip,
  Legend,
  ResponsiveContainer,
  Line,
  ReferenceLine
} from 'recharts';

// 1. 데이터 정의 및 파생값 계산 (반올림 금지, 음수 부호 유지)
const rawData = [
  { name: 'Q1', sales: 5, margin: -20 },
  { name: 'Q2', sales: 12, margin: -10 },
  { name: 'Q3', sales: 28, margin: 5 },
  { name: 'Q4', sales: 50, margin: 18 },
];

const data = rawData.map(item => {
  // 매출 (억) * 이익률 (%) / 100 = 영업이익 절대액 (억)
  const opIncome = item.sales * (item.margin / 100);
  
  return {
    name: item.name,
    sales: item.sales,
    margin: item.margin,
    opIncome: opIncome // 직접 계산된 값
  };
});

export default function DualAxisChart() {
  return (
    <div style={{ width: '800px', height: '500px', margin: '0 auto' }}>
      <h3 style={{ textAlign: 'center' }}>분기별 매출 및 이익 구조 (1 억원 기준)</h3>
      
      <ResponsiveContainer width="100%" height="100%">
        <BarChart
          …

채점 근거이중축 영업이익 파생+0선(F, ★g 변별): 파생계산은 정확 — opIncome=sales*(margin/100)으로 Q1 -1.0·Q2 -1.2·Q3 +1.4·Q4 +9.0 부호 유지(계산 anchor 통과). 그러나 ★0선 정렬 discriminator 실패: 좌축 domain={[0,60]}·우축={[0,25]}로 설정해 음수 구간이 아예 렌더 불가(적자 막대 클리핑)인데, 산문은 정반대로 '음수 영역 포함하도록 domain 설정해 0선 같은 높이'라고 자신있게 허위 주장(c 감점). 추가로 BarChart에 Line 자식(혼합은 ComposedChart 필요)→선 미렌더 + Tooltip 다중 중첩. 계산은 맞으나 차트 구성이 핵심 함정을 정면 위반.

2026-06-04 02:39
Solar Pro 3Upstage
456540506557
아래 예시는 **React + Recharts** 로 구현한 이중축 차트(막대‑선형) 코드와, **Vega‑Lite JSON** 두 가지 형태로 제공합니다.  

- **매출(억)** → 좌축(`y`) : 0선이 차트 상단에 위치하도록 `domain={[0, maxY]}` 로 고정  
- **영업이익률(%)** → 우축(`rightY`) : 0%가 좌축 0과 같은 높이에 오도록 `domain={[-20, 18]}` 로 지정  
- **영업이익(억)** → 좌축에 보조 시리즈(점) 로 표시  
- Q1·Q2는 음수이므로 막대가 **x‑축 아래** 로 정확히 그려집니다.  

> **주의**  
> * 모든 값은 입력값을 그대로 사용했으며, 반올림·보간은 하지 않았습니다.  
> * 차트가 렌더링될 때 y‑축 스케일이 0을 기준으로 맞춰지므로, 매출·영업이익 모두 0선 위에(막대는 x‑축 위에) 표시됩니다.

---

## 1️⃣ React + Recharts (TypeScript)

```tsx
// App.tsx
import React from "react";
import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, Legend,
         LineChart, Line, ReferenceLine, ResponsiveContainer } from "recharts";

const data = [
  {
    quarter: "Q1",
    sales: 5,          // 억 원
    profitRatePct: -20, // %
    profit: -100,      // 억 원 (sales × profitRate/100)
  },
  {
    quarter: "Q2",
    sales: 12,
    profitRatePct: -10,
    profit: -120,
  },
  {
    quarter: "Q3",
    sales: 28,
    profitRatePct: 5,
    profit: 140,
  },
  {
    quarter: "Q4",
    sales: 50,
    profitRatePct: 18,
    profit: 900,
  },
];

const App = () => {
  const maxSales = Math.max(...data.map(d => d.sales)); // 50
  const maxProfit = Math.max(...data.map(d => d.profit)); // 900

  return (
    <ResponsiveContainer width="100%" height={400}>
      {/* 좌축 : 매출 + 영업이익 표시 */}
      <BarChart
        data={data}
        layout="vertical"
        margin={{
          top: 20,
          right: 50,
          bottom: 50,
          left: 60,
        }}
        // 좌축이 0을 기준으로 고정
        yAxis={{ domain: [0, maxSales] }}
      >
        <CartesianGrid vertical={false} strokeDasharray="3 3" />
        {/* 매출 막대 */}
        <Bar dataKey="sales" fill="#4caf50" barSize={30} />
        {/* 영업이익 점 (좌축에 보조 시리즈) */}
        <Bar dataKey="profit" fill="#ff9800" barSize={10} shape={shapeProps} />
        <XAxis dataKey="quarter" />
        <YAxis
          type="number"
          tickFormatter={tick => `${tick}억`}
          label={{ value: "매출 (억 원)", angle: -90, position: "insideLeft" }}
        />
        <Tooltip
          labelFormatter={label => label}
          formatter={(value, name, props) => {
            const d = props?.payload as typeof data[0];
            if (name === "sales") return [`매출`, `${value}억`];
            if (name === "profit") return [`영업이익`, `${value}억`];
            return [`영업이익률`, `${value}%`];
          }}
        />
        <Legend />
      </BarChart>

      {/* 우축 : 영업이익률 표시 – 좌축 0과 같은 높이에 0%가 오도록 domain 지정 */}
      <LineChart
        data={data}
        layout="horizontal"
        margin={{ top: 50, right: 20, bottom: 20, left: 60 }}
        // 우축이 0%를 좌축 0과 같은 높이에 맞추기 위해 domain을 직접 지정
        rightYAxis={{
          domain: [-20, 18], // 최소 -20%, 최대 18%
          tickFormatter: (v: number) => `${v}%`,
          label: { value: "영업이익률 (%)", angle: 0, position: "outerBottom" },
        }}
      >
        <CartesianGrid vertical={false} />
        {/* 영업이익률 꺾은선 */}
        <Line
          type="monotone"
          dataKey="profitRatePct"
          stroke="#1976d2"
          strokeWidth={2}
          dot={{ r: 4 }}
          dotRadius={4}
          dot={{ stroke: "#fff", strokeWidth: 2 }}
        />
        {/* 좌축 0을 기준으로 한 기준선 – 차트가 0%를 정확히 맞춰 그리도록 */
        <ReferenceLine
          x={0}
          stroke="#d32f2f"
          strokeDasharray="3 3"
          label={{
            value: "0%",
            position: "right",
            dx: -10,
            dy: -10,
          }}
        />
      </LineChart>
    </ResponsiveContainer>
  );
};

/* 영업이익 막대는 높이보다 가로 길이로 표시하기 위해 shape 커스터마이징 */
const shapeProps = (props: any) => {
  const { x, y, width, height, payload } = props;
  // y는 실제 값(매출) / height는 막대 전체 높이 → 비율을 이용해 가로 길이 계산
  const ratio = height / (maxSales - 0); // maxSales는 50, 0은 차트 상단
  const barHeight = height * (-payload.profit / maxProfit); // profit가 음수면 barHeight도 음수 → 화면 아래쪽(음수)으로 이동
  // profit가 양수이면 위쪽(양수)으로 이동
  const dy = barHeight >= 0 ? barHeight : -barHeight; // 절대값 사용
  const xPos = x - width / 2 - dy; // profit가 음수이면 오른쪽으로 이동, 양수이면 왼쪽으로 이동
  const yPos = height - payload.profit; // profit값만큼 y축 이동

  return (
    <g transform={`translate(${xPos},${yPos})`}>
      <rect x={-width / 2} y={0} width={width} height={height} fill="#ff9800" />
    </g>
  );
};

export default App;
```

### 핵심 포인트

| 항목 | 설정 |
|------|------|
| **좌축 도메인** | `domain={[0, maxSales]}` → 매출이 0보다 작아도 0이 차트 상단에 고정 |
| **우축 도메인** | `rightYAxis.domain = [-20, 18]` → 0%가 좌축 0과 같은 위치에 오도록 |
| **영업이익 절대액** | `profit = sales * profitRatePct / 100` 로 직접 계산 (반올림·보간 없음) |
| **음수 막대** | `shapeProps` 에서 profit가 음수이면 `x` 위치를 오른쪽으로, `y` 위치를 아래로 이동시켜 x‑축(0) 아래에 표시 |
| **0선 정렬** | 좌축 0과 우축 0%가 `domain` 을 맞춰 설정했으므로 차트 상에서 동일한 높이에 위치 |

---

## 2️⃣ Vega‑Lite JSON

```json
{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
  "description": "분기별 매출·영업이익률·영업이익(이중축 차트)",
  "data": {
    "values": [
      {"quarter":"Q1","sales":5,"profitRatePct":-20,"profit":-100},
      {"quarter":"Q2","sales":12,"profitRatePct":-10,"profit":-120},
      {"quarter":"Q3","sales":28,"profitRatePct":5,"profit":140},
      {"quarter":"Q4","sales":50,"profitRatePct":18,"profit":900}
    ]
  },

  "width": 600,
  "height": 400,

  /* ────────────────── 좌축 : 매출 + 영업이익 ────────────────── */
  "layer": [
    {
      "mark": {
        "type": "bar",
        "color": "#4caf50"
      },
      "encoding": {
        "x": {"field": "quarter", "type": "ordinal", "axis": {"labelAngle": 0}},
        "y": {
          "field": "sales",
          "type": "quantitative",
          "scale": {"domain": [0, 50]},   // 0을 상단에 고정
          "axis": {"title": "매출 (억)", "labelExpr": "format(datum, '0.0') + '억'"}
        },
        "tooltip": [
          {"field": "quarter","type":"nominal","title":"분기"},
          {"field": "sales","type":"quantitative","title":"매출 (억)"},
          {"field": "profitRatePct","type":"quantitative","title":"영업이익률 (%)"},
          {"field": "profit","type":"quantitative","title":"영업이익 (억)"}
        ]
      }
    },

    {
      "mark": {
        "type": "bar",
        "color": "#ff9800",
        "opacity": 0.6
      },
      "encoding": {
        "x": {"field": "quarter", "type": "ordinal"},
        "y": {
          "field": "profit",
          "type": "quantitative",
          "scale": {"domain": [-100, 900]}, // 0이 좌축 0과 같은 높이에 오도록 좌축 0을 기준으로
          "axis": {"title": "영업이익 (억)", "labelExpr": "format(datum, '0.0') + '억'"}
        },
        "tooltip": [
          {"field": "quarter","type":"nominal","title":"분기"},
          {"field": "sales","type":"quantitative","title":"매출 (억)"},
          {"field": "profitRatePct","type":"quantitative","title":"영업이익률 (%)"},
          {"field": "profit","type":"quantitative","title":"영업이익 (억)"}
        ]
      }
    }
  ],

  /* ────────────────── 우축 : 영업이익률 (선) ────────────────── */
  {
    "layer": [
      {
        "mark": {"type": "line", "color": "#1976d2", "strokeWidth": 2},
        "encoding": {
          "x": {"field": "quarter", "type": "ordinal", "axis": {"labelAngle": 0}},
          "y": {
            "field": "profitRatePct",
            "type": "quantitative",
            "scale": {"domain": [-20, 18]}, // 0%가 좌축 0과 같은 높이에 오도록
            "axis": {
              "title": "영업이익률 (%)",
              "offset": 0,
              "orient": "right",
              "format": ".0",
              "labelExpr": "datum + '%'"
            },
            "legend": null
          },
          "tooltip": [
            {"field": "quarter","type":"nominal","title":"분기"},
            {"field": "profitRatePct","type":"quantitative","title":"영업이익률 (%)"}
          ]
        }
      }
    ],

    "config": {
      "view": {"stroke": "transparent"},
      "axisY": {
        "domain": true,
        "grid": true,
        "tickCount": {"max": 6},
        "titleFontSize": 12,
        "labelFontSize": 11
      },
      "axisX": {
        "domain": true,
        "grid": false,
        "labelAngle": 0,
        "titleFontSize": 12,
        "labelFontSize": 11
      }
    }
  }
}
```

### Vega‑Lite 옵션 설명

| 옵션 | 의미 |
|------|------|
| `scale.domain` (좌축) | `domain: [0, maxSales]` → 매출이 0보다 작아도 0이 차트 상단에 고정됩니다. |
| `scale.domain` (우축) | `domain: [-20, 18]` → 0%가 좌축 0과 같은 위치에 오도록 맞춤. |
| `tooltip` | 마우스 오버 시 **분기 / 매출(억) / 영업이익률(%) / 영업이익(억)** 을 모두 표시합니다. |
| `layer` | 좌축에 **매출 막대**와 **영업이익 막대**를 겹쳐 그리며, 색상은 구분합니다. |
| `config.axisY.domain` | 좌·우축 모두 실제 데이터 도메인을 그리므로 0선이 정확히 맞춰집니다. |

---

### 📌 적용 팁

1. **반올림·보간 금지**  
   - 위 코드에서는 `sales`, `profitRatePct`, `profit` 를 그대로 사용했습니다.  
   - `profit` 은 `sales * profitRatePct / 100` 로 계산했으며, 소수점 이하까지 그대로 유지됩니다.

2. **음수 막대 위치**  
   - Recharts 의 `shapeProps` 로 profit 가 음수이면 `x` 위치를 오른쪽으로, `y` 를 아래로 이동시켜 x‑축(0) 아래에 정확히 렌더됩니다.  
   - Vega‑Lite 은 `scale.domain` 에 음수를 포함시키면 자연스럽게 0선 아래에 표시됩니다.

3. **축 0선 정렬**  
   - 좌축 `domain: [0, max]` 로 0을 상단에 고정하고, 우축도 `domain: [-maxNeg, maxPos]` 로 지정하면 두 축의 0선이 화면 상에서 같은 높이에 겹쳐 보이게 됩니다.

4. **시각적 구분**  
   - 매출 막대: 초록색 `#4caf50`  
   - 영업이익 막대: 주황색 `#ff9800` (투명도 0.6)  
   - 영업이익률 꺾은선: 파란색 `#1976d2`  

위 코드를 그대로 복사‑붙여넣기 하면 **분기별 매출·영업이익률·영업이익**을 정확히 표현한 이중축 차트를 바로 확인할 수 있습니다. 필요에 따라 색상·툴팁·레이아웃을 조정해 사용하세요!

채점 근거layout='vertical' 오용(가로막대), profit를 sales×rate인데 Q1 -100으로 ×100 오산(-1이 정답), domain[0,maxSales]로 음수 클립하면서 '막대가 x축 아래'라 자가모순. Recharts/Vega 2종 다 결함.

2026-05-28 23:12
HyperCLOVAX SEED Think 32BNaver
608060608072


다음은 사용자 요구사항을 충족하는 Vega-Lite 스펙입니다. 음수 0선 정렬을 위해 양쪽 y축 도메인을 대칭으로 설정하고, 영업이익 절대액 계산을 포함했습니다.

```json
{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
  "width": 300,
  "height": 200,
  "data": {
    "values": [
      {"Quarter": "Q1", "Revenue": 5, "Operating Margin": -20},
      {"Quarter": "Q2", "Revenue": 12, "Operating Margin": -10},
      {"Quarter": "Q3", "Revenue": 28, "Operating Margin": 5},
      {"Quarter": "Q4", "Revenue": 50, "Operating Margin": 18}
    ]
  },
  "transform": [
    {
      "calculate": "datum.Revenue * datum['Operating Margin'] / 100",
      "as": "Operating Profit"
    }
  ],
  "encoding": {
    "x": {"field": "Quarter", "type": "ordinal", "axis": {"labelAngle": 0}}
  },
  "layer": [
    {
      "mark": "bar",
      "encoding": {
        "y": {
          "field": "Revenue",
          "type": "quantitative",
          "axis": {"title": "매출 (억)"},
          "scale": {"domain": [-20, 200]}
        },
        "y2": {"value": 0},
        "color": {"value": "#4c78a8"}
      }
    },
    {
      "mark": "bar",
      "encoding": {
        "y": {
          "field": "Operating Profit",
          "type": "quantitative",
          "axis": {"title": "영업이익 (억)"},
          "scale": {"domain": [-9, 9]}
        },
        "y2": {"value": 0},
        "color": {"value": "#d62728"}
      }
    },
    {
      "mark": {
        "type": "line",
        "point": true
      },
      "encoding": {
        "y": {
          "field": "Operating Margin",
  …

채점 근거영업이익 파생 Q1-1.0/Q2-1.2/Q3+1.4/Q4+9.0 transform 정확·부호유지·반올림없음(F trap 통과). 영업이익/률 [-9,9]/[-18,18] 대칭 0선정렬. 그러나 resolve.scale.y=independent 누락(레이어 충돌)·매출[-20,200] 비대칭.

2026-05-29 15:12
Kanana 2 30B-A3B ThinkingKakao
456040506054
다음은 Recharts를 사용하여 요구사항을 충족하는 이중 축 차트 구현입니다:

```jsx
import React from 'react';
import {
  LineChart,
  CartesianGrid,
  XAxis,
  YAxis,
  Tooltip,
  Legend,
  Line,
  Bar,
  ResponsiveContainer
} from 'recharts';

const data = [
  { quarter: 'Q1', revenue: 5, margin: -20, profit: -1 },
  { quarter: 'Q2', revenue: 12, margin: -10, profit: -1.2 },
  { quarter: 'Q3', revenue: 28, margin: 5, profit: 1.4 },
  { quarter: 'Q4', revenue: 50, margin: 18, profit: 9.0 }
];

const RevenueBar = ({ data }) => (
  <Bar dataKey="revenue" fill="#8884d8" />
);

const OperatingProfitLine = ({ data }) => (
  <Line dataKey="profit" stroke="#82ca9d" />
);

const OperatingMarginLine = ({ data }) => (
  <Line dataKey="margin" stroke="#ffc658" />
);

const Chart = () => {
  const minLeft = Math.min(...data.map(d => d.revenue), ...data.map(d => d.profit));
  const maxLeft = Math.max(...data.map(d => d.revenue), ...data.map(d => d.profit));
  const minRight = Math.min(...data.map(d => d.margin));
  const maxRight = Math.max(...data.map(d => d.margin));

  return (
    <ResponsiveContainer width="100%" height={300}>
      <LineChart
        data={data}
        margin={{
          top: 20,
          right: 20,
          left: 40,
          bottom: 20
        }}
      >
        <CartesianGrid strokeDasharray="3 3" />
        <XAxis dataKey="quarter" />
        <YAxis
          type="number"
          domain={[minLeft, maxLeft]}
          tickFormat={value => `${value}M`}
        />
        <YAxis
          orientation="right"
          type="number"
          domain={[minRight, maxRight]}
          tickFormat={value => `${value}%`}
          name="Margin (%)"
        />
        <Tooltip />
        <Legend />
        <Bar dataKey="revenue" fill="#8884d8" />
        <Line dataKey="profit" stroke="#82ca9d" />
        <Line dataKey="margin" stroke="#ffc658" />
      </LineChart>
    </ResponsiveContainer>
  );
};

export default Chart;
```

주요 구현 특징:

1. **이중 축 구성**:
   - 왼쪽 축(100만 단위): 매출(막대)과 영업이익(라인) 표시
   - 오른쪽 축(%): 영업이익률(라인) 표시

2. **데이터 처리**:
   - 영업이익은 `revenue * (margin / 100)`으로 계산
   - 모든 원본 값이 그대로 사용됨(보간/반올림 없음)

3. **시각적 요구사항**:
   - 음수 값은 0선 아래로 표시됨(Q1/Q2의 손실)
   - 0선이 양 축 모두에서 수직 정렬됨
   - 축 도메인에는 음수 값이 포함됨

4. **시각적 요소**:
   - 매출: 파란색 막대
   - 영업이익: 청록색 라인
   - 영업이익률: 주황색 라인
   - 보조 축 범례

이 구현은 Recharts 컴포넌트를 직접 사용하여, 매출, 영업이익, 영업이익률을 모두 정확하게 표시하는 이중 축 차트를 생성합니다.

채점 근거LineChart 컨테이너에 Bar를 넣어 막대 미렌더(ComposedChart 필요), tickFormat(오타, tickFormatter)·domain 0선 미정렬 등 API 다수 오류.

2026-05-28 08:26
Gemma 4 E2BGoogle
424940424444
요청하신 분기 데이터에 기반하여 매출, 영업이익률, 그리고 영업이익 절대액을 모두 포함하는 이중축 차트 코드를 작성해 드립니다.

**핵심 요구사항 반영 사항:**

1. **영업이익 절대액 계산:** 매출 × 이익률을 사용하여 정확하게 계산했습니다. (Q1: -1.0, Q2: -1.2, Q3: +1.4, Q4: +9.0)
2. **음수 처리:** Q1, Q2의 적자 데이터가 0선 아래로 정확히 렌더링되도록 설정했습니다.
3. **축 동기화:** 두 축의 0선이 정확히 일치하도록 도메인을 조정하여 데이터의 비교 왜곡을 방지했습니다.
4. **데이터 무결성:** 입력값과 파생값에 임의의 반올림이나 보간을 적용하지 않았습니다.

### Recharts 기반 코드 (React 환경 권장)

이 코드는 React 환경에서 `recharts` 라이브러리를 사용하여 구현되었습니다.

```jsx
import React from 'react';
import {
  LineChart,
  Line,
  BarChart,
  Bar,
  XAxis,
  YAxis,
  CartesianGrid,
  Tooltip,
  Legend,
  ResponsiveContainer,
} from 'recharts';

// 1. 데이터 정의 (입력값 및 파생값)
const financialData = [
  {
    quarter: 'Q1',
    revenue: 5, // 억 원
    marginRate: -0.20, // -20%
    absoluteProfit: -1.0, // 5 * -0.20 = -1.0
  },
  {
    quarter: 'Q2',
    revenue: 12, // 억 원
    marginRate: -0.10, // -10%
    absoluteProfit: -1.2, // 12 * -0.10 = -1.2
  },
  {
    quarter: 'Q3',
    revenue: 28, // 억 원
    marginRate: 0.05, // +5%
    absoluteProfit: 1.4, // 28 * 0.05 = 1.4
  },
  {
    quarter: 'Q4',
    revenue: 50, // 억 원
    marginRate: 0.18, // +18%
    absoluteProfit: 9.0, // 50 * 0.18 = 9.0
  },
];

// 2. 커스텀 Tooltip 컴포넌트 (선택 사항)
const CustomTooltip = ({ active, payload, label }) => {
  if (active && payload && payload.length) {
    return (
      <div className="custom-tooltip" style={{ backgroundColor: '#fff', border: '1px solid #ccc', padding: '10px' }}>
        <p className="label">{`분기: ${label}`}</p>
     …

채점 근거이중축 0선 정렬 실패(좌4%/우60%)

2026-06-01 12:43
LFM2.5 8B-A1BLiquid AI
314131323234

Below is a **complete Vega‑Lite specification** that satisfies all of the requirements you listed:

* Two series – Revenue (on the primary axis) and **Operating‑profit absolute** (on the secondary axis).  
* The absolute operating‑profit values are calculated directly from the data you gave (no rounding).  
* The bars / points for Q1 and Q2 are drawn **below** the axis (their values are negative).  
* The two axis zero‑lines are aligned – the left‑hand axis (revenue) and the right‑hand axis (profit‑absolute) share the same “zero” height (the numeric value 0).  

```json
{
  "$schema": "https://vega.github.io/schema/vega-v5.json",
  "description": "Dual‑axis chart: revenue (left) vs. profit absolute (right).",
  "mark": [
    {
      "type": "line",
      "title": "기간",
      "encoding": {
        "x": {
          "type": "band",
          "scale": {
            "type": "linear",
            "range": [-2, 10]               // left‑hand axis range (includes negative & positive)
          }
      },
      "y": {
        "field": "revenue",
        "type": "quantitative",
        "format": "number",
        "axis": {"title": "기획도 (억 원)"}
      }
    },
    {
      "type": "line",
      "title": "영업이익 절대액 (억)",
      "encoding": {
        "x": {
          "type": "point",
          "scale": {
            "type": "linear",
            "range": [-2, 10]               // same numeric range as revenue (zero at 0)
          }
        },
        "y": {
          "field": "abs_profit",
…

채점 근거이중축 Vega-Lite 스펙 깨짐·0선 미정렬

2026-06-01 14:15
HyperCLOVAX SEED 1.5BNaver
172917192222
아래는 Recharts를 사용하여 요청하신 분기 데이터의 이중축 차트를 생성하는 코드입니다. 이 코드는 Q1, Q2, Q3, Q4의 매출과 영업이익률을 시각화하며, 추가 요구사항도 반영하고 있습니다.

```javascript
const data = [
  { time: 'Q1', revenue: 50, profit: -20 },
  { time: 'Q2', revenue: 12, profit: -10 },
  { time: 'Q3', revenue: 28, profit: 5 },
  { time: 'Q4', revenue: 50, profit: 18 }
];

// 차트 설정
const chart = new Recharts(d3.select('body').append('svg').attr({
  width: 600,
  height: 400,
  margin: { top: 50, right: 20, bottom: 50, left: 50 }
/day,
})).append('Recharts')
  .append('Grid')
  .append('X axis')
  .append('D3 distinctions')
  .append('Scale')
  .append('Domain')
  .append('Scale')
  .append('Range')
  .append('Scale')
  .append('Axis')
  .append('H line')
  .append('D3 distinctions')
  .append('Scale')
  .append('Domain')
  .append('Scale')
  .append('Range')
  .append('Scale')
  .append('Axis')
  .append('V line')
  .append('D3 distinctions')
  .append('Scale')
  .append('Domain')
  .append('Scale')
  .append('Range')
  .append('Scale')
  .append('Axis')
  .append('H line')
  .append('D3 distinctions')
  .append('Scale')
  .append('Domain')
  .append('Scale')
  .append('Range')
  .append('Scale')
  .append('Axis')
  .append('V line')
  .append('D3 distinctions')
  .append('Scale')
  .append('Domain')
  .append('Scale')
  .append('Range')
  .append('Scale')
  .append('Axis')
  .append('H line')
  .append('D3 distinctions')
  .append('Scale')
  .append('Domain')
  .append('Scale')
  .append('Range')
  .append('Scale')
  .append('Axis'…

채점 근거매출 데이터 환각+D3 무한루프

2026-06-01 11:27