Skip to main content

creating-data-visualizations

Published by @askskills

Transform raw data into compelling, shareable charts and visualizations using D3.js, Chart.js, or description-ready specs

Third-Party Content

This skill is created by a third-party developer, not Asterism. While security-scanned, we cannot guarantee safety. By using any skill, you accept our Terms of Service and assume all risk.

Installation
aster install creating-data-visualizations

Universal installation

By installing, you accept the Terms of Service. Skills are third-party content; Asterism is not liable for their use.

README

# Creating Data Visualizations

Transform data into compelling visual stories that inform, persuade, and go viral.

## What This Skill Does

This skill helps you create effective data visualizations by:
- Choosing the right chart type for your data
- Generating production-ready code (D3.js, Chart.js, or pure SVG)
- Adding annotations and storytelling elements
- Optimizing for different platforms (web, social, presentations)

## Chart Selection Guide

### When to Use Each Chart Type

| Data Type | Best Chart | Avoid |
|-----------|-----------|-------|
| **Comparison** (categories) | Bar chart | Pie chart (>5 items) |
| **Trend over time** | Line chart | Pie chart |
| **Part of whole** | Pie/Donut (≤5 items), Treemap | Line chart |
| **Distribution** | Histogram, Box plot | Pie chart |
| **Correlation** | Scatter plot | Bar chart |
| **Ranking** | Horizontal bar | Pie chart |
| **Geographic** | Choropleth map | Bar chart |
| **Flow/Process** | Sankey, Funnel | Scatter plot |
| **Hierarchy** | Treemap, Sunburst | Line chart |

## Chart.js Templates

### Line Chart (Time Series)

```javascript
const config = {
  type: 'line',
  data: {
    labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
    datasets: [{
      label: 'Revenue ($)',
      data: [12000, 19000, 15000, 25000, 22000, 30000],
      borderColor: '#3B82F6',
      backgroundColor: 'rgba(59, 130, 246, 0.1)',
      fill: true,
      tension: 0.4,
      pointRadius: 4,
      pointHoverRadius: 6
    }]
  },
  options: {
    responsive: true,
    plugins: {
      legend: {
        display: false
      },
      title: {
        display: true,
        text: 'Monthly Revenue Growth',
        font: { size: 18, weight: 'bold' }
      },
      annotation: {
        annotations: {
          milestone: {
            type: 'line',
            xMin: 'Apr',
            xMax: 'Apr',
            borderColor: '#10B981',
            borderWidth: 2,
            label: {
              display: true,
              content: 'Product Launch',
              position: 'start'
            }
          }
        }
      }
    },
    scales: {
      y: {
        beginAtZero: true,
        ticks: {
          callback: (value) => '$' + value.toLocaleString()
        }
      }
    }
  }
};
```

### Bar Chart (Comparison)

```javascript
const config = {
  type: 'bar',
  data: {
    labels: ['Product A', 'Product B', 'Product C', 'Product D', 'Product E'],
    datasets: [{
      label: 'Sales',
      data: [65, 59, 80, 81, 56],
      backgroundColor: [
        '#3B82F6', '#3B82F6', '#10B981', '#3B82F6', '#3B82F6'
      ],
      borderRadius: 8,
      barThickness: 40
    }]
  },
  options: {
    indexAxis: 'y',  // Horizontal bars
    responsive: true,
    plugins: {
      legend: { display: false },
      title: {
        display: true,
        text: 'Product Performance Comparison'
      }
    },
    scales: {
      x: {
        grid: { display: false }
      }
    }
  }
};
```

### Donut Chart (Part of Whole)

```javascript
const config = {
  type: 'doughnut',
  data: {
    labels: ['Direct', 'Organic', 'Referral', 'Social', 'Email'],
    datasets: [{
      data: [35, 25, 20, 12, 8],
      backgroundColor: [
        '#3B82F6', '#10B981', '#F59E0B', '#EF4444', '#8B5CF6'
      ],
      borderWidth: 0,
      cutout: '70%'
    }]
  },
  options: {
    responsive: true,
    plugins: {
      legend: {
        position: 'right'
      },
      title: {
        display: true,
        text: 'Traffic Sources'
      }
    }
  }
};
```

