/// <summary> /// Gets the "total amount" text for a given statistic type. /// The unit type of the text depends on the unit type used for graph painting. /// </summary> private string TotalText(Stat stat) { float[] totals = TrafficStat.Total(stat, TotalsAverageCount); if (totals.Length > 0) { bool bits = GraphPaint.Scale.InBits; // TODO bad programming practice, code smell. float average = totals.Average(); if (bits) { average *= 8.0f; } var trafficValue = new TrafficUnitValue(average, bits); return(TrafficUnit.Humanize(trafficValue) + "/s"); } return("N/A"); }
/// <summary> /// Paints <see cref="TrafficStat"/> on an arbitrary Bitmap. /// </summary> public void Paint(Bitmap bitmap, TrafficStat stat) { Graphics graphics = Graphics.FromImage(bitmap); try { graphics.Clear(ClearColor); int amount = bitmap.Width; float[] downloadTotals = stat.Total(Stat.Download, amount); float[] uploadTotals = stat.Total(Stat.Upload, amount); // It's a buggy state if this happens. if (downloadTotals.Length != uploadTotals.Length) { throw new TrafficMeasureException("uneven upload/download totals"); } // However, it's perfectly fine to get lesser amount of totals than requested. int realAmount = downloadTotals.Length; // Totals length may be shorter than the graph width, but we still want // the graph bars to stick to the right edge. for (int idx = 0, drawPos = bitmap.Width - realAmount; idx < realAmount; ++idx, ++drawPos) { float download = downloadTotals[idx]; float upload = uploadTotals[idx]; float biggerTotal; Pen biggerPen; float lowerTotal; if (download > upload) { biggerTotal = download; lowerTotal = upload; biggerPen = DownloadPen; } else { biggerTotal = upload; lowerTotal = download; biggerPen = UploadPen; } // We're drawing from bottom up, so from graph.Height to 0. graphics.DrawLine(biggerPen, drawPos, bitmap.Height, drawPos, GetDrawY1(biggerTotal, bitmap.Height)); // This bar will always be smaller. graphics.DrawLine(BothPen, drawPos, bitmap.Height, drawPos, GetDrawY1(lowerTotal, bitmap.Height)); // Draw scale text. } if (CanPaintScale(bitmap)) { graphics.DrawString(ScaleText, TextFont, TextBrush, 1, 1); } } finally { graphics.Dispose(); } }