protected void PaintOnBackBuffer(int width, int height)
 {
     if (vectorGraphics)
     {
         return;
     }
     if (!area.IsEmpty)
     {
         backBuffer.FillRectangle(Color.LightGray, 0, 0, width, height);
         backBuffer.FillRectangle(Color.White, area.X, area.Y, area.Width, area.Height);
     }
     else
     {
         backBuffer.FillRectangle(BackColor, 0, 0, width, height);
     }
     PaintGrid(width, height);
     SymbolProperties[] gg = ArrayUtils.GetKeys(values);
     int[] counts          = new int[gg.Length];
     for (int i = 0; i < counts.Length; i++)
     {
         counts[i] = values[gg[i]].Count;
     }
     int[] o = ArrayUtils.Order(counts);
     Array.Reverse(o);
     gg = ArrayUtils.SubArray(gg, o);
     foreach (SymbolProperties g in gg)
     {
         bool[,] vals    = values[g].Data;
         double[,] zvals = null;
         if (zValues != null)
         {
             zvals = zValues[g];
         }
         for (int i = 0; i < width; i++)
         {
             for (int j = 0; j < height; j++)
             {
                 if (vals[i, j] && backBuffer != null)
                 {
                     Color color;
                     if (zvals != null && !double.IsNaN(zvals[i, j]) && colorScale != null)
                     {
                         color = colorScale.GetColor(zvals[i, j]);
                     }
                     else
                     {
                         color = g.Color;
                     }
                     SymbolType symbolType = SymbolType.allSymbols[g.Type];
                     int        symbolSize = g.Size;
                     if (symbolSize > 0)
                     {
                         int[] pathX;
                         int[] pathY;
                         symbolType.GetPath(symbolSize, out pathX, out pathY);
                         backBuffer.DrawPath(color, i, j, pathX, pathY);
                     }
                 }
             }
         }
     }
 }
        protected void PaintOnGraphicsBitmap(IGraphics g, int width, int height)
        {
            if (backBuffer == null || scatterPlot == null)
            {
                return;
            }
            UnsafeBitmap copyBackBuffer = new UnsafeBitmap(backBuffer);

            copyBackBuffer.LockBitmap();
            // selected data-points
            foreach (int s in scatterPlot.Selection)
            {
                double[] w = scatterPlot.GetDataAt(s);
                if (w.Length > 0)
                {
                    double           x  = w[0];
                    double           y  = w[1];
                    SymbolProperties gx = GetPointProperties != null?GetPointProperties(s) : defaultSymbol;

                    SymbolType symbolType = SymbolType.allSymbols[gx.Type];
                    int        symbolSize = gx.Size;
                    if (symbolSize > 0)
                    {
                        int[] pathX;
                        int[] pathY;
                        symbolType.GetPath(symbolSize, out pathX, out pathY);
                        copyBackBuffer.DrawPath(SelectionColor, ModelToViewX(x, width), ModelToViewY(y, height), pathX, pathY);
                    }
                }
            }
            copyBackBuffer.UnlockBitmap();
            // labels
            ScatterPlotLabelMode labelMode = scatterPlot.GetLabelMode();
            bool cutLabels = scatterPlot.CutLabels;

            if (labelMode == ScatterPlotLabelMode.All && scatterPlot.HasLabels)
            {
                Font font = new Font("Arial", scatterPlot.FontSize, scatterPlot.FontStyle);
                for (;;)
                {
                    double[] x;
                    double[] y;
                    double[] z;
                    string[] labels;
                    int      index;
                    try{
                        scatterPlot.GetData(out x, out y, out z, out labels, out index);
                    } catch (IndexOutOfRangeException) {
                        break;
                    }
                    if (x == null)
                    {
                        break;
                    }
                    SymbolProperties gx = GetPointProperties != null?GetPointProperties(index) : defaultSymbol;

                    for (int i = 0; i < x.Length; i++)
                    {
                        if (labelMode == ScatterPlotLabelMode.All || scatterPlot.IsSelected(i))
                        {
                            int   ix = ModelToViewX(x[i], width);
                            int   iy = ModelToViewY(y[i], height);
                            Color c;
                            if (z != null && colorScale != null)
                            {
                                c = colorScale.GetColor(z[i]);
                            }
                            else
                            {
                                c = gx.Color;
                            }
                            Brush b = new SolidBrush(c);
                            if (ix >= 0 && iy >= 0 && ix < width && iy < height)
                            {
                                if (labels[i] != null)
                                {
                                    string s = labels[i];
                                    if (cutLabels)
                                    {
                                        if (s.Contains(";"))
                                        {
                                            s = s.Substring(0, s.IndexOf(';'));
                                        }
                                    }
                                    copyBackBuffer.DrawString(s, font, b, ix, iy);
                                }
                            }
                        }
                    }
                }
                scatterPlot.Reset();
            }
            if (labelMode == ScatterPlotLabelMode.Selected && scatterPlot.HasLabels)
            {
                Brush br   = new SolidBrush(SelectionColor);
                Font  font = new Font("Arial", scatterPlot.FontSize, scatterPlot.FontStyle);
                foreach (int s in scatterPlot.Selection)
                {
                    double[] w     = scatterPlot.GetDataAt(s);
                    string   label = scatterPlot.GetLabelAt(s);
                    double   x     = w[0];
                    double   y     = w[1];
                    int      ix    = ModelToViewX(x, width);
                    int      iy    = ModelToViewY(y, height);
                    if (ix >= 0 && iy >= 0 && ix < width && iy < height)
                    {
                        if (label != null)
                        {
                            if (cutLabels)
                            {
                                if (label.Contains(";"))
                                {
                                    label = label.Substring(0, label.IndexOf(';'));
                                }
                            }
                            copyBackBuffer.DrawString(label, font, br, ix, iy);
                        }
                    }
                }
            }
            // draw the image
            g.DrawImageUnscaled(copyBackBuffer.Bitmap, 0, 0);
            copyBackBuffer.Dispose();
            g.SmoothingMode = SmoothingMode.AntiAlias;
            DrawPolygons(g, width, height);
            if (drawFunctions != null)
            {
                drawFunctions(g, width, height, ModelToViewX, ModelToViewY, ViewToModelX, ViewToModelY);
            }
            g.SmoothingMode = SmoothingMode.Default;
        }