Skip to content

Instantly share code, notes, and snippets.

@tmcw
Last active February 27, 2017 00:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tmcw/2fe369cfcbff6141b5700cd26a84c1a1 to your computer and use it in GitHub Desktop.
Save tmcw/2fe369cfcbff6141b5700cd26a84c1a1 to your computer and use it in GitHub Desktop.
#[macro_use]
extern crate serde_derive;
extern crate chrono;
extern crate pdf_canvas;
extern crate serde_json;
use serde_json::Value;
use std::fs::File;
use std::path::Path;
use std::io::prelude::*;
use std::fs;
use pdf_canvas::{Pdf, BuiltinFont, FontSource};
use pdf_canvas::graphicsstate::Color;
use chrono::prelude::*;
#[derive(Serialize, Deserialize, Debug)]
struct Song {
artist: String,
title: String,
}
#[derive(Serialize, Deserialize, Debug)]
struct SongTimeline {
song: Song,
positions: Vec<(String, u32)>,
}
// fn date_to_x(date: String) {
// }
fn main() {
println!("Starting");
let file = File::open("reduced.rust.json").unwrap();
let songs: Vec<SongTimeline> = serde_json::from_reader(file).unwrap();
println!("Computing start date");
let start_date = UTC.datetime_from_str("1990-01-01 12:00:00", "%Y-%m-%d %H:%M:%S").unwrap();
let end_date = UTC.datetime_from_str("2017-01-01 12:00:00", "%Y-%m-%d %H:%M:%S").unwrap();
let timespan = end_date.signed_duration_since(start_date).num_weeks() as f32;
println!("Computed");
// The 14 builtin fonts are available
let mut document = Pdf::create("example.pdf").expect("Create pdf file");
println!("Rendering page");
let width = 80000.0;
let font = BuiltinFont::Helvetica;
let height = 2000.0;
document.render_page(width + 10.0, height + 10.0, |canvas| {
// This closure defines the content of the page
let hello = "Hello World!";
let w = font.get_width(24.0, hello) + 8.0;
try!(canvas.set_fill_color(Color::rgb(200, 20, 30)));
try!(canvas.set_stroke_color(Color::rgb(200, 20, 30)));
for song in songs {
let is_post_1990 = song.positions.iter().all(|ref position| {
let date_with_time = position.0.clone() + &" 12:00:00";
let position_date = UTC.datetime_from_str(&date_with_time, "%Y-%m-%d %H:%M:%S")
.unwrap();
position_date.signed_duration_since(start_date).num_days() > 0
});
if is_post_1990 {
let mut i = 0;
for position in song.positions {
let date_with_time = position.0 + &" 12:00:00";
let position_date =
UTC.datetime_from_str(&date_with_time, "%Y-%m-%d %H:%M:%S").unwrap();
let difference = position_date.signed_duration_since(start_date)
.num_weeks();
let x = (((difference as f32) / timespan) * width) + 10f32;
let y = (((position.1 as f32) / 100.0) * height) + 10f32;
if i == 0 {
try!(canvas.left_text(x + 10.0, y, font, 10.0, &song.song.title));
try!(canvas.circle(x, y, 3.0));
try!(canvas.fill());
try!(canvas.move_to(x, y));
} else {
try!(canvas.line_to(x, y));
}
i = i + 1;
}
try!(canvas.stroke());
}
}
})
.expect("Write page");
// Write all pending content, including the trailer and index
document.finish().expect("Finish pdf document");
println!("Done!");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment