This is a migrated thread and some comments may be shown as answers.

Behaviour-based chart print solution

3 Answers 112 Views
Chart
This is a migrated thread and some comments may be shown as answers.
Alex
Top achievements
Rank 1
Alex asked on 15 Sep 2011, 10:44 PM
Hello.
In the examples I found the solution that use the RadRichTextBox to print a Chart. As for me, it looks a little strange. So, I use something like this:

public class ChartPrintBehaviour
{
    private const double ImageMargin = 100;
    private const double PageMargin = 10;
 
    private readonly RadChart chart;
 
    private readonly string header;
 
    private readonly bool portrait;
 
    public static readonly DependencyProperty IsEnabledProperty = DependencyProperty.RegisterAttached("IsEnabled", typeof(bool), typeof(ChartPrintBehaviour), new PropertyMetadata(false, IsEnabledChanged));
     
    public static readonly DependencyProperty HeaderProperty = DependencyProperty.RegisterAttached("Header", typeof(string), typeof(ChartPrintBehaviour));
 
    public static readonly DependencyProperty PortraitProperty = DependencyProperty.RegisterAttached("Portrait", typeof(bool), typeof(ChartPrintBehaviour));
 
    public ChartPrintBehaviour(RadChart chart, string header, bool portrait)
    {
        this.chart = chart;
        this.header = header;
        this.portrait = portrait;
    }
 
    public static void SetIsEnabled(DependencyObject dependencyObject, bool isEnabled)
    {
        dependencyObject.SetValue(IsEnabledProperty, isEnabled);
    }
 
    public static bool GetIsEnabled(DependencyObject dependencyObject)
    {
        return (bool)dependencyObject.GetValue(IsEnabledProperty);
    }
 
    public static void SetHeader(DependencyObject dependencyObject, string header)
    {
        dependencyObject.SetValue(HeaderProperty, header);
    }
 
    public static void SetPortrait(DependencyObject dependencyObject, bool portrait)
    {
        dependencyObject.SetValue(PortraitProperty, portrait);
    }
 
    private static void IsEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var chart = d as RadChart;
        if (chart == null)
        {
            return;
        }
 
        if (!((bool)e.NewValue))
        {
            return;
        }
        var header = d.GetValue(HeaderProperty);
        var beh = new ChartPrintBehaviour(chart, header == null ? string.Empty : header.ToString(), (bool)d.GetValue(PortraitProperty));
        beh.Attach();
    }
 
    private void Attach()
    {
        chart.CommandBindings.Add(new CommandBinding(ApplicationCommands.Print, PrintExecuted, CanPrintExecute));
    }
 
    private void CanPrintExecute(object sender, CanExecuteRoutedEventArgs e)
    {
        e.CanExecute = chart != null;
    }
 
    private void PrintExecuted(object sender, ExecutedRoutedEventArgs e)
    {
        if (chart == null)
        {
            return;
        }
 
        var dlg = new PrintDialog { PrintQueue = LocalPrintServer.GetDefaultPrintQueue() };
        dlg.PrintTicket = dlg.PrintQueue.DefaultPrintTicket;
        if (!portrait)
        {
            dlg.PrintTicket.PageOrientation = PageOrientation.Landscape;
        }
 
        if (!dlg.ShowDialog().GetValueOrDefault())
        {
            return;
        }
 
        var doc = new FlowDocument
        {
            PageWidth = dlg.PrintableAreaWidth - PageMargin,
            PageHeight = dlg.PrintableAreaHeight - PageMargin
        };
 
        FillDocument(doc);
 
        var writer = PrintQueue.CreateXpsDocumentWriter(dlg.PrintQueue);
        writer.Write(((IDocumentPaginatorSource)doc).DocumentPaginator, dlg.PrintTicket);
    }
 
    protected virtual void FillDocument(FlowDocument doc)
    {
        var bi = new BitmapImage();
        bi.BeginInit();
        bi.CacheOption = BitmapCacheOption.OnLoad;
        var ms = new MemoryStream();
        chart.ExportToImage(ms, new PngBitmapEncoder());
        bi.StreamSource = ms;
        bi.EndInit();
         
        var img = new Image
        {
            Source = bi,
            Stretch = Stretch.Uniform,
            Height = doc.PageHeight - ImageMargin,
            Width = doc.PageWidth - ImageMargin,
            VerticalAlignment = VerticalAlignment.Top
        };
 
        Run headerRun = null;
        if (!string.IsNullOrEmpty(header))
        {
            headerRun = new Run(header);
        }
 
        var fig = new Figure
        {
            VerticalAnchor = FigureVerticalAnchor.ContentTop,
            HorizontalAnchor = FigureHorizontalAnchor.ContentCenter
        };
 
        if (headerRun != null)
        {
            fig.Blocks.Add(new Paragraph(headerRun) { TextAlignment = TextAlignment.Center });
        }
 
        var block = new BlockUIContainer(img);
        fig.Blocks.Add(block);
 
        doc.Blocks.Add(new Paragraph(fig));
    }
}

After that we can print any Chart with the this code:

  <telerik:RadChart TelerikExtentions:ChartPrintBehaviour.Header="Print Header"
                          TelerikExtentions:ChartPrintBehaviour.IsEnabled="True">
 <telerik:ChartArea.ContextMenu>
      <ContextMenu>
           <MenuItem Header="Print" Command="Print" />
      </ContextMenu>
</telerik:ChartArea.ContextMenu>
 

3 Answers, 1 is accepted

Sort by
0
Evgenia
Telerik team
answered on 21 Sep 2011, 08:05 AM
Hi Alex,

Thanks for sharing your sample code and approach for printing RadChart. I suggest that you send us your sample project so that  as a Code Library sample - it's a place for exchanging code samples, sharing knowledge and getting hands-on experience. For more information you can read here.

P.S. Your Telerik points were updated.

All the best,
Evgenia
the Telerik team
Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>
0
andrea
Top achievements
Rank 1
answered on 10 Nov 2015, 07:58 AM

Hello,

 

i try to use your code but i'm unable to do this:

<telerik:RadChart TelerikExtentions:ChartPrintBehaviour.Header="Print Header"
                          TelerikExtentions:ChartPrintBehaviour.IsEnabled="True">

 

What is "TelerikExtensions"​?

 

thank you

0
Evgenia
Telerik team
answered on 10 Nov 2015, 12:25 PM
Hi Andrea,

TelerikExtensions is a namespace name that points to a local class -- the one that Alex used to create an attached behavior. He posted the full source code below.

On a side note I'd like to say that we highly encourage our clients to migrate to our newest charting control - RadChartView. It addresses some of the limitations and deficiencies that we have identified in the RadChart implementation over the years (we chose to implement a separate control in order not to break backwards compatibility). Also the RadChartView control has been around for some years and provides rich and mature functionality that covers a large spectrum of user case scenarios. There is a very detailed documentation article that points the differencies between the RadChart and RadChartView controls here.

Regards,
Evgenia
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Tags
Chart
Asked by
Alex
Top achievements
Rank 1
Answers by
Evgenia
Telerik team
andrea
Top achievements
Rank 1
Share this question
or