Here are 5 examples of Data-Driven Graphics tools using Ruby. These cover raster manipulation, programmatic vectors, and specific handling for messy SVG templates exported from tools like Illustrator or Inkscape.

1. Standalone: RMagick (Raster)

This is the classic way to generate memes, social media cards, or certificates. It composites an avatar image onto a base template and draws text dynamically.

File: badge_generator.rb

require 'rmagick'
include Magick

def generate_badge(name, role, avatar_path, template_path)
  # 1. Load the Template
  img = Image.read(template_path).first

  # 2. Composite the User's Avatar (Resize and Overlay)
  avatar = Image.read(avatar_path).first
  avatar.resize_to_fill!(150, 150)
  # Overlay avatar at x:50, y:50
  img.composite!(avatar, 50, 50, OverCompositeOp)

  # 3. Configure Text (Draw)
  text = Draw.new
  text.font_family = 'Helvetica'
  text.pointsize = 48
  text.gravity = CenterGravity
  text.fill = '#FFFFFF'

  # 4. Annotate the image with data
  # x, y, width, height, text
  text.annotate(img, 0, 0, 0, 100, name)
  
  text.pointsize = 32
  text.annotate(img, 0, 0, 0, 200, role)

  # 5. Save
  output_filename = "badge_#{name.downcase.strip}.png"
  img.write(output_filename)
  puts "Generated: #{output_filename}"
end

# Usage
generate_badge("Alice Smith", "Senior Engineer", "avatar.jpg", "template.png")

2. Rails Integration: MiniMagick (Service Object)

In Rails, MiniMagick is often preferred over RMagick to save memory. This example shows how to wrap graphic generation in a Service Object, which is the "Rails Way" to keep controllers clean.

File: app/services/social_card_service.rb

class SocialCardService
  require 'mini_magick'

  def initialize(title, author, bg_image_path)
    @title = title
    @author = author
    @bg_image_path = bg_image_path
  end

  def call
    image = MiniMagick::Image.open(@bg_image_path)

    image.combine_options do |c|
      c.font "Arial"
      c.fill "#FFFFFF"
      
      # Draw Title (Large, Centered)
      c.pointsize "60"
      c.gravity "Center"
      c.draw "text 0,-50 '#{@title}'"

      # Draw Author (Smaller, Bottom Right)
      c.pointsize "30"
      c.gravity "SouthEast"
      c.draw "text 20,20 'By #{@author}'"
    end

    # Return the temp path or upload to S3 here
    image.path
  end
end

# Usage in a Controller:
# path = SocialCardService.new("New Feature Launch", "Dev Team", "assets/bg.jpg").call
# send_file path, type: 'image/jpeg', disposition: 'inline'

3. Standalone: Victor (Programmatic SVG)

If you don't have a template and want to draw pure vector graphics (like charts or geometric badges) from code, Victor is the cleanest Ruby DSL.

File: chart_builder.rb

require 'victor'

# Data to visualize
data = { "Ruby" => 80, "Python" => 70, "Go" => 90 }

svg = Victor::SVG.new width: 400, height: 300, style: { background: '#f0f0f0' }

svg.build do
  # Title
  text "Language Popularity", x: 200, y: 40, text_anchor: "middle", 
       font_family: "Arial", font_weight: "bold"

  # Draw Bars dynamically
  x_pos = 50
  data.each do |lang, score|
    # Bar
    rect x: x_pos, y: (250 - score * 2), width: 50, height: (score * 2), fill: "#456789"
    
    # Label
    text lang, x: x_pos + 25, y: 270, text_anchor: "middle", font_size: 12
    
    x_pos += 100
  end
end

# Save
svg.save 'chart'
puts "Generated chart.svg"

4. Standalone: Nokogiri (The "Inkscape/Illustrator" Fix)

The Context: When you design in Illustrator or Inkscape and edit text, the software often splits a single word into multiple <tspan> tags for kerning (e.g., <text><tspan>He</tspan><tspan>llo</tspan></text>). A simple string replace fails here.

The Solution: Assign an ID to the text element in your design tool (e.g., id="employee_name"). This script finds that ID, deletes all messy tspans inside it, and inserts clean text.

File: vector_template_processor.rb