public Image DrawBarList(BarListImpl bl, BarInterval bi, Color up, Color down) { bl.DefaultInterval = bi; Bitmap sl = new Bitmap(w, h); Graphics g = Graphics.FromImage(sl); high = Calc.HH(bl); low = Calc.LL(bl); decimal range = high - low; int pixperdollar = range != 0 ? (int)(h / range) : 0; int pixperbar = bl.Count != 0 ? (int)(w / (decimal)bl.Count) : 0; for (int i = 0; i < bl.Count; i++) { Bar b = bl[i, bi]; Pen p = new Pen(b.Close >= b.Open ? up : down); g.DrawLine(p, i * pixperbar, h - (int)((b.Low - low) * pixperdollar), i * pixperbar, h - (int)((b.High - low) * pixperdollar)); } return(sl); }
void Chart_Paint(object sender, PaintEventArgs e) { if (bl != null) { highesth = Calc.HH(bl); lowestl = Calc.LL(bl); barc = bl.Count; } if ((bl == null) || (bl.Count == 0)) { return; } // setup to draw Pen p = new Pen(Color.Black); g = e.Graphics; Form f = (Form)sender; g.Clear(f.BackColor); // get title Text = Title; // get window r = ClientRectangle; // get number of pixels available for each bar, based on screensize and barcount pixperbar = (((decimal)r.Width - (decimal)border - ((decimal)border / 3)) / (decimal)barc); // pixels for each time stamp const int pixperbarlabel = 60; // number of labels we have room to draw int numbarlabels = (int)((double)(r.Width - border - ((double)border / 3)) / pixperbarlabel); // draw a label every so many bars (assume every bar to star) int labeleveryX = 1; // if there's more bars than space if (barc > numbarlabels) { labeleveryX = (int)Math.Round(((double)barc / numbarlabels)); } // get dollar range for chart decimal range = (highesth - lowestl); // get pixels available for each dollar of movement pixperdollar = range == 0 ? 0 : (((decimal)r.Height - (decimal)border * 2) / range); Color fgcol = (f.BackColor == Color.Black) ? Color.White : Color.Black; // x-axis g.DrawLine(new Pen(fgcol), (int)(border / 3), r.Height - border, r.Width - border, r.Height - border); // y-axis g.DrawLine(new Pen(fgcol), r.Width - border, r.Y + border, r.Width - border, r.Height - border); const int minxlabelwidth = 30; int lastlabelcoord = -500; for (int i = 0; i < barc; i++) { // get bar color Color bcolor = (bl[i].Close > bl[i].Open) ? Color.Green : Color.Red; p = new Pen(bcolor); try { // draw high/low bar g.DrawLine(p, getX(i), getY(bl[i].Low), getX(i), getY(bl[i].High)); // draw open bar g.DrawLine(p, getX(i), getY(bl[i].Open), getX(i) - (int)(pixperbar / 3), getY(bl[i].Open)); // draw close bar g.DrawLine(p, getX(i), getY(bl[i].Close), getX(i) + (int)(pixperbar / 3), getY(bl[i].Close)); // draw time labels (time @30min and date@noon) // if interval is intra-day if (bl.DefaultInterval != BarInterval.Day) { // every 6 bars draw the bartime if ((i % labeleveryX) == 0) { g.DrawString(bl[i].Bartime.ToString(), f.Font, new SolidBrush(fgcol), getX(i), r.Height - (f.Font.GetHeight() * 3)); } // if it's noon, draw the date if (bl[i].Bartime == 1200) { g.DrawString(bl[i].Bardate.ToString(), f.Font, new SolidBrush(fgcol), getX(i), r.Height - (float)(f.Font.GetHeight() * 1.5)); } } else // otherwise it's daily data { // get date int[] date = Calc.Date(bl[i].Bardate); int[] lastbardate = date; // get previous bar date if we have one if ((i - 1) > 0) { lastbardate = Calc.Date(bl[i - 1].Bardate); } // if we have room since last time we drew the year if ((getX(lastlabelcoord) + minxlabelwidth) <= getX(i)) { // get coordinate for present days label lastlabelcoord = i; // draw day g.DrawString(date[2].ToString(), f.Font, new SolidBrush(fgcol), getX(i), r.Height - (f.Font.GetHeight() * 3)); } // if it's first bar or a new month if ((i == 0) || (lastbardate[1] != date[1])) { // get the month string ds = date[1].ToString(); // if it sfirst bar or the year has changed, add year to month if ((i == 0) || (lastbardate[0] != date[0])) { ds += '/' + date[0].ToString(); } // draw the month g.DrawString(ds, f.Font, new SolidBrush(fgcol), getX(i), r.Height - (float)(f.Font.GetHeight() * 1.5)); } } } catch (OverflowException) { } } // DRAW YLABELS // max number of even intervaled ylabels possible on yaxis int numlabels = (int)((r.Height - border * 2) / (f.Font.GetHeight() * 1.5)); // nearest price units giving "pretty" even intervaled ylabels decimal priceunits = NearestPrettyPriceUnits(highesth - lowestl, numlabels); // starting price point from low end of range, including lowest low in barlist decimal lowstart = lowestl - ((lowestl * 100) % (priceunits * 100)) / 100; // original "non-pretty" price units calc //decimal priceunits = (highesth-lowestl)/numlabels; Pen priceline = new Pen(Color.BlueViolet); priceline.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot; for (decimal i = 0; i <= numlabels; i++) { decimal price = lowstart + (i * priceunits); g.DrawString(price.ToString("C"), f.Font, new SolidBrush(fgcol), r.Width - border, getY(price) - f.Font.GetHeight()); g.DrawLine(priceline, border / 3, getY(price), r.Width - border, getY(price)); } DrawLabels(); }