# Chart Templates — Implementation Code

> Load on demand when you need specific chart code. Do NOT load upfront.

---

## Native Excel Charts (openpyxl.chart)

### Bar Chart
```python
from openpyxl.chart import BarChart, Reference
from templates.base import make_chart_title

chart = BarChart()
chart.type = "col"
chart.title = make_chart_title("Revenue by Product", 14)
chart.y_axis.title = make_chart_title("Revenue ($)", 10, bold=False, axis=True)
chart.x_axis.title = make_chart_title("Product", 10, bold=False)

data = Reference(ws, min_col=3, min_row=4, max_col=3, max_row=last_row)
cats = Reference(ws, min_col=2, min_row=5, max_row=last_row)

chart.add_data(data, titles_from_data=True)
chart.set_categories(cats)
chart.shape = 4
chart.width = 18
chart.height = 10

ws.add_chart(chart, "J4")
```

### Line Chart
```python
from openpyxl.chart import LineChart, Reference
from templates.base import make_chart_title

chart = LineChart()
chart.title = make_chart_title("Monthly Trend", 14)
chart.y_axis.title = make_chart_title("Amount", 10, bold=False, axis=True)
chart.style = 10

data = Reference(ws, min_col=3, max_col=5, min_row=4, max_row=last_row)
cats = Reference(ws, min_col=2, min_row=5, max_row=last_row)

chart.add_data(data, titles_from_data=True)
chart.set_categories(cats)
for series in chart.series:
    series.smooth = True

ws.add_chart(chart, "J4")
```

### Pie Chart
```python
from openpyxl.chart import PieChart, Reference
from openpyxl.chart.label import DataLabelList
from templates.base import make_chart_title

chart = PieChart()
chart.title = make_chart_title("Market Share", 14)

data = Reference(ws, min_col=3, min_row=4, max_row=last_row)
cats = Reference(ws, min_col=2, min_row=5, max_row=last_row)

chart.add_data(data, titles_from_data=True)
chart.set_categories(cats)

chart.dataLabels = DataLabelList()
chart.dataLabels.dLblPos = 'bestFit'
chart.dataLabels.showLeaderLines = True
chart.dataLabels.showCatName = True
chart.dataLabels.showPercent = True
chart.dataLabels.showVal = False

ws.add_chart(chart, "J4")
```

### Combo Chart (Bar + Line, dual axis)
```python
from openpyxl.chart import BarChart, LineChart, Reference
from templates.base import make_chart_title

bar = BarChart()
bar.add_data(Reference(ws, min_col=2, max_col=2, min_row=1, max_row=10), titles_from_data=True)
bar.title = make_chart_title("Revenue vs Growth", 14)
bar.y_axis.title = make_chart_title("Revenue ($)", 10, bold=False, axis=True)

line = LineChart()
line.add_data(Reference(ws, min_col=3, max_col=3, min_row=1, max_row=10), titles_from_data=True)
line.y_axis.title = make_chart_title("Growth %", 10, bold=False, axis=True)
line.y_axis.axId = 200

bar += line
ws.add_chart(bar, "E2")
```

---

## Matplotlib Charts (embedded as images)

### Chinese Font Setup
```python
import matplotlib
import matplotlib.pyplot as plt
import os

_font_path = os.path.join(os.path.dirname(__file__), '..', '..', '..', 'fonts', 'truetype', 'chinese', 'SimHei.ttf')
if not os.path.exists(_font_path):
    # Fallback: try workspace fonts
    _font_path = os.path.expanduser('~/.openclaw/workspace/fonts/truetype/chinese/SimHei.ttf')
if os.path.exists(_font_path):
    matplotlib.font_manager.fontManager.addfont(_font_path)
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
```

### Standard Template
```python
fig, ax = plt.subplots(figsize=(10, 6))
ax.bar(categories, values, color='#4A90D9')
ax.set_title('Chart Title', fontsize=14, fontweight='bold', pad=15)
ax.set_xlabel('X Label', fontsize=11)
ax.set_ylabel('Y Label', fontsize=11)
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.tick_params(axis='x', rotation=45)
fig.tight_layout(pad=2.0)
plt.legend(loc='best', fontsize='small')
fig.savefig('chart.png', dpi=150, bbox_inches='tight', facecolor='white')
plt.close()
```

### Embed in Excel (preserving aspect ratio)
```python
from openpyxl.drawing.image import Image as XlImage
from PIL import Image as PILImage

pil_img = PILImage.open('chart.png')
orig_w, orig_h = pil_img.size
target_w = 600
scale = target_w / orig_w

xl_img = XlImage('chart.png')
xl_img.width = target_w
xl_img.height = int(orig_h * scale)

ws.add_image(xl_img, 'B20')
```

### Smart Chart Recommend Function
```python
def recommend_chart(df, x_col, y_cols):
    if pd.api.types.is_datetime64_any_dtype(df[x_col]):
        return "line"
    n_categories = df[x_col].nunique()
    n_series = len(y_cols)
    if n_series == 1:
        vals = df[y_cols[0]]
        if vals.sum() > 95 and vals.sum() < 105:
            return "pie" if n_categories <= 5 else "bar_horizontal"
    if n_categories <= 6:
        return "bar_grouped" if n_series > 1 else "bar"
    elif n_categories <= 15:
        return "bar_horizontal"
    else:
        return "bar_top10"
```
