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.
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")
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'
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"
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