问题描述
一个文本文件包含100个学生,每行包括:名字,姓氏,考试1,考试2,考试3。我将数据从文本文件读取到一系列结构中。但是现在我需要创建一个折线图,x轴上的学生人数,y轴上的三个考试分数中的每一个。考试1为绿色,考试2为红色,考试3为蓝色。并且水平线表示每次考试的平均值。理论上应该看起来像这样。
这是我到目前为止提出的代码,但是我甚至无法弄清从哪里开始创建折线图。
#include "library.h"
#include<iostream>
#include<cmath>
#include <cstdlib>
#include <fstream>
#include <string>
#include <iostream>
using namespace std;
struct StudentInfo {
string first;
string last;
int e1;
int e2;
int e3;
};
void main()
{
ifstream in_file;
in_file.open("exams.txt");
StudentInfo students[100];
int count = 0;
while(in_file >> students[count].first){
in_file >> students[count].last;
in_file >> students[count].e1;
in_file >> students [count].e2;
in_file >> students [count].e3;
count ++;
}
for (int i = 0; i < count; i++){
cout << students[i].first << " " << students[i].last << " " << students[i].e1 << " " << students[i].e2 << " " << students[i].e3 << endl;
}
in_file.close();
}
解决方法
您很可能希望使用图形库。 有一些可以为您绘制图表的地方。 还有其他只能画形状的东西。
我使用SFML创建了这个丑陋的示例,因为这是我最熟悉的示例:
为了提高速度,我进行了很多硬编码。
这通过绘制边框来实现:
std::array<sf::Vertex,3> border {
sf::Vertex(sf::Vector2f(0.f,0.f),sf::Color::Black),sf::Vertex(sf::Vector2f(0.f,100.f),sf::Vertex(sf::Vector2f(full_width,sf::Color::Black)
};
window.draw(border.data(),border.size(),sf::PrimitiveType::LineStrip);
创建顶点矢量以存储折线图的折线部分:
std::vector<sf::Vertex> line_graph_1;
std::vector<sf::Vertex> line_graph_2;
std::vector<sf::Vertex> line_graph_3;
遍历每个学生并将顶点添加到这些向量:
line_graph_1.emplace_back(sf::Vector2f(x,100.f - student.e1),sf::Color::Red);
line_graph_2.emplace_back(sf::Vector2f(x,100.f - student.e2),sf::Color::Green);
line_graph_3.emplace_back(sf::Vector2f(x,100.f - student.e3),sf::Color::Blue);
在底部绘制名称:
text.setString(student.first + ' ' + student.last);
const auto bounds = text.getLocalBounds();
text.setPosition(
x + bounds.left - bounds.width / 2.f,128.f + bounds.top - bounds.height / 2.f
);
window.draw(text);
遍历所有学生后,绘制线向量:
window.draw(line_graph_1.data(),line_graph_1.size(),sf::PrimitiveType::LineStrip);
window.draw(line_graph_2.data(),line_graph_2.size(),sf::PrimitiveType::LineStrip);
window.draw(line_graph_3.data(),line_graph_3.size(),sf::PrimitiveType::LineStrip);
最后画出平均线:
std::array<sf::Vertex,3> average_line{
sf::Vertex(sf::Vector2f(0.f,100.f - average_1),sf::Color::Red),sf::Color::Red)
};
window.draw(average_line.data(),average_line.size(),sf::PrimitiveType::Lines);
average_line = {
sf::Vertex(sf::Vector2f(0.f,100.f - average_2),sf::Color::Green),sf::Color::Green)
};
window.draw(average_line.data(),100.f - average_3),sf::Color::Blue),sf::Color::Blue)
};
window.draw(average_line.data(),sf::PrimitiveType::Lines);
对于没有内置图形的图形库,类似的东西将是一个好的开始。