public FormTempMonitor()
        {
            InitializeComponent();
            RegMemory.RestoreWindowPos("tempMonitorWindow", this);
            this.SuspendLayout();
            comboMonitor.SelectedIndex = 0;
            source = new DataSource();
            source.AutoScaleY = true;
            source.AutoScaleX = false;
            source.Name = "Temperature";
            source.OnRenderXAxisLabel += RenderXLabel;
            source.OnRenderYAxisLabel += RenderYLabel;
            source.SetDisplayRangeY(0, 300);
            source.SetGridDistanceY(10);
            source.SetGridOriginY(20);
            source.GraphColor = Color.Red;

            target = new DataSource();
            target.AutoScaleY = true;
            target.AutoScaleX = false;
            target.Name = "Target temp.";
            target.OnRenderXAxisLabel += RenderXLabel;
            target.OnRenderYAxisLabel += RenderYLabel;
            target.SetDisplayRangeY(0, 300);
            target.SetGridDistanceY(10);
            target.SetGridOriginY(20);
            target.GraphColor = Color.Blue;
            target.Active = false; // only show when requested

            output = new DataSource();
            output.AutoScaleY = true;
            output.AutoScaleX = false;
            output.Name = "Output";
            output.OnRenderXAxisLabel += RenderXLabel;
            output.OnRenderYAxisLabel += RenderYLabel;
            output.SetDisplayRangeY(0, 255);
            output.SetGridDistanceY(50);
            output.SetGridOriginY(0);
            output.GraphColor = Color.Green;

            /* for (int i = 0; i < 1500; i++)
                         {
                             source.Add(i, 23f+180f*(1-300/(1+i))+20f*(float)Math.Sin(0.1f*i));
                         }*/
            plotter.DataSources.Add(source);
            plotter.DataSources.Add(target);
            plotter.DataSources.Add(output);
            plotter.SetDisplayRangeX(0, 300);
            plotter.SetGridDistanceX(15);

            plotter.PanelLayout = PlotterGraphPaneEx.LayoutMode.VERTICAL_ARRANGED;
            plotter.BackgroundColorTop = Color.Black;
            plotter.BackgroundColorBot = Color.Black;
            plotter.SolidGridColor = Color.DarkGray;
            plotter.DashedGridColor = Color.DarkGray;

            this.ResumeLayout();
            Main.conn.eventTempMonitor += OnTempMonitor;
        }
 private String RenderYLabel(DataSource s, float value)
 {
     return value.ToString("0");
 }
        private void DrawYLabels(Graphics g, DataSource source, List<int> marker_pos,  float offset_x,  float offset_y )
        {
            using (Brush b = new SolidBrush(source.GraphColor))
            {
                using (Pen pen = new Pen(b))
                {
                    pen.DashPattern = new float[] { 2, 2 };

                    // draw labels for horizontal lines
                    if (source.DY != 0)
                    {
                        float Idx = 0;

                        float y0 = (float)(source.grid_off_y * source.CurGraphHeight / source.DY + source.off_Y);

                        String value = "" + Idx;

                        if (source.OnRenderYAxisLabel != null)
                        {
                            value = source.OnRenderYAxisLabel(source, Idx);
                        }

                        SizeF dim = g.MeasureString(value, legendFont);
                        g.DrawString(value, legendFont, b, new PointF((int)offset_x - dim.Width, (int)(offset_y + y0 + 0.5f + dim.Height / 2)));

                        float GridDistY = source.grid_distance_y;

                        if (source.AutoScaleY)
                        {
                            // calculate a matching grid distance
                           // GridDistY = - Utilities.MostSignificantDigit(source.DY );

                            if (GridDistY == 0)
                            {
                                GridDistY =  source.grid_distance_y;

                            }
                        }

                        for (Idx =  (source.grid_off_y); Idx >  (source.Cur_YD0); Idx -=  GridDistY)
                        {
                            if (Idx != 0)
                            {
                                float y1 = (float)((Idx) * source.CurGraphHeight) / source.DY + source.off_Y;

                                value = "" + (Idx);

                                if (source.OnRenderYAxisLabel != null)
                                {
                                    value = source.OnRenderYAxisLabel(source, Idx);
                                }

                                dim = g.MeasureString(value, legendFont);
                                g.DrawString(value, legendFont, b, new PointF((int)offset_x - dim.Width, (int)(offset_y + y1 + 0.5f + dim.Height / 2)));
                            }
                        }

                        for (Idx =  (source.grid_off_y); Idx <  (source.Cur_YD1); Idx +=  GridDistY)
                        {
                            if (Idx != 0)
                            {
                                float y2 = (float)((Idx) * source.CurGraphHeight) / source.DY + source.off_Y;

                                value = "" + (Idx);

                                if (source.OnRenderYAxisLabel != null)
                                {
                                    value = source.OnRenderYAxisLabel(source, Idx);
                                }

                                dim = g.MeasureString(value, legendFont);
                                g.DrawString(value, legendFont, b, new PointF((int)offset_x - dim.Width, (int)(offset_y + y2 + 0.5f + dim.Height / 2)));
                            }
                        }
                    }
                }
            }
        }
 private String RenderXLabel(DataSource s, int idx)
 {
     float x = ((cPoint)s.Samples[idx]).x;
     return x.ToString("0", GCode.format);
 }
        private void DrawXLabels(Graphics g, DataSource source, List<int> marker_pos, float offset_x, float offset_y)
        {
            Color XLabColor = source.GraphColor;

            if (layout == LayoutMode.NORMAL || layout == LayoutMode.STACKED)
            {
                XLabColor = GraphBoxColor;
            }

            using (Brush b = new SolidBrush(XLabColor))
            {
                using (Pen pen = new Pen(b))
                {
                    pen.DashPattern = new float[] { 2, 2 };

                    if (DX != 0 && source.DY != 0)
                    {
                        if (source.Samples != null && source.Samples.Count > 1)
                        {
                            ArrayList data = source.Samples;

                            float mult_y = source.CurGraphHeight / source.DY;
                            float mult_x = source.CurGraphWidth / DX;

                            float coff_x = off_X - starting_idx * mult_x;

                            if (source.AutoScaleX)
                            {
                                coff_x = off_X;     // avoid dragging in x-autoscale mode
                            }

                            foreach (int i in marker_pos)
                            {
                                int xi = (int)(((cPoint)data[i]).x);

                                if (xi % grid_distance_x == 0)
                                {
                                    float x = ((cPoint)data[i]).x * mult_x   + coff_x;

                                    String value = "" + ((cPoint)data[i]).x;

                                    if (source.OnRenderXAxisLabel != null)
                                    {
                                        value = source.OnRenderXAxisLabel(source, i);
                                    }

                                    if (MoveMinorGrid == false)
                                    {
                                        g.DrawLine(pen, x, GraphCaptionLineHeight + offset_y + source.CurGraphHeight - 14, x, GraphCaptionLineHeight + offset_y + source.CurGraphHeight);
                                        g.DrawString(value, legendFont, b, new PointF((int)(0.5f + x + offset_x + 4), GraphCaptionLineHeight + offset_y + source.CurGraphHeight - 12));
                                    }
                                    else
                                    {
                                        SizeF dim = g.MeasureString(value, legendFont);
                                        g.DrawString(value, legendFont, b, new PointF((int)(0.5f + x + offset_x + 4 - dim.Width / 2), GraphCaptionLineHeight + offset_y + source.CurGraphHeight - 12));

                                    }
                                }
                            }
                        }
                    }

                }
            }
        }
        private void DrawGrid( Graphics g, DataSource source,  float CurrOffX, float CurOffY )
        {
            int Idx = 0;
            float mult_x = source.CurGraphWidth / DX;
            float coff_x = off_X - starting_idx * mult_x;

            if (source.AutoScaleX)
            {
            coff_x = off_X;     // avoid dragging in x-autoscale mode
            }

            Color CurGridColor = MajorGridColor;
            Color CurMinGridClor = MinorGridColor;

            if (layout == LayoutMode.NORMAL && source.AutoScaleY)
            {
            CurGridColor = source.GraphColor;
            CurMinGridClor = source.GraphColor;
            }

            using (Pen minorGridPen = new Pen(CurMinGridClor))
            {
               minorGridPen.DashPattern = MinorGridPattern;
               minorGridPen.DashStyle = MinorGridDashStyle;

               using (Pen p2 = new Pen(CurGridColor))
               {
                p2.DashPattern = MajorGridPattern;
                p2.DashStyle = MajorGridDashStyle;

                if (DX != 0)
                {
                    while (true)
                    {
                        float x = Idx * grid_distance_x * source.CurGraphWidth / DX + grid_off_x * source.CurGraphWidth / DX;

                        if (MoveMinorGrid)
                        {
                            x += coff_x;
                        }

                        if (x > 0 && x < source.CurGraphWidth)
                        {
                            g.DrawLine(minorGridPen, new Point((int)(x + CurrOffX - 0.5f), (int)(CurOffY)),
                                                     new Point((int)(x + CurrOffX - 0.5f), (int)(CurOffY + source.CurGraphHeight)));
                        }
                        if (x > source.CurGraphWidth)
                        {
                            break;
                        }

                        Idx++;
                    }
                }

                if (source.DY != 0)
                {
                    float y0 = (float)(source.grid_off_y * source.CurGraphHeight / source.DY + source.off_Y);

                    // draw horizontal zero grid lines
                    g.DrawLine(p2, new Point((int)CurrOffX, (int)(CurOffY + y0 + 0.5f)), new Point((int)(CurrOffX + source.CurGraphWidth + 0.5f), (int)(CurOffY + y0 + 0.5f)));

                    // draw horizontal grid lines
                    for (Idx = (int)(source.grid_off_y);Idx > (int)(source.YD0 ); Idx -= (int)source.grid_distance_y)
                    {
                        float y = (float)(Idx * source.CurGraphHeight) / source.DY + source.off_Y;

                        if (y >= 0 && y < source.CurGraphHeight)
                        {
                            g.DrawLine(minorGridPen,
                                        new Point((int)CurrOffX, (int)(CurOffY + y + 0.5f)),
                                        new Point((int)(CurrOffX + source.CurGraphWidth + 0.5f), (int)(0.5f + CurOffY + y)));
                        }
                    }

                    // draw horizontal grid lines
                    for (Idx = (int)(source.grid_off_y); Idx < (int)(source.YD1  ); Idx += (int)source.grid_distance_y)
                    {
                        float y = (float)Idx * source.CurGraphHeight / source.DY + source.off_Y;

                        if (y >= 0 && y < source.CurGraphHeight)
                        {
                            g.DrawLine(minorGridPen,
                                       new Point((int)CurrOffX, (int)(CurOffY + y + 0.5f)),
                                       new Point((int)(CurrOffX + source.CurGraphWidth + 0.5f), (int)(0.5f + CurOffY + y)));
                        }
                    }
                }
            }
            }
        }
        private List<int> DrawGraphCurve( Graphics g, DataSource source,  float offset_x, float offset_y )
        {
            List<int> marker_positions = new List<int>();

            if (DX != 0 && source.DY != 0)
            {
                List<Point> ps = new List<Point>();

                if (source.Samples != null && source.Samples.Count > 1)
                {

                    int DownSample = source.Downsampling;
                    ArrayList data = source.Samples;
                    float mult_y = source.CurGraphHeight / source.DY;
                    float mult_x = source.CurGraphWidth / DX;
                    float coff_x = off_X - starting_idx * mult_x;

                    if (source.AutoScaleX)
                    {
                        coff_x = off_X;     // avoid dragging in x-autoscale mode
                    }

                    for (int i = 0; i < data.Count - 1; i += DownSample)
                    {
                        float x = ((cPoint)data[i]).x  * mult_x   + coff_x;
                        float y = ((cPoint)data[i]).y  * mult_y + source.off_Y;

                        int xi = (int)(((cPoint)(data[i])).x);

                        if (xi % grid_distance_x == 0)
                        {
                            if (x >= (0 - pad_xlabel) && x <= (source.CurGraphWidth + pad_xlabel))
                            {
                                if (i == 0)
                                    marker_positions.Add(i);
                                else
                                {
                                    int xxi = (int)(((cPoint)(data[i-1])).x);
                                    if (xxi % grid_distance_x != 0)
                                    {
                                        marker_positions.Add(i);
                                    }
                                }
                            }
                        }

                        if (x > 0 && x < (source.CurGraphWidth))
                        {
                            ps.Add(new Point((int)(x + offset_x+0.5f), (int)(y  + offset_y  + 0.5f)));
                        }
                        else if (x > source.CurGraphWidth)
                        {
                            break;
                        }
                    }

                    using (Pen p = new Pen(source.GraphColor))
                    {
                        if (ps.Count > 0)
                        {
                            g.DrawLines(p, ps.ToArray());
                        }
                    }
                }
            }
            return marker_positions;
        }
        private void DrawGraphCaption(Graphics g, DataSource source, List<int> marker_pos, float offset_x, float offset_y)
        {
            using (Brush b = new SolidBrush(source.GraphColor))
            {
                using (Pen pen = new Pen(b))
                {
                    pen.DashPattern = new float[] { 2, 2 };

                    g.DrawString(source.Name, legendFont, b, new PointF(offset_x + 12, offset_y + 2));

                }
            }
        }
        private void DrawGraphBox(  Graphics g, DataSource source,
                                    float offset_x,
                                     float offset_y,
                                    float GraphCaptionLineHeight  )
        {
            using (Pen p2 = new Pen(GraphBoxColor))
            {
                g.DrawLine(p2, new Point((int)(offset_x + 0.5f), (int)(offset_y + 0.5f)),
                              new Point((int)(offset_x + source.CurGraphWidth - 0.5f), (int)(offset_y + 0.5f)));

                g.DrawLine(p2, new Point((int)(offset_x + source.CurGraphWidth - 0.5f), (int)(offset_y + 0.5f)),
                             new Point((int)(offset_x + source.CurGraphWidth - 0.5f), (int)(offset_y + source.CurGraphHeight + GraphCaptionLineHeight / 2 + 0.5f)));

                g.DrawLine(p2, new Point((int)(offset_x + source.CurGraphWidth - 0.5f), (int)(offset_y + source.CurGraphHeight + GraphCaptionLineHeight / 2 + 0.5f)),
                           new Point((int)(offset_x + 0.5f), (int)(offset_y + source.CurGraphHeight + GraphCaptionLineHeight / 2 + 0.5f)));

                g.DrawLine(p2, new Point((int)(offset_x + 0.5f), (int)(offset_y + source.CurGraphHeight + GraphCaptionLineHeight / 2 + 0.5f)),
                          new Point((int)(offset_x + 0.5f), (int)(offset_y + 0.5f)));
            }
        }