## D3.js Templates

### Responsive Line Chart

```javascript
function createLineChart(data, selector) {
  const margin = { top: 40, right: 30, bottom: 50, left: 60 };
  const width = 800 - margin.left - margin.right;
  const height = 400 - margin.top - margin.bottom;

  const svg = d3.select(selector)
    .append('svg')
    .attr('viewBox', `0 0 ${width + margin.left + margin.right} ${height + margin.top + margin.bottom}`)
    .append('g')
    .attr('transform', `translate(${margin.left},${margin.top})`);

  // Scales
  const x = d3.scaleTime()
    .domain(d3.extent(data, d => d.date))
    .range([0, width]);

  const y = d3.scaleLinear()
    .domain([0, d3.max(data, d => d.value) * 1.1])
    .range([height, 0]);

  // Area
  const area = d3.area()
    .x(d => x(d.date))
    .y0(height)
    .y1(d => y(d.value))
    .curve(d3.curveMonotoneX);

  svg.append('path')
    .datum(data)
    .attr('fill', 'rgba(59, 130, 246, 0.1)')
    .attr('d', area);

  // Line
  const line = d3.line()
    .x(d => x(d.date))
    .y(d => y(d.value))
    .curve(d3.curveMonotoneX);

  svg.append('path')
    .datum(data)
    .attr('fill', 'none')
    .attr('stroke', '#3B82F6')
    .attr('stroke-width', 2)
    .attr('d', line);

  // Axes
  svg.append('g')
    .attr('transform', `translate(0,${height})`)
    .call(d3.axisBottom(x).ticks(6))
    .selectAll('text')
    .style('font-size', '12px');

  svg.append('g')
    .call(d3.axisLeft(y).ticks(5).tickFormat(d => '$' + d.toLocaleString()))
    .selectAll('text')
    .style('font-size', '12px');

  // Interactive tooltip
  const tooltip = d3.select(selector)
    .append('div')
    .attr('class', 'tooltip')
    .style('opacity', 0)
    .style('position', 'absolute')
    .style('background', 'white')
    .style('padding', '8px 12px')
    .style('border-radius', '4px')
    .style('box-shadow', '0 2px 8px rgba(0,0,0,0.15)');

  // Dots with hover
  svg.selectAll('.dot')
    .data(data)
    .enter()
    .append('circle')
    .attr('class', 'dot')
    .attr('cx', d => x(d.date))
    .attr('cy', d => y(d.value))
    .attr('r', 4)
    .attr('fill', '#3B82F6')
    .on('mouseover', function(event, d) {
      tooltip.transition().duration(200).style('opacity', 1);
      tooltip.html(`<strong>${d3.timeFormat('%b %Y')(d.date)}</strong><br/>$${d.value.toLocaleString()}`)
        .style('left', (event.pageX + 10) + 'px')
        .style('top', (event.pageY - 10) + 'px');
    })
    .on('mouseout', function() {
      tooltip.transition().duration(500).style('opacity', 0);
    });
}
```

### Animated Bar Chart Race

```javascript
function createBarChartRace(data, selector) {
  const duration = 500;
  const n = 10; // Number of bars to show
  const margin = { top: 16, right: 6, bottom: 6, left: 0 };
  const barSize = 48;
  const height = margin.top + barSize * n + margin.bottom;
  const width = 800;

  const x = d3.scaleLinear([0, 1], [margin.left, width - margin.right]);
  const y = d3.scaleBand()
    .domain(d3.range(n + 1))
    .rangeRound([margin.top, margin.top + barSize * (n + 1 + 0.1)])
    .padding(0.1);

  const color = d3.scaleOrdinal(d3.schemeTableau10);

  const svg = d3.select(selector)
    .append('svg')
    .attr('viewBox', [0, 0, width, height]);

  // Animation loop
  async function animate() {
    for (const keyframe of keyframes) {
      const transition = svg.transition()
        .duration(duration)
        .ease(d3.easeLinear);

      x.domain([0, keyframe[1][0].value]);

      updateBars(transition, keyframe);
      updateLabels(transition, keyframe);
      updateAxis(transition);

      await transition.end();
    }
  }

  animate();
}
```

## Visualization Best Practices

### Color Accessibility

```javascript
// Colorblind-safe palette
const accessiblePalette = [
  '#0072B2',  // Blue
  '#E69F00',  // Orange
  '#009E73',  // Green
  '#CC79A7',  // Pink
  '#F0E442',  // Yellow
  '#56B4E9',  // Light Blue
  '#D55E00',  // Red-Orange
];

// Always include non-color indicators
// ✓ Different shapes for data points
// ✓ Patterns in addition to colors
// ✓ Labels directly on data
// ✓ Sufficient contrast (4.5:1 minimum)
```

### Annotation Tips

```javascript
// Key insight callout
const annotation = {
  type: 'label',
  xValue: 'March',
  yValue: 45000,
  backgroundColor: 'rgba(255, 255, 255, 0.9)',
  borderRadius: 4,
  content: ['↑ 45% increase', 'after campaign launch'],
  font: { size: 12 },
  padding: 8
};

// Trend line
const trendLine = {
  type: 'line',
  borderColor: 'rgba(0, 0, 0, 0.3)',
  borderWidth: 2,
  borderDash: [6, 6],
  label: {
    display: true,
    content: 'Trend: +12% monthly'
  }
};
```

### Data Labels for Social Media

```javascript
// Large, bold numbers for thumbnails
const socialMediaStyle = {
  plugins: {
    datalabels: {
      color: '#fff',
      font: {
        size: 24,
        weight: 'bold'
      },
      formatter: (value) => value + '%',
      anchor: 'center',
      align: 'center'
    }
  }
};
```

## Platform-Specific Optimizations

### For Twitter/X
- **Dimensions**: 1200 x 675px (1.91:1)
- **Key data point prominent** in top-left
- **Minimal text** - let visual do the work
- **Strong contrast** for small displays

### For LinkedIn
- **Dimensions**: 1200 x 627px
- **Professional color palette**
- **Include source citation**
- **Clear title and subtitle**

### For Presentations
- **Dimensions**: 1920 x 1080px (16:9)
- **Minimal elements** - one point per slide
- **Large fonts** (24px minimum)
- **Animate data reveal** for storytelling

### For Websites/Dashboards
- **Responsive** - use viewBox for SVGs
- **Interactive** - tooltips, hover states
- **Loading states** - skeleton or spinner
- **Export options** - PNG, SVG, CSV

## Storytelling Framework

### The Data Story Arc

1. **Hook**: Start with the most surprising insight
2. **Context**: What's the baseline/expectation?
3. **Tension**: Show the gap or problem
4. **Resolution**: Reveal the insight
5. **Call to Action**: What should viewer do?

### Example Narrative

```
HOOK: "Revenue grew 150% in 6 months"
         ↓
CONTEXT: "Industry average is 15% annually"
         ↓
TENSION: "We were flat for 2 years"
         ↓
RESOLUTION: "Product redesign in March changed everything"
         ↓
CTA: "Here's what we learned..."
```

## Output Format

When creating visualizations, provide:

1. **Chart Code** - Production-ready implementation
2. **Design Specs** - Colors, fonts, dimensions
3. **Data Insights** - Key takeaways (2-3 bullets)
4. **Annotation Suggestions** - What to highlight
5. **Platform Optimization** - Size/format for target
6. **Accessibility Notes** - Color contrast, alt text
Comments

Sign in to leave a comment