0

I have C# project already done but im having issue with printing it's charts when comes out with more pages of data points, i got the scroll bar work when start getting more pages so the user can review all data on all pages but i could not find how to make the print preview shows them or print them, when click on print, it shows only the first page on the print preview and same thing when print it out.

her is the print code:

     PrintPreviewDialog ppd = new PrintPreviewDialog();

     ppd.Document = this.chart1.Printing.PrintDocument;

     ((Form)ppd).WindowState = FormWindowState.Maximized;

     chart1.Printing.PrintDocument.DefaultPageSettings.Landscape = true;

     
     chart1.Printing.PrintDocument.DefaultPageSettings.Margins.Left = 0;
     chart1.Printing.PrintDocument.DefaultPageSettings.Margins.Right = 0;
     chart1.Printing.PrintDocument.DefaultPageSettings.Margins.Top = 0;
     chart1.Printing.PrintDocument.DefaultPageSettings.Margins.Bottom = 0;

     
     ppd.ShowDialog();

and here is the chart load code:

    public void loadChart(string sqlvalue)//load chart method
     {
     
     chart1.ChartAreas[0].AxisY.Maximum = 55;
     chart1.ChartAreas[0].AxisY.Minimum = 35;
     chart1.ChartAreas[0].AxisY.Interval = 5;//control how many lines/Interval 


     chart1.ChartAreas[0].AxisY.ScrollBar.Enabled = true;
     chart1.ChartAreas[0].AxisY.ScaleView.Zoomable = true;

     chart1.ChartAreas[0].AxisX.Minimum = 0;
    // chart1.ChartAreas[0].AxisX.Maximum = 10;
     chart1.ChartAreas[0].AxisX.Interval = 1;

     //X AXES label angle
     chart1.ChartAreas[0].AxisX.LabelStyle.Angle = 60;
         
     da = new SqlDataAdapter(sqlvalue, cn.connect());

     da.Fill(dt);

     this.chart1.DataSource = dt;
     this.chart1.Series["left"].XValueMember = dt.Columns[3].ToString();//date data
     this.chart1.Series["left"].YValueMembers = dt.Columns[1].ToString();//spindle 1 data
     this.chart1.Series["Right"].YValueMembers = dt.Columns[2].ToString();//spindle 2 data

     //label the series lines, Backcolor and forcolor
     chart1.Series[0].LabelBackColor = Color.Red;
     chart1.Series[0].LabelForeColor = Color.White;



     //datapoint marker's color, bordercolor,style and size
     chart1.Series[0].MarkerColor = Color.White;
     chart1.Series[0].MarkerBorderColor = Color.Black;
     chart1.Series[0].MarkerStyle = MarkerStyle.Circle;
     chart1.Series[0].MarkerSize = 8;

     //datapoint marker's color, style and size
     chart1.Series[1].MarkerColor = Color.White;
     chart1.Series[1].MarkerBorderColor = Color.Black;
     chart1.Series[1].MarkerStyle = MarkerStyle.Circle;
     chart1.Series[1].MarkerSize = 8;

     
     chart1.Series[1].LabelBackColor = Color.Blue;
     chart1.Series[1].LabelForeColor = Color.White;

    
     //Chart background lines color
     chart1.ChartAreas[0].AxisX.MajorGrid.LineColor = Color.Silver;
     chart1.ChartAreas[0].AxisY.MajorGrid.LineColor = Color.Silver;

    

     this.chart1.DataBind();
     cn.disconnect();
  
     // enable autoscroll
     chart1.ChartAreas[0].CursorX.AutoScroll = true;//------------
     chart1.ChartAreas[0].AxisX.ScaleView.Zoomable = true;
     chart1.ChartAreas[0].AxisX.ScaleView.Zoom(0, 15);

     
      
     chart1.ChartAreas[0].AxisX.ScrollBar.ButtonStyle = ScrollBarButtonStyles.SmallScroll;

     // set scrollbar small change to the target size
     chart1.ChartAreas[0].AxisX.ScaleView.SmallScrollSize = 15;


     Legend left = new Legend();
     Legend LC = CustomCloneLegend(chart1, left);
     chart1.Legends.Add(LC);

  
     chart1.Padding = Padding.Empty;

     ChartArea CA = chart1.ChartAreas[0];
     CA.Position = new ElementPosition(4,6, 100, 90);
    
    }
    

Thank you for your time and help, here is the chart code update:

 private static Image MergeImages(List<Image> imageList)
  {
     var finalSize = new Size();
     foreach (var image in imageList)
     {
        if (image.Width > finalSize.Width)
        {
           finalSize.Width = image.Width;
        }
        finalSize.Height += image.Height;
     }
     var outputImage = new Bitmap(finalSize.Width, finalSize.Height);
     using (var gfx = Graphics.FromImage(outputImage))
     {
        var y = 0;
        foreach (var image in imageList)
        {
           gfx.DrawImage(image, 0, y);
           y += image.Height;
        }
     }
     return outputImage;
  }

The second method:

 List<Image> ChartsToImages(List<Chart> charts)
  {
     var imageList = new List<Image>();
     foreach (var c in charts)
     {
        using (var ms = new MemoryStream())
        {
           c.SaveImage(ms, ChartImageFormat.Png);
           var bmp = System.Drawing.Bitmap.FromStream(ms);
           imageList.Add(bmp);
        }
     }
     return imageList;
  }

