In [1]:
#require "vg,vg.svg"
In [2]:
open Gg
open Vg
In [3]:
type svg_render = Gg.size2 * Gg.box2 * Vg.image
In [4]:
let gray = I.const (Gg.Color.gray 0.9)
In [26]:
let string_of_svg ?(xml_decl=false) (size,view,image) =
let buffer = Buffer.create 1024 in
let r = Vgr.create (Vgr_svg.target ~xml_decl ()) (`Buffer buffer) in
ignore (Vgr.render r (`Image (size, view, image)));
ignore (Vgr.render r `End);
Buffer.contents buffer
In [32]:
let print_svg fmt svg =
Iocaml.display
"text/html"
("<object data=" ^ Iocaml.data_uri "image/svg+xml" (string_of_svg svg) ^ "></object>")
;;
#install_printer print_svg
In [33]:
(Size2.v 30. 30., Box2.unit, gray)
This is the minimal example modified for the printer
In [34]:
(* 1. Define your image *)
let aspect = 1.618
let size = Size2.v (aspect *. 100.) 100. (* mm *)
let view = Box2.v P2.o (Size2.v aspect 1.)
let image = I.const (Color.v_srgb 0.314 0.784 0.471)
(* 2. Render *)
let _ = size, view, image
This is the pie ambiguity example from the website
In [35]:
let size = (Size2.v 90. 138.)
let view = (Box2.v P2.o (Size2.v 1.5 2.3))
let f = begin fun _ ->
let pie_chart r colors pcts =
let rv = V2.v r r in
let sector (acc, start) color pct =
let stop = start +. (pct /. 100.) *. Float.two_pi in
let sector =
P.empty >>
P.line (V2.polar r start) >> P.earc rv (V2.polar r stop) >>
P.line P2.o
in
acc >> I.blend (color >> I.cut sector), stop
in
fst (List.fold_left2 sector (I.void, Float.pi_div_2) colors pcts)
in
let bar_chart bar_size pad colors pcts =
let w, h = V2.to_tuple bar_size in
let font =
{ Font.name = "Open Sans"; slant = `Normal; weight = `W400;
size = (h *. 0.015) }
in
let mgray = I.const (Color.gray 0.3) in
let lgray = I.const (Color.gray 0.75) in
let bar (acc, x) color pct =
let bar =
let box = Box2.v P2.o (Size2.v w ((pct /. 100.) *. h)) in
color >> I.cut (P.empty >> P.rect box)
in
let label =
let text = Printf.sprintf "%g" pct in
let pos = P2.v (0.275 *. w) (-1.4 *. font.Font.size) in
mgray >> I.cut_glyphs ~text font [] >> I.move pos
in
let x = x +. pad in
acc >> I.blend (bar >> I.blend label >> I.move (V2.v x 0.)), x +. w
in
let bars, xmax = List.fold_left2 bar (I.void, 0.) colors pcts in
let floor =
let ln = P.empty >> P.sub (P2.v pad 0.) >> P.line (P2.v xmax 0.) in
lgray >> I.cut ~area:(`O { P.o with P.width = h *. 0.001 }) ln
in
bars >> I.blend floor
in
let distribs = [[ 23.; 22.; 20.; 18.; 17.];
[ 20.; 20.; 19.; 21.; 20.];
[ 17.; 18.; 20.; 22.; 23.]]
in
let colors = (* Brewer's Set2, http://colorbrewer.org/ *)
let c r g b = I.const (Color.v_srgbi r g b) in
[c 102 194 165; c 252 141 98; c 141 160 203; c 231 138 195; c 166 216 84]
in
let bar_and_pie (acc, y) pcts =
let pie = pie_chart 0.25 colors pcts in
let bars = bar_chart (Size2.v 0.08 2.) 0.04 colors pcts in
let bp = bars >> I.blend (pie >> I.move (V2.v 1.0 0.25)) in
acc >> I.blend (bp >> I.move (V2.v 0. y)), y +. 0.75
in
let white = I.const Color.white in
let charts = fst (List.fold_left bar_and_pie (white, 0.) distribs) in
charts >> I.move (V2.v 0.125 0.15)
end
In [36]:
(size,view,f())
Daniel suggests that legalizing the SVG for HTML is a better approach. Indeed the data-uri scheme seems to cause problems with nbviewer.
In [37]:
#require "cow,cow.syntax"
In [46]:
let svg = string_of_svg ~xml_decl:false (size, view, image)
let xml = Cow.Xml.of_string svg
In [47]:
let converted = Cow.Xml.to_string xml