Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsBlogPro
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Authors
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges
  • Chrome Extension
  • Skill Manager

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

ProTermsPrivacyRefunds
Back to skills

Blog Chart

ASecurity

Generate dark-mode-compatible inline SVG data visualization charts for blog posts. Supports horizontal bar, grouped bar, donut, line, lollipop, area, and radar charts with automatic platform detection (HTML vs JSX/MDX). Enforces chart type diversity, accessible markup (role=img, aria-label), source attribution, and transparent backgrounds. Use whenever the user mentions data visualization, charts, graphs, comparison tables that need to be visualized, or wants to embed inline SVG visualization...

158 stars
0 votes
0 copies
0 views
Added 10/6/2026
content-marketinggoshell

Security Analysis

A100/100

Scanned 10/6/2026

$npx -y skills add NVlabs/Skill2Env --skill blog-chart --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Blog Chart?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Blog Chart
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/nvlabs-blog-chart/badge)](https://www.skillsdirectory.com/skills/nvlabs-blog-chart)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
Files
SKILL.md
---
name: blog-chart
description: >
  Generate dark-mode-compatible inline SVG data visualization charts for blog
  posts. Supports horizontal bar, grouped bar, donut, line, lollipop, area,
  and radar charts with automatic platform detection (HTML vs JSX/MDX).
  Enforces chart type diversity, accessible markup (role=img, aria-label),
  source attribution, and transparent backgrounds. Use whenever the user
  mentions data visualization, charts, graphs, comparison tables that need
  to be visualized, or wants to embed inline SVG visualizations in a blog
  post, even if not invoking blog-write. Use when user says "blog chart",
  "generate chart", "data visualization", "svg chart", "blog graph",
  "visualize data", or when the blog-write workflow identifies chart-worthy
  data points (3+ comparable metrics, trends, before/after data).
user-invokable: false
---

# Blog Chart: Built-In SVG Data Visualization

Generates dark-mode-compatible inline SVG charts for blog posts. Invoked
internally by `blog-write` and `blog-rewrite` when chart-worthy data is
identified. Not a standalone user-facing command.

**Styling source of truth:** `references/visual-media.md`

## Input Format

The writer or researcher passes a chart request:

```
Chart Request:
- Type: horizontal bar
- Title: "AI Citation Sources by Platform"
- Data: ChatGPT 43.8%, Perplexity 6.6%, Google AI Overviews 2.2%, Reddit 7.15%
- Source: Ahrefs, December 2025
- Platform: mdx (or html)
```

## Chart Type Selection

Select based on the data pattern. Diversity is mandatory - never repeat a
type within one post.

| Data Pattern | Best Chart Type |
|-------------|-----------------|
| Before/after comparison | Grouped bar chart |
| Ranked factors / correlations | Lollipop chart |
| Parts of whole / market share | Donut chart |
| Trend over time | Line chart |
| Percentage improvement | Horizontal bar chart |
| Distribution / range | Area chart |
| Multi-dimensional scoring | Radar chart |

## Styling Rules (Non-Negotiable)

All charts must work on both dark and light backgrounds:

```
Text elements:     fill="currentColor"
Grid lines:        stroke="currentColor" opacity="0.08"
Axis lines:        stroke="currentColor" opacity="0.3"
Background:        transparent (no fill on root SVG)
Subtitle text:     fill="currentColor" opacity="0.45"
Source text:        fill="currentColor" opacity="0.35"
Label text:        fill="currentColor" opacity="0.8"
```

### Color Palette

| Color | Hex | Use Case |
|-------|-----|----------|
| Orange | `#f97316` | Primary / highest value |
| Sky Blue | `#38bdf8` | Secondary / comparison |
| Purple | `#a78bfa` | Tertiary / special category |
| Green | `#22c55e` | Quaternary / positive indicator |

For text inside colored elements: `fill="white"` with `fontWeight="800"`.

## Standard SVG Shell (HTML)

```xml
<svg
  viewBox="0 0 560 380"
  style="max-width: 100%; height: auto; font-family: 'Inter', system-ui, sans-serif"
  role="img"
  aria-label="Chart description with key data point"
>
  <title>Chart Title</title>
  <desc>Description for screen readers with all key data points and source</desc>

  <!-- Chart content -->

  <text x="280" y="372" text-anchor="middle" font-size="10" fill="currentColor" opacity="0.35">
    Source: Source Name (Year)
  </text>
</svg>
```

## JSX/MDX Shell (camelCase attributes)

```jsx
<svg
  viewBox="0 0 560 380"
  style={{maxWidth: '100%', height: 'auto', fontFamily: "'Inter', system-ui, sans-serif"}}
  role="img"
  aria-label="Chart description"
>
  <title>Chart Title</title>
  <desc>Description for screen readers</desc>

  {/* Chart content */}

  <text x="280" y="372" textAnchor="middle" fontSize="10" fill="currentColor" opacity="0.35">
    Source: Source Name (Year)
  </text>
</svg>
```

## JSX Attribute Conversion (Required for MDX)

| HTML | JSX |
|------|-----|
| `stroke-width` | `strokeWidth` |
| `stroke-dasharray` | `strokeDasharray` |
| `stroke-linecap` | `strokeLinecap` |
| `text-anchor` | `textAnchor` |
| `font-size` | `fontSize` |
| `font-weight` | `fontWeight` |
| `font-family` | `fontFamily` |
| `class` | `className` |
| `style="..."` | `style={{...}}` |

## Chart Type Construction

### Horizontal Bar Chart

Best for: percentage improvements, single-metric comparisons.

1. Define chart area: x=80, y=40, width=440, height=280
2. Calculate bar height: `chartHeight / dataCount - gap` (gap=8)
3. Calculate bar width: `(value / maxValue) * chartWidth`
4. Position bars: `y = chartY + index * (barHeight + gap)`
5. Label on left (right-aligned at x=75): category name
6. Value label at end of bar: percentage or number
7. Source text at bottom center

### Grouped Bar Chart

Best for: before/after, A vs B comparisons.

1. Define groups along Y axis, bars within each group
2. Use 2 colors (primary + secondary) for the two series
3. Add legend at top: colored square + label for each series
4. Gap between groups > gap within groups

### Donut Chart

Best for: parts of whole, market share.

1. Center: cx=280, cy=180, outer radius=140, inner radius=80
2. Calculate arc segments using cumulative angles
3. Each segment: `<path d="M... A... L... A... Z" fill="color" />`
4. Center text: total or key label
5. Legend below chart with color squares + labels + values

### Line Chart

Best for: trends over time.

1. X axis: time periods, evenly spaced
2. Y axis: value range with 4-5 grid lines
3. Draw grid lines: `stroke="currentColor" opacity="0.08"`
4. Plot data points: `<circle cx=... cy=... r="4" fill="color" />`
5. Connect with: `<polyline points="..." fill="none" stroke="color" strokeWidth="2" />`
6. Optional: area fill below line with `opacity="0.1"`

### Lollipop Chart

Best for: ranked factors, correlations.

1. Horizontal orientation (like bar chart but with circles)
2. Thin line from axis to data point: `stroke="currentColor" opacity="0.15" strokeWidth="1"`
3. Circle at data point: `r="6"` with fill color
4. Value label next to circle
5. Categories on Y axis (left-aligned)

### Area Chart

Best for: distribution, cumulative data.

1. Same as line chart but with filled area below
2. Area fill: `<path d="M... L... L... Z" fill="color" opacity="0.15" />`
3. Line on top: `stroke="color" strokeWidth="2" fill="none"`
4. Grid lines behind the area

### Radar Chart

Best for: multi-dimensional scoring (5-7 axes).

1. Center: cx=280, cy=190
2. Draw concentric polygons for grid (3-4 levels)
3. Calculate axis endpoints at equal angles
4. Plot data points on each axis proportional to value
5. Connect data points with filled polygon: `fill="color" opacity="0.2" stroke="color"`
6. Label each axis at the outer edge

## Output Format

Wrap every chart in a `<figure>` element:

**HTML:**
```html
<figure>
  <svg viewBox="0 0 560 380" style="max-width: 100%; height: auto; font-family: 'Inter', system-ui, sans-serif" role="img" aria-label="[description]">
    <title>[Chart Title]</title>
    <desc>[Full description with data points for screen readers]</desc>
    <!-- chart content -->
    <text x="280" y="372" text-anchor="middle" font-size="10" fill="currentColor" opacity="0.35">
      Source: [Source Name] ([Year])
    </text>
  </svg>
</figure>
```

**MDX:**
```mdx
<figure className="chart-container" style={{margin: '2.5rem 0', textAlign: 'center', padding: '1.5rem', borderRadius: '12px'}}>
  <svg viewBox="0 0 560 380" style={{maxWidth: '100%', height: 'auto', fontFamily: "'Inter', system-ui, sans-serif"}} role="img" aria-label="[description]">
    <title>[Chart Title]</title>
    <desc>[Full description]</desc>
    {/* chart content with camelCase attributes */}
    <text x="280" y="372" textAnchor="middle" fontSize="10" fill="currentColor" opacity="0.35">
      Source: [Source Name] ([Year])
    </text>
  </svg>
</figure>
```

## Quality Checklist (Verify Before Returning)

- [ ] No hardcoded text colors (all use `currentColor`)
- [ ] No white/light backgrounds (transparent or none)
- [ ] Source attribution text present at bottom
- [ ] `role="img"` and `aria-label` present on `<svg>`
- [ ] `<title>` and `<desc>` present inside `<svg>`
- [ ] Chart type not already used in this post
- [ ] If MDX: all attributes camelCased (no hyphens in attribute names)
- [ ] Data values match the source data exactly
- [ ] Color palette uses only approved colors
- [ ] ViewBox is `0 0 560 380` (standard) or justified alternative

Attribution

NVlabsNVlabs
View sourceSee grades on GitHubMore from NVlabs →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Postiz

Postiz is a tool to schedule social media and chat posts to 28+ channels X, LinkedIn, LinkedIn Page, Reddit, Instagram, Facebook Page, Threads, YouTube, Google My Business, TikTok, Pinterest, Dribbble, Discord, Slack, Kick, Twitch, Mastodon, Bluesky, Lemmy, Farcaster, Telegram, Nostr, VK, Medium, Dev.to, Hashnode, WordPress, ListMonk

21281 votes

Serp Analysis

SERP analysis techniques for intent classification, feature identification, and competitive intelligence. Use when analyzing search results for content strategy.

2831 votes

On Page Seo Auditor

This skill performs detailed on-page SEO audits to identify issues and optimization opportunities. It analyzes all on-page elements that affect search rankings and provides actionable recommendations.

1821 votes

Brand

Brand voice, visual identity, messaging frameworks, asset management, brand consistency. Activate for branded content, tone of voice, marketing assets, brand compliance, style guides.

1328090 votes

Release Announcement

Write a release announcement — changelog, blog post, in-app note, or social post — that leads with user impact, names the audience, and includes upgrade/migration steps without filler.

953190 votes
View all in content-marketing →