Now comes the fun part of the application: creating a picture based on random data provided by people.
The picture will be created by a script that:
loads all contributions from the JSON file
builds a string that contains the SVG code for the picture, based on the contributions
saves the SVG code into a file
The code to create the picture doesn't use any new concepts you didn't see already in the previous chapters. We will just create a new service responsible to create the picture. Proceed as follows:
Create file se_picture_creator.osc in the source code's li_random_arcs directory and copy-paste the following code:
service picture_creator
// file used to store the SVG picture
attribute picture_file type:file default:fa_relative_file.create ( "picture.svg"~ ).make_absolute_file end
command create_picture
in show_contributor_names type:yes_no default:no end // if set to 'yes' then the contributors' names will de drawn
%system_error_handler_input_argument
%system_error_output_argument
script
system.console.write_line ( "Creating picture" )
// load all contributions stored in JSON file into a list
var !indexed_list<contribution> contribution_list
se_contribution_list.get_list ( &
error_handler = i_error_handler ) &
( v_contribution_list = result &
o_error = error )
if o_error #r void then
exit script
end if
// parameters
const positive32 image_width = 800
const positive32 image_height = 800
const string opacity = "0.9"
// 'SVG_string' will contains the SVG code
const mutable_string SVG_string = fa_mutable_string.create_empty
// start of SVG code
SVG_string.append ( """<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="{{image_width.to_string}}" height="{{image_height.to_string}}" xmlns="http://www.w3.org/2000/svg" version="1.1">
<title>Arcs</title>
<desc>Arcs created by random data provided by different sources</desc>
<!-- draw a frame -->
<rect x="1" y="1" width="{{(image_width - 1).to_string}}" height="{{(image_height - 1).to_string}}" fill="none" stroke="blue" stroke-width="1" />
""" )
// coordinates to draw a contributor's name
var positive32 x_name = 10
var positive32 y_name = 22
// coordinates to draw an arc
// var signed_integer32 x_start; x_end = fa_signed_integer32.create ( image_width.value / 2~ )
var signed_integer32 x_start; x_end = image_width / 2
var signed_integer32 y_start; y_end = image_height / 2
var signed_integer32 x_delta; y_delta = 0
// draw the picture
repeat for each contribution contribution in v_contribution_list
if i_show_contributor_names then
// draw the contributor's name
SVG_string.append ( """ <text x = "{{x_name.to_string}}" y = "{{y_name.to_string}}" font-family="Verdana" font-size = "11">{{c_contribution.first_name}} {{c_contribution.last_name}}</text>
""" )
y_name = y_name + 15
end if
// determine the arc's radius based on the contribution's random value
// const positive32 radius = fa_positive32.create ( 20~ + c_contribution.random_number.value * 10~ )
const positive32 radius = 20 + 10 * c_contribution.random_number
// make arcs rotate clockwise
if x_end > x_start then
y_delta = radius
else
y_delta = -radius
end if
if y_end >= y_start
x_delta = -radius
else
x_delta = radius
end if
// calculate new start- and end-points
x_start = x_end
y_start = y_end
x_end = x_start + x_delta
y_end = y_start + y_delta
// create random RGB color
const string color = """rgb({{get_random_color_value}},{{get_random_color_value}},{{get_random_color_value}})"""
// draw one arc
// format for arcs in SVG is:
// A rx ry x-axis-rotation large-arc-flag sweep-flag x y
// (see http://www.w3.org/TR/SVG/paths.html#PathDataEllipticalArcCommands)
SVG_string.append ( """ <path d="M {{x_start.to_string}} {{y_start.to_string}} A {{radius.to_string}} {{radius.to_string}} 0 0 1 {{x_end.to_string}} {{y_end.to_string}}" stroke="{{color}}" fill="none" stroke-width="40" opacity="{{opacity}}"/>
""" )
end repeat
// end of SVG code
SVG_string.append ( "</svg>" )
// store SVG code into file
o_error = se_text_file_IO.store_string_to_new_or_existing_file ( &
string = SVG_string.to_string &
file = a_picture_file &
error_handler = i_error_handler )
if o_error #r void then
exit script
end if
system.console.write_line ( """Ok. The picture has been store to file {{a_picture_file}}.""" )
end script
end command
command get_random_color_value private:yes
out result type:string end
script
o_result = se_random.get_zero_positive32_random ( &
minimum = 0 &
maximum = 255 ).to_string
end
end
end serviceWe could now add again a test script to check if everything works fine. But we will do that in the next chapter and use a different way to test.