PieChart.cpp
#include "PieChart.h"
#include "textfunctions.h"
using namespace std;
/**
* Write the necessary junk for the top of the chart
*/
static void writeTopBoilerPlateOfPieChart( ostream& out) {
out<<("<html>\n");
out<<("<head>\n");
out<<("<!--Load the AJAX API-->\n");
out<<("<script type=\"text/javascript\"");
out<<("src=\"https://www.google.com/jsapi\">");
out<<("</script>\n");
out<<("<script type=\"text/javascript\">\n");
out<<("google.load('visualization', '1.0', {'packages':['corechart']});\n");
out<<("google.setOnLoadCallback(drawChart);\n");
out<<("function drawChart() {\n");
out<<("var data = new google.visualization.DataTable();\n");
out<<("data.addColumn('string', 'Label');\n");
out<<("data.addColumn('number', 'Value');\n");
}
/**
* Write the intesting bit of the Pie Chart
*/
static void writeDataOfPieChart( ostream& out,
const vector<string>& labels,
const vector<double>& values) {
out<< "data.addRows([\n";
int nLabels = labels.size();
for (int i=0; i<nLabels; i++) {
string label = labels[i];
double value = values[i];
out<<"['"<<escapeJavascriptString(label)<<"', "<<value<<"]";
if (i!=nLabels-1) {
out<<",";
}
out<<"\n";
}
out<<"]);\n";
}
/**
* Write the boring bit at the bottom of a pie chart
*/
static void writeBottomBoilerPlateOfPieChart( ostream & out, std::string title ) {
out<<"var options = {'title':'"<<escapeJavascriptString(title)<<"',\n";
out<<"'width':400,\n";
out<<"'height':300\n";
out<<"};\n";
out<<"var chart = new google.visualization.PieChart(document.getElementById('chart_div'));\n";
out<<"chart.draw(data, options);\n";
out<<"}\n";
out<<"</script>\n";
out<<"</head>\n";
out<<"<body>\n";
out<<"<div id='chart_div'>\n";
out<<"</body>\n";
out<<"</html>";
}
////////////////////////
// Pie Chart implementation
////////////////////////
PieChart::PieChart() :
title("A Pie Chart") {
}
void PieChart::setTitle( const std::string& t ) {
title = t;
}
void PieChart::addEntry( const string& label,
double value ) {
labels.push_back( label );
values.push_back( value );
}
void PieChart::writeAsHTML( ostream& out ) const {
writeTopBoilerPlateOfPieChart(out);
writeDataOfPieChart( out, labels, values );
writeBottomBoilerPlateOfPieChart( out, title );
}
void PieChart::writeAsHTML( const string& file ) const {
ofstream out;
out.open(file.c_str());
writeAsHTML( out );
out.close();
}
///////////////////////////////////////////
//
// Tests for pie chart
//
///////////////////////////////////////////
static void testPieChartData() {
// this test automates the checking
stringstream out;
vector<string> labels(3);
vector<double> vals(3);
for (int i=0; i<3; i++) {
stringstream ss;
ss<<"A Label "<<i;
labels[i] =ss.str();
INFO( labels[i] );
vals[i]=(double)i;
}
writeDataOfPieChart( out,
labels,
vals );
string asString = out.str();
stringstream expected;
expected<<"data.addRows([\n";
expected<<"['A Label 0', 0],\n";
expected<<"['A Label 1', 1],\n";
expected<<"['A Label 2', 2]\n";
expected<<"]);\n";
string expectedStr = expected.str();
ASSERT( asString==expectedStr );
}
static void testPieChartClass() {
// just checks that the class compiles etc.
PieChart pieChart;
pieChart.addEntry("Mushrooms",200);
pieChart.addEntry("Salami",100);
pieChart.addEntry("Spinach",150);
pieChart.setTitle("Pizza Toppings");
pieChart.writeAsHTML( "PizzaPie.html" );
}
void testPieChart() {
TEST( testPieChartData );
TEST( testPieChartClass );
}