aboutsummarylogtreecommitdiffstats
path: root/graph.c
diff options
context:
space:
mode:
authorAntony Kellermann2018-03-17 14:37:03 -0400
committerAntony Kellermann2018-03-17 14:37:03 -0400
commitc383b029c80222787d967afdfaf5975a4025fef0 (patch)
tree292c4c13001037cc5fadce2a919faf89bfac383d /graph.c
parent3f2c67221fc705e202aef9f9ef46e715acb6d44f (diff)
downloadaur-c383b029c80222787d967afdfaf5975a4025fef0.tar.gz
Implemented zooming in and out for graphing
Diffstat (limited to 'graph.c')
-rw-r--r--graph.c91
1 files changed, 73 insertions, 18 deletions
diff --git a/graph.c b/graph.c
index 9313ebfb4a17..3f9166ca0fd8 100644
--- a/graph.c
+++ b/graph.c
@@ -1,48 +1,102 @@
#include "graph.h"
-void graph_main(const char* ticker_name_string){
+void graph_main(const char* ticker_name_string) {
initscr();
noecho();
keypad(stdscr, TRUE);
curs_set(0);
double* data = api_get_hist_5y(ticker_name_string);
- if (data != NULL) {
- time_t now = time(NULL);
- struct tm* ts = localtime(&now);
- ts->tm_year -= 5;
- graph_print(data, ts);
+ if (data == NULL) {
+ puts("Invalid symbol.");
+ return;
}
- else puts("Invalid symbol.");
+ time_t now = time(NULL);
+ struct tm ts = *localtime(&now);
+ ts.tm_year -= 5;
+
+ int ch, zoom = ZOOM_5y;
+ graph_print(data, &ts, zoom);
- int ch;
while (1) {
ch = getch();
if (ch == 'q')
break;
+ if ((ch == KEY_UP && zoom != ZOOM_1m) || (ch == KEY_DOWN && zoom != ZOOM_5y)) {
+ if (ch == KEY_UP) {
+ zoom++;
+ if (zoom <= ZOOM_1y)
+ ts.tm_year += 1;
+ else if (zoom <= ZOOM_3m)
+ ts.tm_mon += 3;
+ else ts.tm_mon += 2;
+ } else if (ch == KEY_DOWN) {
+ zoom--;
+ if (zoom < ZOOM_1y)
+ ts.tm_year -= 1;
+ else if (zoom < ZOOM_3m)
+ ts.tm_mon -= 3;
+ else ts.tm_mon -= 2;
+ }
+ clear();
+ mktime(&ts); // Normalize
+ graph_print(data, &ts, zoom);
+ }
}
endwin();
free(data);
}
-void graph_print(const double* points, struct tm* start_time) {
+void graph_print(const double* points, struct tm* start_time, int zoom) {
struct winsize w;
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
int cols = w.ws_col - 11; // 10 offset to give space for graph labels + 1 for right side
- int lines = w.ws_row - ROWS_SPACING;
+ int lines = w.ws_row;
lines -= lines % ROWS_SPACING; // Round down to multiple of 5
if (cols < 10 || lines < 10) {
puts("Terminal not large enough.");
return;
}
- double max = points[0], min = points[0];
- int data_length = 0;
- for (int i = 1; points[i] != '\0'; i++) { // Find max and min values for graph upper/lower bounds
+ struct tm end_time = *start_time;
+
+ if (zoom == ZOOM_5y)
+ end_time.tm_year += 5;
+ else if (zoom == ZOOM_4y)
+ end_time.tm_year += 4;
+ else if (zoom == ZOOM_3y)
+ end_time.tm_year += 3;
+ else if (zoom == ZOOM_2y)
+ end_time.tm_year += 2;
+ else if (zoom == ZOOM_1y)
+ end_time.tm_year += 1;
+ else if (zoom == ZOOM_9m)
+ end_time.tm_mon += 9;
+ else if (zoom == ZOOM_6m)
+ end_time.tm_mon += 6;
+ else if (zoom == ZOOM_3m)
+ end_time.tm_mon += 3;
+ else if (zoom == ZOOM_1m)
+ end_time.tm_mon += 1;
+
+ mktime(&end_time); // Normalize
+
+ double seconds = difftime(mktime(&end_time), mktime(start_time));
+ int trading_days = (int) ((1.0 / DAYS_TO_BUSINESS_DAYS_RATIO) * seconds / 86400.0); // Total trading day to print
+
+ time_t now = time(NULL);
+ struct tm* five_y = localtime(&now);
+ five_y->tm_year -= 5;
+
+ seconds = difftime(mktime(start_time), mktime(five_y));
+ int starting_index = (int) ((1.0 / DAYS_TO_BUSINESS_DAYS_RATIO) * seconds / 86400.0);
+
+ double max = points[starting_index], min = points[starting_index];
+ for (int i = starting_index + 1;
+ i < trading_days + starting_index; i++) { // Find max and min values for graph upper/lower bounds
if (points[i] > max)
max = points[i];
if (points[i] < min)
min = points[i];
- data_length++;
}
double line_diff = (max - min) / lines, dat; // Each lines includes data point up to line_diff below
@@ -51,7 +105,7 @@ void graph_print(const double* points, struct tm* start_time) {
printw("%9.2lf ", (max - ((lines - i) * line_diff)));
else printw(" ");
for (int j = 0; j < cols; j++) {
- dat = points[(int) ((double) j * data_length / cols)];
+ dat = points[starting_index + (int)((double) j * trading_days / cols)];
if (dat <= (max - ((lines - i) * line_diff)) && dat > (min + ((i - 1) * line_diff)))
addch(ACS_DIAMOND);
else if (i % ROWS_SPACING == 0 && j % COLS_SPACING == 0)
@@ -60,19 +114,20 @@ void graph_print(const double* points, struct tm* start_time) {
addch(ACS_HLINE);
else if (j % COLS_SPACING == 0)
addch(ACS_VLINE);
- else addch(' ');
+ else
+ addch(' ');
}
addch('\n');
}
printw(" ");
char time_string[16];
- double x = (DAYS_TO_BUSINESS_DAYS_RATIO * data_length) / (cols / COLS_SPACING);
+ double x = (DAYS_TO_BUSINESS_DAYS_RATIO * trading_days) / (cols / COLS_SPACING);
struct tm copy = *start_time;
for (int i = 0; i < cols; i++) {
if (i % (2 * COLS_SPACING) == 0 && cols - i > 10) { // Print x-axis date labels every two
if (i != 0)
- copy.tm_mday += x * 2;
+ copy.tm_sec += x * 2.0 * 86400.0;
mktime(&copy);
strftime(time_string, 16, "%m/%d/%Y", &copy);
printw("%s ", time_string); // Width 2 * COLS_SPACING