protected void RecalcValuesImpl(int width, int height)
        {
            if (width < 0 || height < 0)
            {
                return;
            }
            if (scatterPlot != null)
            {
                InvalidateData();
                for (;;)
                {
                    double[] x;
                    double[] y;
                    double[] z;
                    string[] labels;
                    int      index;
                    scatterPlot.GetData(out x, out y, out z, out labels, out index);
                    if (x == null)
                    {
                        break;
                    }
                    if (z != null)
                    {
                        if (zValues == null)
                        {
                            zValues = new Dictionary <SymbolProperties, double[, ]>();
                        }
                        double min;
                        double max;
                        ArrayUtils.MinMax(z, out min, out max);
                        if (double.IsNaN(scatterPlot.ColorMax) || max > scatterPlot.ColorMax)
                        {
                            scatterPlot.ColorMax = max;
                        }
                        if (double.IsNaN(scatterPlot.ColorMin) || min < scatterPlot.ColorMin)
                        {
                            scatterPlot.ColorMin = min;
                        }
                    }
                    else
                    {
                        zValues = null;
                    }
                    SymbolProperties prop = GetPointProperties != null?GetPointProperties(index) : defaultSymbol;

                    GridData vals;
                    double[,] zVals = null;
                    lock (locker2){
                        if (values.ContainsKey(prop))
                        {
                            try{
                                vals = values[prop];
                            } catch (Exception) {
                                break;
                            }
                        }
                        else
                        {
                            vals = new GridData(0, new bool[width, height]);
                            values.Add(prop, vals);
                        }
                    }
                    if (zValues != null)
                    {
                        lock (locker){
                            if (zValues.ContainsKey(prop))
                            {
                                try {
                                    zVals = zValues[prop];
                                } catch (Exception) {
                                    break;
                                }
                            }
                            else
                            {
                                zVals = new double[width, height];
                                zValues.Add(prop, zVals);
                            }
                        }
                    }
                    for (int i = 0; i < x.Length; i++)
                    {
                        int ix = ModelToViewX(x[i], width);
                        int iy = ModelToViewY(y[i], height);
                        if (ix >= 0 && iy >= 0 && ix < vals.Data.GetLength(0) && iy < vals.Data.GetLength(1))
                        {
                            vals.Data[ix, iy] = true;
                            vals.Count++;
                            if (zVals != null && z != null)
                            {
                                zVals[ix, iy] = z[i];
                            }
                        }
                    }
                }
                scatterPlot.Reset();
                if (colorScale != null)
                {
                    colorScale.Max = scatterPlot.ColorMax;
                    colorScale.Min = scatterPlot.ColorMin;
                }
            }
            InvalidateImage();
            Invalidate();
        }
 protected void RecalcValuesImpl(int width, int height)
 {
     if (width < 0 || height < 0){
         return;
     }
     if (scatterPlot != null) {
         InvalidateData();
         for (;;){
             double[] x;
             double[] y;
             double[] z;
             string[] labels;
             int index;
             scatterPlot.GetData(out x, out y, out z, out labels, out index);
             if (x == null){
                 break;
             }
             if (z != null){
                 if (zValues == null){
                     zValues = new Dictionary<SymbolProperties, double[,]>();
                 }
                 double min;
                 double max;
                 ArrayUtils.MinMax(z, out min, out max);
                 if (double.IsNaN(scatterPlot.ColorMax) || max > scatterPlot.ColorMax) {
                     scatterPlot.ColorMax = max;
                 }
                 if (double.IsNaN(scatterPlot.ColorMin) || min < scatterPlot.ColorMin) {
                     scatterPlot.ColorMin = min;
                 }
             } else{
                 zValues = null;
             }
             SymbolProperties prop = GetPointProperties != null ? GetPointProperties(index) : defaultSymbol;
             GridData vals;
             double[,] zVals = null;
             lock (locker2){
                 if (values.ContainsKey(prop)){
                     try{
                         vals = values[prop];
                     } catch (Exception){
                         break;
                     }
                 } else{
                     vals = new GridData(0, new bool[width,height]);
                     values.Add(prop, vals);
                 }
             }
             if (zValues != null){
                 lock (locker){
                     if (zValues.ContainsKey(prop)) {
                         try {
                             zVals = zValues[prop];
                         } catch (Exception) {
                             break;
                         }
                     } else {
                         zVals = new double[width, height];
                         zValues.Add(prop, zVals);
                     }
                 }
             }
             for (int i = 0; i < x.Length; i++){
                 int ix = ModelToViewX(x[i], width);
                 int iy = ModelToViewY(y[i], height);
                 if (ix >= 0 && iy >= 0 && ix < vals.Data.GetLength(0) && iy < vals.Data.GetLength(1)){
                     vals.Data[ix, iy] = true;
                     vals.Count++;
                     if (zVals != null && z != null){
                         zVals[ix, iy] = z[i];
                     }
                 }
             }
         }
         scatterPlot.Reset();
         if (colorScale != null){
             colorScale.Max = scatterPlot.ColorMax;
             colorScale.Min = scatterPlot.ColorMin;
         }
     }
     InvalidateImage();
     Invalidate();
 }