and this code

     var chartList = new List<Chart> { chart1 };
     var imageList = ChartsToImages(chartList);
     var finalImage = MergeImages(imageList);
     finalImage.Save("D:\\Junk.png", ImageFormat.Png);

Im not sure is that what you mean by your first comment, but i found this code here under Converting chart to image questions. this code convert and saves the chart in the same amount of pages but i need to show them in the printpreviewcontrol and print them.

Mgeeb
  • 9
  • 2
  • There are several routes you may want to choose. One is to create a large (wide) image of the chart and print it in sections. Note that you can create bitmaps much larger than you could show on screen. 40k pixels width is no problem; just set the size and use chart.SaveImage.. This is rather simple but the downside is that all side information like the y-axis or the legend will only show up on the 1st and last section.. – TaW Jun 21 '20 at 08:24
  • Another option would be to show only portions of the data and after capturing it page to the next part. You could either use the scrollbar, which is not so nice on a printout or set the Minimum and Maximum of the X-Axis.. – TaW Jun 21 '20 at 08:26
  • And then there is the bult-in print manager but I don't think it'll work well for multi-page charts. However it should work ok with the Min/Max scrolling above.. ie with shifting the x-Axis Minimum and Maximum values. [Example](https://stackoverflow.com/questions/50076045/chart-auto-scroll-oscilloscope-effect/50077332#50077332) – TaW Jun 21 '20 at 08:42
  • I just did a quick test and with this `ChartArea ca = chart.ChartAreas[0]; Axis ax = ca.AxisX; double min = ax.Minimum; double max = ax.Maximum; int pages = 4; double pagerange = (max - min) / pages; for (int i = 0; i < pages; i++) { ax.Minimum = min + pagerange * i; ax.Maximum = ax.Minimum + pagerange; // do the prinint stuff here! }` one can easily print a chart onto n pages. To actually 'do the printing stuff' you need to decide on whether you want one chart portion per page of you want to print the chart parts onto a page you control otherwise. For the former... – TaW Jun 21 '20 at 09:09
  • ...use ..chart.Printing.Print for the latter integrate the loop into your printing routine and use chart.Printing.PrintPaint with its Graphics object..! And if you want to save pages use a Graphics object from an image.. The Rectangle will let you place and size the chart where and how you want it – TaW Jun 21 '20 at 09:10
  • Thank you i tried execute your idea but i could not. it seam good solution but i dont know how to get it. – Mgeeb Jun 23 '20 at 00:02
  • What exactly did you try (update the question to show the new code!) and what did not work..? – TaW Jun 23 '20 at 07:45
  • Try this one https://stackoverflow.com/questions/57247750/how-to-use-printdocument-with-a-scrollable-panel it prints all records inside a scrollable forms or panel – Cyrille Con Morales Jun 25 '20 at 06:23
  • Thank you, it didnt work i was getting error and when i modified it , iit just stopped working – Mgeeb Jun 26 '20 at 20:51

1 Answers1

0

Below code refers to the as per page count starting point and ending point based printing. And Grid view value chars are row loop based counting the page.

    private int numberOfItemsPerPage = 0;
    private int numberOfItemsPrintedSoFar = 0;

    private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
    {
       
                  

        int height = 480; //page height stating point
        for (int l = numberOfItemsPrintedSoFar; l < dataGridView2.Rows.Count; l++)
        {
            numberOfItemsPerPage = numberOfItemsPerPage + 1;
            if (numberOfItemsPerPage <= 25) // 25 is Page Line Item
            {
                numberOfItemsPrintedSoFar++;

                if (numberOfItemsPrintedSoFar <= dataGridView2.Rows.Count)
                {
                    
                    height += dataGridView2.Rows[0].Height;
                    e.Graphics.DrawString(dataGridView2.Rows[l].Cells[0].FormattedValue.ToString(), dataGridView2.Font = new Font("Book Antiqua", 8), Brushes.Black, new RectangleF(5, height, dataGridView2.Columns[0].Width, dataGridView2.Rows[0].Height));
                    e.Graphics.DrawString(dataGridView2.Rows[l].Cells[1].FormattedValue.ToString(), dataGridView2.Font = new Font("Book Antiqua", 8), Brushes.Black, new RectangleF(170, height, dataGridView2.Columns[0].Width, dataGridView2.Rows[0].Height));
                    e.Graphics.DrawString(dataGridView2.Rows[l].Cells[2].FormattedValue.ToString(), dataGridView2.Font = new Font("Book Antiqua", 8), Brushes.Black, new RectangleF(290, height, dataGridView2.Columns[0].Width, dataGridView2.Rows[0].Height));
                    e.Graphics.DrawString(dataGridView2.Rows[l].Cells[3].FormattedValue.ToString(), dataGridView2.Font = new Font("Book Antiqua", 8), Brushes.Black, new RectangleF(345, height, dataGridView2.Columns[0].Width, dataGridView2.Rows[0].Height));
                }
                else
                {
                    e.HasMorePages = false;
                }

            }
            else
            {
                numberOfItemsPerPage = 0;
                e.HasMorePages = true;
                return;

            }


        }
        numberOfItemsPerPage = 0;
        numberOfItemsPrintedSoFar = 0;

    }



    
barath
  • 1
  • 3
  • While this does show a basic example of multi-page printing I can't see how it answers the question, which is about charts. But after creating the partial images to print it may be used.. – TaW Jun 21 '20 at 08:35