Skip to content

Commit fc8e7eb

Browse files
committed
initial commit
0 parents  commit fc8e7eb

14 files changed

+505
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.vscode/
2+
/test.csv
3+
ascii-data-visualizer

Makefile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CC = g++
2+
TARGET = ascii-data-visualizer
3+
SOURCES = ascii-data-visualizer.cpp src/*.cpp
4+
FLAGS = -o ascii-data-visualizer -Iinclude
5+
6+
$(TARGET): $(SOURCES)
7+
$(CC) $(FLAGS) $(SOURCES)
8+

README.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# ascii-graph
2+
A terminal application which visualizes statistical data via ascii characters.
3+
4+
## Requirements
5+
- g++
6+
- Support for `make` command (which compiles c++ code)
7+
- c++17
8+
9+
10+
11+
## Installation
12+
To build/execute the file, `cd` into the directory of the repo and use the `make` command.<br>
13+
After compiling the file, it will create an executable file.<br>
14+
15+
Build and execute example:
16+
```bash
17+
$ make
18+
$ ./ascii-data-visualizer file.csv
19+
```
20+
21+
## Usage
22+
To visualize data, you must first specify a csv file to read.<br>
23+
The first command line argument will be the file, e.g.:
24+
```bash
25+
$ ./ascii-data-visualizer file.csv
26+
```
27+
28+
### Arguments
29+
Command line arguments can be used to change how you visualize your data.<br>
30+
If you want your chart to be vertical, you can use the `orientation` argument:
31+
```bash
32+
$ ./ascii-data-visualizer file.csv --orientation vertical
33+
```
34+
35+
### File Format
36+
Format follows `label,value` format:
37+
```csv
38+
title: Programming languages used by programmers (percent)
39+
40+
C,20
41+
C++,23
42+
Python,51
43+
```

ascii-data-visualizer.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#include <iostream>
2+
#include <string>
3+
#include <fstream>
4+
#include <regex>
5+
#include <filesystem>
6+
#include <cmath>
7+
#include <unordered_map>
8+
#include "chart_manager.h"
9+
#include "file_reader.h"
10+
#include "arg_handler.h"
11+
12+
int main(int argc, char **argv)
13+
{
14+
std::string fileName = getFileNameFromArgs(argc, argv);
15+
auto cmdArgs = getCommandLineArgs(argc, argv);
16+
17+
std::string orientation = getArgValue(cmdArgs, "orientation", "horizontal");
18+
int length = std::stoi(getArgValue(cmdArgs, "length", "10"));
19+
std::string chartString = "";
20+
if (orientation == "vertical"){
21+
int height = std::stoi(getArgValue(cmdArgs, "height", "10"));
22+
VerticalBarChart myChart(fileName, length, height);
23+
chartString = myChart.drawChart();
24+
} else{
25+
HorizontalBarChart myChart(fileName, length);
26+
chartString = myChart.drawChart();
27+
}
28+
std::cout << chartString;
29+
return 0;
30+
}

include/arg_handler.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#pragma once
2+
3+
#include <iostream>
4+
#include <string>
5+
#include <regex>
6+
#include <unordered_map>
7+
8+
const std::regex commandLineArgsPattern{"(?:--)(\\w+?)\\s(\\w+)"};
9+
10+
std::string getArgValue(
11+
std::unordered_map<std::string, std::string>,
12+
std::string argName, std::string defaultValue
13+
);
14+
15+
std::string getFileNameFromArgs(int argc, char **argv);
16+
std::unordered_map<std::string, std::string> getCommandLineArgs(int argc, char **argv);

include/bar_chart_utilities.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#pragma once
2+
3+
#include <iostream>
4+
#include <string>
5+
#include <vector>
6+
7+
const std::string HORIZONTAL_BORDER_CHAR = "\u2500";
8+
const std::string HORIZONTAL_BAR_CHAR = "#";
9+
const std::string VERTICAL_BAR_CHAR = "\u2588";
10+
11+
std::string drawHorizontalBorder(int length);
12+
std::string drawHorizontalBar(int length);
13+
int getMaxStringLength(std::vector<std::string> strings);

include/chart_manager.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#pragma once
2+
3+
#include <iostream>
4+
#include <string>
5+
#include <vector>
6+
7+
struct ChartDataPoint{
8+
std::string label;
9+
double value;
10+
};
11+
12+
struct BarChartInfo{
13+
std::string title = "";
14+
std::vector<ChartDataPoint> dataPoints;
15+
};
16+
17+
BarChartInfo getBarChartInfoFromFile(std::string filename);
18+
19+
class HorizontalBarChart{
20+
public:
21+
int maxLength;
22+
std::string title;
23+
std::vector<ChartDataPoint> dataPoints;
24+
std::string drawChart();
25+
HorizontalBarChart(std::string filename, int maxLength = 10);
26+
};
27+
class VerticalBarChart{
28+
public:
29+
int width, height;
30+
std::string title;
31+
std::vector<ChartDataPoint> dataPoints;
32+
std::string drawChart();
33+
VerticalBarChart(std::string filename, int width = 10, int height = 10);
34+
};

include/data_utilities.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#pragma once
2+
3+
#include <iostream>
4+
#include <string>
5+
#include <regex>
6+
7+
const std::regex lastDecimalPattern{"^([\\d.]+?(?:[1-9]?$|(?=0+?$)))"};
8+
9+
std::string doubleToStringPrecision(double value);

include/file_reader.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#pragma once
2+
3+
#include <iostream>
4+
#include <string>
5+
#include <regex>
6+
#include <unordered_map>
7+
8+
const std::regex csvFilePattern{"^(.+?),([\\d.]+)(?=,|$)"};
9+
const std::regex csvDelimiterPattern{"^(\\w+?):\\s*(.+?)$"};
10+
const std::regex validFilePattern{"^[a-z0-9_-]*\\.csv$", std::regex_constants::icase};
11+
std::vector<std::string> getFileLines(std::string filename);

src/arg_handler.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#include <iostream>
2+
#include <string>
3+
#include <unordered_map>
4+
#include <regex>
5+
#include "arg_handler.h"
6+
7+
std::string getArgValue(
8+
std::unordered_map<std::string, std::string> args,
9+
std::string argName, std::string defaultValue = "")
10+
{
11+
if (!args.count(argName))
12+
return defaultValue;
13+
return args.at(argName);
14+
}
15+
16+
std::string getFileNameFromArgs(int argc, char **argv)
17+
{
18+
if (argc > 1)
19+
return argv[1];
20+
throw std::runtime_error("no file specified");
21+
}
22+
23+
std::unordered_map<std::string, std::string> getCommandLineArgs(int argc, char **argv)
24+
{
25+
std::unordered_map<std::string, std::string> args;
26+
if (argc == 1)
27+
return args;
28+
std::smatch argMatch;
29+
std::string argsString("");
30+
for (int i = 1; i < argc; ++i){
31+
argsString += argv[i];
32+
if (i+1 < argc)
33+
argsString += " ";
34+
}
35+
for (std::sregex_iterator i = std::sregex_iterator(
36+
argsString.begin(), argsString.end(), commandLineArgsPattern);
37+
i != std::sregex_iterator();
38+
++i)
39+
{
40+
std::smatch argMatch = *i;
41+
std::string arg = argMatch[1].str();
42+
std::string argValue = argMatch[2].str();
43+
args[arg] = argValue;
44+
}
45+
return args;
46+
}

0 commit comments

Comments
 (0)