= Introduction = This project is focused on using STL containers in order to graph data on a one-dimensional and two-dimensional (and if time allows, 3D!) plot. The plot would be written in an `svg` image, compliant with the W3C standard. The goals of the project are as follows: * To let users produce a simple plot with minimal intervention by using sane defaults * To demonstrate how to incorporate SVG images into Boost documentation * To allow users to easily customize graphs to their heart's content * To allow the user to talk with the `svg_graph` class using coordinate units instead of pixels or other arbitrary measures I have only a student's grasp of C++, so if you have a suggestion to help me with design or implementation, either leave them here or email me at jakevoytko [at] gmail [dot] com[[BR]] This page will hold examples of what I have implemented thus far, and what my program will be capable of in the future. More complete documentation will be live in a few days on my personal website. = What can it do? = == Example == == Potential example == {{{ #!cpp svg_plot my_plot; // size/scale settings my_plot.set_image_size(500, 350) .set_x_scale(-2, 10); // command settings my_plot.set_axis(true) .set_legend(true); // color settings my_plot.set_background_color(lightgray) .set_legend_background_color(whitesmoke); // drawing plot_range(my_plot, data2.begin(), data2.end(), "Lions", blue); plot_range(my_plot, data1.begin(), data1.end(), "Tigers", limegreen); // write to file. NOTE: Will change to write(filename) soon my_plot.write("D:\\1d_simple.svg"); }}} produces the following output: [http://www.tcnj.edu/~voytko2/svg_simple.htm] == Complex example == Because Boost.Array supports an iterator-like interface, (`my_arr.begin()`, `my_arr.end()`), Boost.Array can freely be used with the program. This example shows what a completely customized graph might look like. The colors were suggested by Sarah Braun to match the [http://www.drivehq.com/file/df.aspx/publish/matias.capeletto/wwwhome/doc_test/xhtml/index.html Unified Look and Feel] project {{{ #!cpp vector data1; deque data2; boost::array data3; svg_plot my_plot; // size/scale settings my_plot.set_image_size(500, 350) .set_x_scale(-3, 10); // Text settings my_plot.set_title("Oh My!") .set_title_font_size(29) .set_x_label_text("Time in Months"); // command settings my_plot.set_axis(true) .set_legend(true) .set_plot_window(true) .set_x_label(true) .set_x_major_labels(true); // color settings my_plot.set_background_color(svg_color(67, 111, 69)) .set_legend_background_color(svg_color(207, 202,167)) .set_plot_background_color(svg_color(136, 188, 126)) .set_title_color(white) .set_x_axis_color(black) .set_x_major_tick_color(black) .set_legend_border_color(svg_color(102, 102, 84)) .set_x_minor_tick_color(black); //axis settings my_plot.set_x_major_tick(2) .set_x_num_minor_ticks(3) .set_x_major_tick_length(14) .set_x_minor_tick_length(7) .set_x_major_tick_width(1) .set_x_minor_tick_width(1); //legend settings my_plot.set_legend_title_font_size(15); plot_range(my_plot, data2.begin(), data2.end(), "Lions", blue); plot_range(my_plot, data1.begin(), data1.end(), "Tigers", purple); plot_range(my_plot, data3.begin(), data3.end(), "Bears", red); my_plot.write("D:/1d_complex.svg"); }}} Produces the following file: [http://www.tcnj.edu/~voytko2/svg_complex.htm] == Simple 2D Example == === Note: Because one of this week's tasks is to make sane defaults, the sample program here will likely be shorter === {{{ #!cpp multimap data; svg_2d_plot my_plot; for(double i=0; i<10; ++i) { data.insert(std::pair(i,f(i))); } // size/scale settings my_plot.set_image_size(500, 350) .set_x_scale(-1, 10) .set_y_scale(-1, 5); // Text settings my_plot.set_title("2D Graph Test") .set_title_font_size(29); // command settings my_plot.set_axis(true) .set_legend(true) .set_plot_window(true) .set_x_major_labels(true) .set_y_major_labels(true); // color settings my_plot.set_background_color(darkgray) .set_legend_background_color(white) .set_plot_background_color(white); //axis settings my_plot.set_x_major_tick(2) .set_x_num_minor_ticks(1) .set_x_major_tick_length(14) .set_x_minor_tick_length(7) .set_x_major_tick_width(2) .set_x_minor_tick_width(1) .set_y_major_tick(2) .set_y_num_minor_ticks(1) .set_y_major_tick_length(20) .set_y_minor_tick_length(10) .set_y_major_tick_width(2) .set_y_minor_tick_width(1); //legend settings my_plot.set_legend_title_font_size(15); plot_range(my_plot, data.begin(), data.end(), "sqrt(x)", black); my_plot.write("D:/test.svg"); }}} Produces the following file: [http://www.tcnj.edu/~voytko2/svg_2d.htm] = To-Do List = == For next week == * Better/more complete Documentation * Fewer bugs * As many suggestions finished as I can = Suggestions = ''By Matias Capeletto:'' * Be able to choose a log scale for either the X or the Y axis * Allow the user to import/export XML data that represents style information * Proposal to include a pluggable extractor to `plot_range()` In general, containers will store other things than double. Starting simple, I want to be able to plot `std::vector`. This is very easy to support. Add a function: {{{ #!cpp template plot& plot_range( Iter start, Iter end, DoubleExtractor double_extractor) { return your_old_plot_range( boost::make_transform_iterator(start, double_extractor), boost::make_transform_iterator(end , double_extractor) ); } }}} This have other implications, for example if we have list hl, and struct get_age_functor { ... }; We can: {{{ #!cpp plot_range(svg, hl.begin(), hl.end(), get_age_functor() ); // fun stuff :) }}} ''By Paul Bristow'' * Customize background color of plot '''''Completed''''' * Customize the background border color '''''Completed''''' * Customize the "axis area" background color '''''Completed''''' * Title * Customize font * Customize font color '''''Completed''''' * Customize font size '''''Completed''''' * Axis * Customize line colors '''''Completed''''' * Customize line thickness '''''Completed''''' * Define labels for axis '''''Completed''''' * Major ticks width, length, color '''''Completed''''' * Minor ticks width, length, color '''''Completed''''' * Reasonable defaults for ticks '''''Completed''''' * Axis marker labels '''''Completed for major ticks''''' * Consider the axis for data where the origin is not in the view window * Consider auto-scaling * Grid lines '''''Completed''''' * Data representation * Allow different data representation points * Allow appropriate customization of data points * Consider labels for data points (combined with exploration of hover-text features of SVG mentioned above) '''''Completed in legend''''' * Multiple data series '''''Completed''''' * Legend * color '''''Partially Completed''''' * position * border thickness * border color '''''Completed''''' * background colors '''''Completed''''' * Unicode strings ''By Cédric Venet'' * Keep an eye towards being extensible towards multiple image formats in the future = 4. Bugs D: = * Changing or setting the x_scale after calling my_graph.draw_axis() makes the axis not be drawn. * This is caused because I store points after setting the graph. I will fix this by storing infinity as +NaN in the point, and when outputting, writing it at a location far off the graph = 5. Acknowledgments = In no particular order, I'd like to thank Joaquín López Muñoz, Paul Bristow, Sarah Braun, John Maddock, Matias Capeletto, and anyone who's taken the time to comment on my progress / offer suggestions.