Guest User

Untitled

a guest
Mar 24th, 2018
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.66 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Drawing;
  5. using System.IO;
  6. using System.Drawing.Drawing2D;
  7.  
  8. ////// Example Usage:
  9. ////// static void Main(string[] args)
  10. ////// {
  11. ////// string[] TestData = {
  12. ////// ",0,100,0,10,1,50,1,50",
  13. ////// ",0,100,0,20,1,60,1,50",
  14. ////// ",0,100,0,30,1,70,1,50",
  15. ////// ",0,100,0,40,1,80,1,50",
  16. ////// ",0,100,0,50,1,90,1,50",
  17. ////// ",0,100,0,60,1,100,1,50",
  18. ////// ",0,100,0,70,1,50,1,50",
  19. ////// ",0,100,0,80,1,60,1,50",
  20. ////// ",0,100,0,90,1,70,1,50",
  21. ////// ",0,100,0,10,1,80,1,50",
  22. ////// ",0,100,0,20,1,90,1,50",
  23. ////// ",0,100,0,30,1,100,1,50",
  24. ////// ",0,100,0,40,1,50,1,50",
  25. ////// ",0,100,0,50,1,60,1,50",
  26. ////// ",0,100,0,60,1,70,1,50",
  27. ////// ",0,100,0,70,1,80,1,50",
  28. ////// ",0,100,0,80,1,90,1,50",
  29. ////// ",0,100,0,90,1,100,1,50",
  30. ////// };
  31. //////
  32. ////// GraphBuilderArgs gbargs = new GraphBuilderArgs()
  33. ////// {
  34. ////// //Data = CSVParser.ReadArray(TestData),
  35. ////// Data = CSVParser.ReadFile("C:\\Users\\user\\Documents\\output.csv"),
  36. ////// Width = 1920,
  37. ////// Height = 1080,
  38. ////// };
  39. //////
  40. ////// GraphBuilder.Build(gbargs).Save("C:\\Users\\user\\Documents\\data.png");
  41. ////// }
  42.  
  43. namespace CashGraph
  44. {
  45. public struct GraphBuilderArgs
  46. {
  47. public int Height { get; set; }
  48. public int Width { get; set; }
  49. public List<Bars> Data { get; set; }
  50. }
  51. static class GraphBuilder
  52. {
  53.  
  54. public static Bitmap Build(GraphBuilderArgs args)
  55. {
  56. List<Bars> Data = args.Data;
  57.  
  58.  
  59. //Determine the max value;
  60. int Income = Largest(Data, 0);
  61. int Expense = Largest(Data, 1);
  62.  
  63. //Some constants
  64. int Margin = 5;
  65. int EqualsBarWidth = 2;
  66.  
  67. float YScale = (float)(args.Height - (Margin * 2)) / (float)(Income + Expense + EqualsBarWidth + 0.0f) * 0.99f;
  68. int XScale = (int)Math.Floor((double)((args.Width - (Margin * 2) + 0.0) / Data.Count + 0.0));
  69. if (XScale < 1) Console.Write("Warning: XSCALE is less than 1, is your Width too small?");
  70.  
  71. //We are just gonna resize it to make it work perfectly;
  72. args.Width = (Margin) + (Data.Count * XScale);
  73.  
  74. int EqualsBarLevel = (int)(Income * YScale) + Margin;
  75.  
  76. Bitmap Image = new Bitmap(args.Width, args.Height);
  77. Graphics g = Graphics.FromImage(Image);
  78.  
  79. //g.SmoothingMode = SmoothingMode.AntiAlias;
  80. g.InterpolationMode = InterpolationMode.HighQualityBicubic;
  81. g.PixelOffsetMode = PixelOffsetMode.HighQuality;
  82.  
  83.  
  84. int i, j, offset, barOffset, monthOffset = 0;
  85. DateTime currentMonth = DateTime.MinValue;
  86. for (i = 0; i < Data.Count; i++)
  87. {
  88. offset = (i * XScale) + Margin + (monthOffset * XScale);
  89. barOffset = EqualsBarLevel - EqualsBarWidth;
  90. for (j = 0; j < Data[i][0].Count; j++)
  91. {
  92. using (var pen = new Pen(GetIncomeColor(j), XScale))
  93. g.DrawLine(pen,
  94. offset, barOffset,
  95. offset, barOffset - (Data[i][0][j] * YScale));
  96. barOffset = (int)(barOffset - (Data[i][0][j] * YScale)) + 1;
  97. }
  98.  
  99. barOffset = EqualsBarLevel;
  100. for (j = 0; j < Data[i][0].Count; j++)
  101. {
  102. using (var pen = new Pen(GetExpenseColor(j), XScale))
  103. g.DrawLine(pen,
  104. offset, barOffset,
  105. offset, barOffset + (Data[i][1][j] * YScale));
  106. barOffset = (int)(barOffset + (Data[i][1][j] * YScale)) - 1;
  107. }
  108.  
  109. if (i == 0)
  110. currentMonth = new DateTime(Data[i].Date.Year, Data[i].Date.Month, 1);
  111. if (currentMonth != new DateTime(Data[i].Date.Year, Data[i].Date.Month, 1))
  112. currentMonth = new DateTime(Data[i].Date.Year, Data[i].Date.Month, 1);
  113. }
  114.  
  115. for (i = 0; i < Data.Count; i++)
  116. {
  117. offset = (i * XScale) + Margin + (monthOffset * XScale);
  118. if (i == 0)
  119. currentMonth = new DateTime(Data[i].Date.Year, Data[i].Date.Month, 1);
  120. if (currentMonth != new DateTime(Data[i].Date.Year, Data[i].Date.Month, 1))
  121. {
  122. barOffset = EqualsBarLevel - EqualsBarWidth;
  123.  
  124. //monthOffset++;
  125. currentMonth = new DateTime(Data[i].Date.Year, Data[i].Date.Month, 1);
  126. using (var pen = new Pen(Color.Black, EqualsBarWidth))
  127. g.DrawLine(pen,
  128. (i * XScale) + Margin, barOffset - (Data[i].Sum(0) * YScale),
  129. (i * XScale) + Margin, barOffset + (Data[i].Sum(1) * YScale));
  130.  
  131. g.DrawString(currentMonth.ToString("MMM"), new Font("Tahoma", 20), Brushes.Black, offset + 10, barOffset + 10);
  132. }
  133.  
  134. }
  135.  
  136. using (var pen = new Pen(Color.Black, EqualsBarWidth))
  137. {
  138. g.FillRectangle(Brushes.Blue, 10, 10, 30, 30);
  139. g.DrawRectangle(pen, 10, 10, 30, 30);
  140. g.DrawString("Checking", new Font("Tahoma", 20), Brushes.Black, 50, 10);
  141.  
  142.  
  143. g.FillRectangle(Brushes.Green, 10, 50, 30, 30);
  144. g.DrawRectangle(pen, 10, 50, 30, 30);
  145. g.DrawString("Savings", new Font("Tahoma", 20), Brushes.Black, 50, 50);
  146.  
  147. g.FillRectangle(Brushes.Red, 10, 90, 30, 30);
  148. g.DrawRectangle(pen, 10, 90, 30, 30);
  149. g.DrawString("Student Loans", new Font("Tahoma", 20), Brushes.Black, 50, 90);
  150.  
  151. g.FillRectangle(Brushes.Orange, 10, 130, 30, 30);
  152. g.DrawRectangle(pen, 10, 130, 30, 30);
  153. g.DrawString("Credit Cards", new Font("Tahoma", 20), Brushes.Black, 50, 130);
  154. }
  155.  
  156. using (var pen = new Pen(Color.Black, EqualsBarWidth))
  157. g.DrawLine(pen,
  158. Margin-2, EqualsBarLevel-1,
  159. (Data.Count * XScale) + Margin-2, EqualsBarLevel-1);
  160.  
  161. return Image;
  162. }
  163.  
  164. private static int GetMonthCount(List<Bars> Data)
  165. {
  166. List<DateTime> seenMonths = new List<DateTime>();
  167.  
  168. Data.ForEach((Bars data) => {
  169. var now = DateTime.Now;
  170. if (!seenMonths.Contains(new DateTime(now.Year, now.Month, 1))) seenMonths.Add(new DateTime(now.Year, now.Month, 1));
  171. });
  172.  
  173. return seenMonths.Count;
  174. }
  175.  
  176. private static int Largest(List<Bars> Data, int Index)
  177. {
  178. int Highest = 0;
  179.  
  180. Data.ForEach((Bars data) =>
  181. {
  182. int sum = data.Sum(Index);
  183. if (sum > Highest) Highest = sum;
  184. });
  185. return Highest;
  186. }
  187.  
  188. public static Color GetExpenseColor(int id)
  189. {
  190. Color[] colors = { Color.Red, Color.Orange, Color.OrangeRed };
  191. if (id < 0 || id >= colors.Length) id = colors.Length - 1;
  192. return colors[id];
  193. }
  194.  
  195. public static Color GetIncomeColor(int id)
  196. {
  197. Color[] colors = { Color.Green, Color.Blue, Color.Turquoise };
  198. if (id < 0 || id >= colors.Length) id = colors.Length - 1;
  199. return colors[id];
  200. }
  201. }
  202.  
  203. public class Bars
  204. {
  205. int[][] _data;
  206.  
  207. public List<int> this[int index] { get { return new List<int>(_data[index]); } }
  208. public DateTime Date { get; set; }
  209.  
  210. public Bars(int[][] data, DateTime date)
  211. {
  212. Date = date;
  213. _data = data;
  214. }
  215.  
  216. public int Sum(int index)
  217. {
  218. return _data[index].Sum();
  219. }
  220. }
  221. public class CSVParser
  222. {
  223.  
  224. public static List<Bars> ReadFile(string filename)
  225. {
  226. return ReadArray(File.ReadAllLines(filename));
  227. }
  228. public static List<Bars> ReadArray(string[] Array)
  229. {
  230. List<string> lines = new List<string>(Array);
  231. List<Bars> Data = new List<Bars>(lines.Count);
  232. lines.ForEach((string s) =>
  233. {
  234. List<int> income = new List<int>();
  235. List<int> expense = new List<int>();
  236. string[] parsed = s.ToLower().Split(',');
  237. if (parsed[0] == "date") return; //Skip over a header
  238. //This could be ugly when they don't put a date/time parsable element there but /shrug
  239. DateTime date = parsed[0].Length > 0 ? DateTime.Parse(parsed[0]) : DateTime.MinValue;
  240. for (int i = 1; i < parsed.Length; i += 2)
  241. {
  242. //Also could be ugly, yay exceptions
  243. int Type = GetType(parsed[i]);
  244. if (Type == 0) income.Add(int.Parse(parsed[i + 1]));
  245. if (Type == 1) expense.Add(int.Parse(parsed[i + 1]));
  246. }
  247. Data.Add(new Bars(new int[][]{ income.ToArray(), expense.ToArray() }, date));
  248. });
  249.  
  250. return Data;
  251. }
  252. private static int GetType(string s)
  253. {
  254. if (s == "income" || s == "0") return 0;
  255. if (s == "expense" || s == "1") return 1;
  256. throw new Exception(String.Format("Input is not [Income|Expense|0|1]: {0}", s));
  257. }
  258. }
  259. }
Add Comment
Please, Sign In to add comment