urallsad
urallsad

Reputation: 115

Creating a .svg bar graph

So what I need to do is:

Write a program that inputs four nonnegative integer values and creates the SVG file that displays a simple bar chart that depicts the integer values. Your program should scale the values so they are always drawn with a maximum height of 400 pixels.

This is what I have so far and everything works well but I have two problems:

1 - My bar graph is being shown upside down, as in instead of the height of the graph going above the x axis, it is going below it.

2 - I can't figure out how to scale the heights so that they are always drawn with a maximum height of 400.

#include <iostream>
#include <fstream>

using namespace std;

int main()
{
int number1, number2, number3, number4;

ofstream fout;

fout.open("rectline.svg");
if (fout.fail())
{
    cout << "Could not open file.";
}
do
{
    cout << "Please enter 4 numbers separated by spaces.\n";
    cin >> number1 >> number2 >> number3 >> number4;
    if (number1 < 0 || number2 < 0 || number3 < 0 || number4 < 0)
    {
        cout << "Please enter a non-negative number.\n";
    }
} while (number1 < 0 || number2 < 0 || number3 < 0 || number4 < 0);


fout << "<?xml version=\"1.0\" standalone=\"no\"?>\n"
     << "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n"
     << "\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n"
     << "<svg width=\"500\" height=\"500\"\n"
     << "xmlns=\"http://www.w3.org/2000/svg\">\n";

// This creates the bars.
fout << "<rect x=\"" << 0 <<"\" y=\"" << 300 << "\" width=\"" << 25
     << "\" height=\"" << number1 << "\" style=\"fill:blue;\"/>\n"
     << "<rect x=\"" << 50 << "\" y=\"" << 300 << "\" width=\"" << 25
     << "\" height=\"" << number2 << "\" style=\"fill:rgb(0,255,0);\"/>\n"
     << "<rect x=\"" << 100 <<"\" y=\"" << 300 << "\" width=\"" << 25
     << "\" height=\"" << number3 << "\" style=\"fill:blue;\"/>\n"
     << "<rect x=\"" << 150 << "\" y=\"" << 300 << "\" width=\"" << 25
     << "\" height=\"" << number4 << "\" style=\"fill:rgb(0,255,0);\"/>\n";

// This creates the lines.
fout << "<line x1=\"" << 0 << "\" y1=\"" << 0 << "\" x2=\"" << 0 << "\" y2=\"" << 300
     << "\" style=\"stroke:purple;stroke-width:2\"/>" << endl
     << "<line x1=\"" << 0 << "\" y1=\"" << 300 << "\" x2=\"" << 300 << "\" y2=\"" << 300
     << "\" style=\"stroke:purple;stroke-width:2\"/>" << endl;

fout << "</svg>" << endl;

fout.close();

}

Upvotes: 1

Views: 997

Answers (1)

Dylan Kley
Dylan Kley

Reputation: 36

SVG doesn't use a traditional Cartesian coordinate system. Instead it uses a system such that the Y-Axis scales in the positive direction as you move down along the screen. Because of this your rectangles are drawn with Y1 300 and Y2 300 + the user input.

For everything conforming to a 400 pixel size, first find the maximum of the user inputs. 400/Max = ScaleFactor. Multiply this scale factor times the height of each to find their scaled height.

Upvotes: 2

Related Questions