How to reproduce: Public Class Form1 Sub New() InitializeComponent() Dim barSeries As New Telerik.WinControls.UI.BarSeries("Performance", "RepresentativeName") barSeries.Name = "Q1" barSeries.LegendTitle = "LegendTitle1" + vbCrLf + "LegendTitle1" + vbCrLf + "LegendTitle1" + vbCrLf + "LegendTitle1" + vbCrLf + "Leg barSeries.DataPoints.Add(New CategoricalDataPoint(177, "Harley")) barSeries.DataPoints.Add(New CategoricalDataPoint(128, "White")) barSeries.DataPoints.Add(New CategoricalDataPoint(143, "Smith")) barSeries.DataPoints.Add(New CategoricalDataPoint(111, "Jones")) barSeries.DataPoints.Add(New CategoricalDataPoint(118, "Marshall")) Me.RadChartView1.Series.Add(barSeries) Dim barSeries2 As New Telerik.WinControls.UI.BarSeries("Performance", "RepresentativeName") barSeries2.Name = "Q2" barSeries2.LegendTitle = "LegendTitle1" + vbCrLf + "LegendTitle1" + vbCrLf + "LegendTitle1" + vbCrLf + "LegendTitle1" + vbCrLf + "Le barSeries2.DataPoints.Add(New CategoricalDataPoint(153, "Harley")) barSeries2.DataPoints.Add(New CategoricalDataPoint(141, "White")) barSeries2.DataPoints.Add(New CategoricalDataPoint(130, "Smith")) barSeries2.DataPoints.Add(New CategoricalDataPoint(88, "Jones")) barSeries2.DataPoints.Add(New CategoricalDataPoint(109, "Marshall")) Me.RadChartView1.Series.Add(barSeries2) Me.RadChartView1.ShowTitle = True Me.RadChartView1.ShowLegend = True Me.RadChartView1.LegendTitle = "Legend" Me.RadChartView1.Size = New Size(500, 150) Me.RadChartView1.ShowPanZoom = True 'Me.SetupLineSeries() End Sub Private Sub RadButton1_Click(sender As Object, e As EventArgs) Handles RadButton1.Click Dim filePath As String = "..\..\exprotedChart2.png" Me.RadChartView1.ExportToImage(filePath, New Size(1000, 800), System.Drawing.Imaging.ImageFormat.Png) End Sub End Class Workaround: increase the size of the chart Public Class Form1 Sub New() InitializeComponent() Dim barSeries As New Telerik.WinControls.UI.BarSeries("Performance", "RepresentativeName") barSeries.Name = "Q1" barSeries.LegendTitle = "LegendTitle1" + vbCrLf + "LegendTitle1" + vbCrLf + "LegendTitle1" + vbCrLf + "LegendTitle1" + vbCrLf + "LegendTitle1" + vbCrLf + "LegendTitle1" barSeries.DataPoints.Add(New CategoricalDataPoint(177, "Harley")) barSeries.DataPoints.Add(New CategoricalDataPoint(128, "White")) barSeries.DataPoints.Add(New CategoricalDataPoint(143, "Smith")) barSeries.DataPoints.Add(New CategoricalDataPoint(111, "Jones")) barSeries.DataPoints.Add(New CategoricalDataPoint(118, "Marshall")) Me.RadChartView1.Series.Add(barSeries) Dim barSeries2 As New Telerik.WinControls.UI.BarSeries("Performance", "RepresentativeName") barSeries2.Name = "Q2" barSeries2.LegendTitle = "LegendTitle1" + vbCrLf + "LegendTitle1" + vbCrLf + "LegendTitle1" + vbCrLf + "LegendTitle1" + vbCrLf + "LegendTitle1" + vbCrLf + "LegendTitle1" barSeries2.DataPoints.Add(New CategoricalDataPoint(153, "Harley")) barSeries2.DataPoints.Add(New CategoricalDataPoint(141, "White")) barSeries2.DataPoints.Add(New CategoricalDataPoint(130, "Smith")) barSeries2.DataPoints.Add(New CategoricalDataPoint(88, "Jones")) barSeries2.DataPoints.Add(New CategoricalDataPoint(109, "Marshall")) Me.RadChartView1.Series.Add(barSeries2) Me.RadChartView1.ShowTitle = True Me.RadChartView1.ShowLegend = True Me.RadChartView1.LegendTitle = "Legend" Me.RadChartView1.Size = New Size(500, 150) Me.RadChartView1.ShowPanZoom = True 'Me.SetupLineSeries() End Sub Dim size As Size Private Sub RadButton1_Click(sender As Object, e As EventArgs) Handles RadButton1.Click AddHandler Me.RadChartView1.SizeChanged, AddressOf RadChartView1_SizeChanged size = Me.RadChartView1.Size Me.RadChartView1.Size = New Size(1000, 800) End Sub Private Sub RadChartView1_SizeChanged(sender As Object, e As EventArgs) RemoveHandler Me.RadChartView1.SizeChanged, AddressOf RadChartView1_SizeChanged Dim filePath As String = "..\..\exprotedChart2.png" Me.RadChartView1.ExportToImage(filePath, Me.RadChartView1.Size, System.Drawing.Imaging.ImageFormat.Png) Me.RadChartView1.Size = size End Sub End Class
To reproduce: - Set the position like this: this.radChartView1.ChartElement.LegendElement.Alignment = ContentAlignment.TopCenter; - Export the chart to an image, the position is not the same as in the application. Workaround: - Set the position manually: this.radChartView1.ChartElement.LegendPosition = LegendPosition.Float; this.radChartView1.ChartElement.LegendOffset = new Point(400, 0);
To reproduce: radChartView1.AreaType = ChartAreaType.Pie; PieSeries series = new PieSeries(); series.DataPoints.Add(new PieDataPoint(50, "Germany")); series.Children.LastOrDefault().BackColor = Color.Red; series.Children.LastOrDefault().BorderColor = Color.Green; series.DataPoints.Add(new PieDataPoint(70, "United States")); series.Children.LastOrDefault().BackColor = Color.Green; series.Children.LastOrDefault().BorderColor = Color.Red; series.DataPoints.Add(new PieDataPoint(40, "France")); series.Children.LastOrDefault().BackColor = Color.Blue; series.Children.LastOrDefault().BorderColor = Color.Yellow; series.DataPoints.Add(new PieDataPoint(25, "United Kingdom")); series.Children.LastOrDefault().BackColor = Color.Yellow; series.Children.LastOrDefault().BorderColor = Color.Blue; this.radChartView1.Series.Add(series); radChartView1.ShowLegend = true; Workaround: for (int i = 0; i < radChartView1.ChartElement.LegendElement.Items.Count; i++) { PieDataPoint point = ((PieDataPoint)series.DataPoints[i]); radChartView1.ChartElement.LegendElement.Items[i].Element.BackColor = Color.Red; radChartView1.ChartElement.LegendElement.Items[i].Element.BorderColor = Color.Yellow; }
Workaround: use a custom ChartPanZoomController public class MyChartPanZoomController : ChartPanZoomController { protected override ActionResult OnMouseWheel(MouseEventArgs e) { if (!(this.Area is CartesianArea)) { return base.OnMouseWheel(e); } if ((Control.ModifierKeys & Keys.Control) == Keys.Control) { IChartView chartView = this.Area.View; double zoomWidth = chartView.ZoomWidth; if (this.PanZoomMode == ChartPanZoomMode.Horizontal || this.PanZoomMode == ChartPanZoomMode.Both) { zoomWidth += ((double)e.Delta / 1200d); } double zoomHeight = chartView.ZoomHeight; if (this.PanZoomMode == ChartPanZoomMode.Vertical || this.PanZoomMode == ChartPanZoomMode.Both) { zoomHeight += ((double)e.Delta / 1200d); } zoomWidth = this.ClampValue(zoomWidth, 1d, 100d); zoomHeight = this.ClampValue(zoomHeight, 1d, 100d); double virtualHorizontalPosition = e.X - this.Area.AreaModel.LayoutSlot.X - chartView.PlotOriginX; double plotAreaVirtualWidth = this.Area.AreaModel.LayoutSlot.Width * chartView.ZoomWidth; double relativeHorizontalPosition = virtualHorizontalPosition / plotAreaVirtualWidth; double newPlotAreaVirtualWidth = this.Area.AreaModel.LayoutSlot.Width * zoomWidth; double newPanOffsetX = (newPlotAreaVirtualWidth * relativeHorizontalPosition) - (e.X - this.Area.AreaModel.LayoutSlot.X); newPanOffsetX = this.ClampValue(newPanOffsetX, 0, this.Area.AreaModel.LayoutSlot.Width * (zoomWidth - 1d)); double virtualVerticalPosition = e.Y - this.Area.AreaModel.LayoutSlot.Y - chartView.PlotOriginY; double plotAreaVirtualHeight = this.Area.AreaModel.LayoutSlot.Height * chartView.ZoomHeight; double relativeVerticalPosition = virtualVerticalPosition / plotAreaVirtualHeight; double newPlotAreaVirtualHeight = this.Area.AreaModel.LayoutSlot.Height * zoomHeight; double newPanOffsetY = (newPlotAreaVirtualHeight * relativeVerticalPosition) - (e.Y - this.Area.AreaModel.LayoutSlot.Y); newPanOffsetY = this.ClampValue(newPanOffsetY, 0, this.Area.AreaModel.LayoutSlot.Height * (zoomHeight - 1d)); this.Area.View.Zoom(zoomWidth, zoomHeight); this.Area.View.Pan(-newPanOffsetX, -newPanOffsetY); } return Controller.Empty; } private double ClampValue(double value, double minValue, double maxValue) { return Math.Max(minValue, Math.Min(value, maxValue)); } }
To reproduce: - Add polar series and selection controller Workaround: private void RadChartView1_CreateRenderer(object sender, ChartViewCreateRendererEventArgs e) { e.Renderer = new MyPolarRenderer(e.Area as PolarArea); } class MyPolarRenderer : PolarRenderer { public MyPolarRenderer(PolarArea area) : base(area) { } public override DataPoint HitTest(int x, int y) { for (int i = 0; i < this.DrawParts.Count; i++) { DataPoint dataPoint = this.DrawParts[i].HitTest(new Point(x, y)); if (dataPoint != null) { return dataPoint; } } return base.HitTest(x, y); } protected override void Initialize() { base.Initialize(); for (int i = 0; i < this.DrawParts.Count; i++) { PolarPointSeriesDrawPart linePart = this.DrawParts[i] as PolarPointSeriesDrawPart; if (linePart != null) { this.DrawParts[i] = new MyDrawpart((PolarPointSeries)linePart.Element, this); } } } } class MyDrawpart : PolarPointSeriesDrawPart { public MyDrawpart(PolarPointSeries series, IChartRenderer renderer) : base(series, renderer) { } public override DataPoint HitTest(Point location) { if (this.Element.PointSize.Width == 0 || this.Element.PointSize.Height == 0) { return null; } for (int i = 0; i < this.Element.DataPoints.Count; i++) { RadRect slot = this.Element.DataPoints[i].LayoutSlot; float pointHalfWidth = this.Element.PointSize.Width / 2; float pointHalfHeight = this.Element.PointSize.Height / 2; RectangleF dataPointBounds = new RectangleF((float)(slot.X - pointHalfWidth), (float)(slot.Y - pointHalfHeight), this.Element.PointSize.Width, this.Element.PointSize.Height); if (dataPointBounds.Contains(location.X, location.Y)) { return this.Element.DataPoints[i]; } } return base.HitTest(location); } }
To reproduce: - Set the palette from the default context menu. - Try to get the palette name. Workaround: class MyChartDataPointElementController : ChartDataPointElementController { protected override RadContextMenu CreatePaletteMenu() { //return base.CreatePaletteMenu(); RadContextMenu menu = new RadContextMenu(); RadChartLocalizationProvider localizationProvider = RadChartLocalizationProvider.CurrentProvider; RadMenuItem paletteItem = new RadMenuItem(localizationProvider.GetLocalizedString(RadChartStringId.Palette)); menu.Items.Add(paletteItem); RadMenuItem item = new RadMenuItem(localizationProvider.GetLocalizedString(RadChartStringId.PaletteArctic)); item.Click += new System.EventHandler(item_Click); paletteItem.Items.Add(item); item = new RadMenuItem(localizationProvider.GetLocalizedString(RadChartStringId.PaletteAutumn)); item.Click += new System.EventHandler(item_Click); paletteItem.Items.Add(item); item = new RadMenuItem(localizationProvider.GetLocalizedString(RadChartStringId.PaletteCold)); item.Click += new System.EventHandler(item_Click); paletteItem.Items.Add(item); item = new RadMenuItem(localizationProvider.GetLocalizedString(RadChartStringId.PaletteFlower)); item.Click += new System.EventHandler(item_Click); paletteItem.Items.Add(item); item = new RadMenuItem(localizationProvider.GetLocalizedString(RadChartStringId.PaletteForest)); item.Click += new System.EventHandler(item_Click); paletteItem.Items.Add(item); item = new RadMenuItem(localizationProvider.GetLocalizedString(RadChartStringId.PaletteGrayscale)); item.Click += new System.EventHandler(item_Click); paletteItem.Items.Add(item); item = new RadMenuItem(localizationProvider.GetLocalizedString(RadChartStringId.PaletteGround)); item.Click += new System.EventHandler(item_Click); paletteItem.Items.Add(item); item = new RadMenuItem(localizationProvider.GetLocalizedString(RadChartStringId.PaletteLilac)); item.Click += new System.EventHandler(item_Click); paletteItem.Items.Add(item); item = new RadMenuItem(localizationProvider.GetLocalizedString(RadChartStringId.PaletteMetro)); item.Click += new System.EventHandler(item_Click); paletteItem.Items.Add(item); item = new RadMenuItem(localizationProvider.GetLocalizedString(RadChartStringId.PaletteNatural)); item.Click += new System.EventHandler(item_Click); paletteItem.Items.Add(item); item = new RadMenuItem(localizationProvider.GetLocalizedString(RadChartStringId.PalettePastel)); item.Click += new System.EventHandler(item_Click); paletteItem.Items.Add(item); item = new RadMenuItem(localizationProvider.GetLocalizedString(RadChartStringId.PaletteRainbow)); item.Click += new System.EventHandler(item_Click); paletteItem.Items.Add(item); item = new RadMenuItem(localizationProvider.GetLocalizedString(RadChartStringId.PaletteSpring)); item.Click += new System.EventHandler(item_Click); paletteItem.Items.Add(item); item = new RadMenuItem(localizationProvider.GetLocalizedString(RadChartStringId.PaletteSummer)); item.Click += new System.EventHandler(item_Click); paletteItem.Items.Add(item); item = new RadMenuItem(localizationProvider.GetLocalizedString(RadChartStringId.PaletteWarm)); item.Click += new System.EventHandler(item_Click); paletteItem.Items.Add(item); item = new RadMenuItem(localizationProvider.GetLocalizedString(RadChartStringId.PaletteWindows8)); item.Click += new System.EventHandler(item_Click); paletteItem.Items.Add(item); item = new RadMenuItem(localizationProvider.GetLocalizedString(RadChartStringId.PaletteSun)); item.Click += new System.EventHandler(item_Click); paletteItem.Items.Add(item); return menu; } void item_Click(object sender, System.EventArgs e) { RadMenuItem item = sender as RadMenuItem; if (item != null) { this.Area.View.Palette = ChartPalette.FromKnownPalette(item.Text); this.Area.View.Palette.Name = item.Text; } } } Change the controller like this: radChartView1.Controllers.Add(new MyChartDataPointElementController());
To reproduce: private void RadChartView1_LabelFormatting(object sender, ChartViewLabelFormattingEventArgs e) { var dataPoint = e.LabelElement.DataPoint as CategoricalDataPoint; if (dataPoint != null) { e.LabelElement.IsVisible = false; } } Workaround: private void RadChartView1_LabelFormatting(object sender, ChartViewLabelFormattingEventArgs e) { var dataPoint = e.LabelElement.DataPoint as CategoricalDataPoint; if (dataPoint != null) { e.LabelElement.Text = ""; } }
Steps to reproduce: 1. Add a chart to a form. 2. Add and remove series continuously. 3. The memory of the project will only raise and memory will not be freed. WORKAROUND*: Clear the data points of the series that is/are removed from the chart. *Although this will significantly reduce the memory consumption it will not eliminate the memory leak. There will still be a small portion of retained memory.
To reproduce: - Add at least two series and zoom the chart so the point from one of the series are visible only - Move the TrackBall - The Track ball is not shown for some of the points.
To reproduce: populate RadChartView with data and try to export it to Emf using (MemoryStream ms = new MemoryStream()) { this.radChartView1.ExportToImage(ms, this.radChartView1.Size, System.Drawing.Imaging.ImageFormat.Emf); } Workaround: use some of the other ImageFormats.
How to reproduce: Dim table As New DataTable() table.Columns.Add("Name", GetType(String)) table.Columns.Add("X", GetType(Integer)) For i As Integer = 0 To 99 table.Rows.Add($"User {i}", i) Next Dim series As New BarSeries() series.DataSource = table series.CategoryMember = "Name" series.ValueMember = "X" RadChartView1.Series.Add(series) CType(RadChartView1.Area, CartesianArea).Orientation = Orientation.Horizontal Dim panZoomController As New ChartPanZoomController() panZoomController.PanZoomMode = ChartPanZoomMode.Vertical RadChartView1.Controllers.Add(panZoomController) RadChartView1.Zoom(1, 8) Workaround: create a custom ChartPanZoomController Dim panZoomController As New MyChartPanZoomController() panZoomController.PanZoomMode = ChartPanZoomMode.Vertical RadChartView1.Controllers.Add(panZoomController) Public Class MyChartPanZoomController Inherits ChartPanZoomController Protected Overrides Function OnMouseMove(e As MouseEventArgs) As ActionResult Dim cartesianArea As CartesianArea = TryCast(Me.Area, CartesianArea) If cartesianArea Is Nothing Then Return MyBase.OnMouseMove(e) End If Dim panPoint As Point? = Me.GetType().BaseType.GetField("panPoint", BindingFlags.Instance Or BindingFlags.NonPublic).GetValue(Me) If e.Button = MouseButtons.Left AndAlso panPoint.HasValue Then Dim offsetX As Double = Me.GetType().BaseType.GetField("offsetX", BindingFlags.Instance Or BindingFlags.NonPublic).GetValue(Me) Dim currentOffsetX As Double = offsetX Dim defaultAxis As Axis = If(cartesianArea.Orientation = Orientation.Horizontal, Me.Area.GetType().GetMethod("GetDefaultFirstAxis", BindingFlags.Instance Or BindingFlags.NonPublic).Invoke(Me.Area, New Object() {}), Me.Area.GetType().GetMethod("GetDefaultSecondAxis", BindingFlags.Instance Or BindingFlags.NonPublic).Invoke(Me.Area, New Object() {})) If Me.PanZoomMode = ChartPanZoomMode.Horizontal OrElse Me.PanZoomMode = ChartPanZoomMode.Both Then currentOffsetX += (panPoint.Value.X - e.Location.X) * -1 If currentOffsetX > 0 Then currentOffsetX = 0 End If If currentOffsetX < defaultAxis.Model.LayoutSlot.Width * (DirectCast(cartesianArea.View, IChartView).ZoomWidth - 1) Then currentOffsetX = -defaultAxis.Model.LayoutSlot.Width * (DirectCast(cartesianArea.View, IChartView).ZoomWidth - 1) End If End If Dim offsetY As Double = Me.GetType().BaseType.GetField("offsetY", BindingFlags.Instance Or BindingFlags.NonPublic).GetValue(Me) Dim currentOffsetY As Double = offsetY If Me.PanZoomMode = ChartPanZoomMode.Vertical OrElse Me.PanZoomMode = ChartPanZoomMode.Both Then currentOffsetY += (panPoint.Value.Y - e.Location.Y) * -1 If currentOffsetY > 0 Then currentOffsetY = 0 End If If currentOffsetY < -defaultAxis.Model.LayoutSlot.Height * (DirectCast(cartesianArea.View, IChartView).ZoomHeight - 1) Then currentOffsetY = -defaultAxis.Model.LayoutSlot.Height * (DirectCast(cartesianArea.View, IChartView).ZoomHeight - 1) End If End If cartesianArea.View.Pan(currentOffsetX, currentOffsetY) End If Return Controller.Empty End Function End Class
Use the attached project to reproduce. Workaround: Hide the panel after the form is shown.
The event should not be triggered when moving the mouse over the same data point, as we already asked for data for it. We can cache it and reuse it.
Steps to reproduce: 1. On a button click create a chart, add series and a data source. 2. Call the Dispose method of the chart. You will notice that the memory allocated by the chart will not be released Workaround: clear the series before you dispose of the chart.
Steps to reproduce: 1. Add RadChartView with two BarSeries 2. Set the Name property of series 3. Set the SelectionMode property to SingleDataPoint 4. Subscribe to the SelectedPointChanging/SelectedPointChanged events. 5. Run the form and select points from different series. The OldSelectedSeries/NewSelectedSeries properties always return the name of the first series now matter which series is selected. Workaround: void radChartView1_SelectedPointChanged(object sender, ChartViewSelectedPointChangedEventArgs e) { BarSeries series = (e.NewSelectedPoint).Presenter as BarSeries; if (series.Name == "Q1") { Console.WriteLine(series.Name); } else if (series.Name == "Q2") { Console.WriteLine(series.Name); } }
To reproduce: LineSeries lineSeries = new LineSeries(); lineSeries.DataPoints.Add(new CategoricalDataPoint(20, "Jan")); lineSeries.DataPoints.Add(new CategoricalDataPoint(22, "Apr")); lineSeries.DataPoints.Add(new CategoricalDataPoint(12, "Jul")); lineSeries.DataPoints.Add(new CategoricalDataPoint(19, "Oct")); lineSeries.LegendTitle = "Series A asdafsafasfd fgsdfg sdfs dfg dafsvsd"; this.radChartView1.Series.Add(lineSeries); LineSeries lineSeries2 = new LineSeries(); lineSeries2.DataPoints.Add(new CategoricalDataPoint(18, "Jan")); lineSeries2.DataPoints.Add(new CategoricalDataPoint(15, "Apr")); lineSeries2.DataPoints.Add(new CategoricalDataPoint(17, "Jul")); lineSeries2.DataPoints.Add(new CategoricalDataPoint(22, "Oct")); lineSeries2.LegendTitle = "Series B sdf asdf adfasdfas dfadsf asdf sadf awef"; this.radChartView1.Series.Add(lineSeries2); LineSeries lineSeries3 = new LineSeries(); lineSeries3.DataPoints.Add(new CategoricalDataPoint(13, "Jan")); lineSeries3.DataPoints.Add(new CategoricalDataPoint(14, "Apr")); lineSeries3.DataPoints.Add(new CategoricalDataPoint(12, "Jul")); lineSeries3.DataPoints.Add(new CategoricalDataPoint(25, "Oct")); lineSeries3.LegendTitle = "Series C sdf asdf adfasdfas dfadsf asdf sadf awef"; this.radChartView1.Series.Add(lineSeries3); this.radChartView1.ShowLegend = true; this.radChartView1.ChartElement.LegendPosition = Telerik.WinControls.UI.LegendPosition.Bottom; radChartView1.ChartElement.LegendElement.StackElement.Orientation = Orientation.Horizontal; Workaround: specify minimum height for the legend radChartView1.ChartElement.LegendElement.MinSize = new Size(0, 50);
To reproduce: - Add two donut series and set their RadiusFactor so both series can be seen. - Add ChartSelectionController. - You will be able to select points from the firs series only. Workaround: class MyPieRenderer : PieRenderer { public MyPieRenderer(PieArea area) : base(area) { } public override DataPoint HitTest(int x, int y) { if (this.DrawParts.Count > 0) { foreach (var item in this.DrawParts) { if (item is PieSeriesDrawPart) { Dictionary<PieDataPoint, GraphicsPath> paths = ((PieSeriesDrawPart)item).PointPaths; foreach (PieDataPoint point in paths.Keys) { GraphicsPath path = new GraphicsPath(); paths.TryGetValue(point, out path); if (path != null) { if (path.IsVisible(x, y)) { return point; } } } } } } return null; } } private void RadChartView1_CreateRenderer(object sender, ChartViewCreateRendererEventArgs e) { e.Renderer = new MyPieRenderer((PieArea)e.Area); }
To reproduce: - Add DateTimeContinuousAxis to a chart and set its MajorStep property. Workaround: Create the DateTimeContinuousAxis in the code behind.
To reproduce: Public Sub New() InitializeComponent() Me.RadChartView1.ShowTitle = True Me.RadChartView1.ChartElement.TitleElement.TextWrap = True Me.RadChartView1.Title = "This is a very long chart title that can't fit in a single line" Dim barSeries As New BarSeries("Performance", "RepresentativeName") barSeries.Name = "Q1" barSeries.DataPoints.Add(New CategoricalDataPoint(177, "Harley")) barSeries.DataPoints.Add(New CategoricalDataPoint(128, "White")) barSeries.DataPoints.Add(New CategoricalDataPoint(143, "Smith")) barSeries.DataPoints.Add(New CategoricalDataPoint(111, "Jones")) barSeries.DataPoints.Add(New CategoricalDataPoint(118, "Marshall")) Me.RadChartView1.Series.Add(barSeries) End Sub Private Sub radButton1_Click(sender As Object, e As EventArgs) Handles RadButton1.Click Dim filePath As String = "..\..\..\exprtedChart.png" Me.RadChartView1.ExportToImage(filePath, Me.RadChartView1.Size, System.Drawing.Imaging.ImageFormat.Png) Process.Start(filePath) End Sub Workaround: titleSize must consider the chart's width Public Sub New() InitializeComponent() AddHandler Me.RadChartView1.CreateRenderer, AddressOf CreateRenderer Me.RadChartView1.ShowTitle = True Me.RadChartView1.ChartElement.TitleElement.TextWrap = True Me.RadChartView1.Title = "This is a very long chart title that can't fit in a single line" Dim barSeries As New BarSeries("Performance", "RepresentativeName") barSeries.Name = "Q1" barSeries.DataPoints.Add(New CategoricalDataPoint(177, "Harley")) barSeries.DataPoints.Add(New CategoricalDataPoint(128, "White")) barSeries.DataPoints.Add(New CategoricalDataPoint(143, "Smith")) barSeries.DataPoints.Add(New CategoricalDataPoint(111, "Jones")) barSeries.DataPoints.Add(New CategoricalDataPoint(118, "Marshall")) Me.RadChartView1.Series.Add(barSeries) End Sub Private Sub radButton1_Click(sender As Object, e As EventArgs) Handles RadButton1.Click Dim filePath As String = "..\..\..\exprtedChart.png" Using fs As New FileStream(filePath, FileMode.Create, FileAccess.Write) ExportToImage(Me.RadChartView1, fs, Me.RadChartView1.Size, System.Drawing.Imaging.ImageFormat.Png) End Using Process.Start(filePath) End Sub Public Sub ExportToImage(chart As RadChartView, stream As Stream, size As Size, imageFormat As ImageFormat) If Not chart.IsLoaded Then chart.LoadElementTree() End If Dim bmp As New Bitmap(size.Width, size.Height) Dim graphics__1 As Graphics = Graphics.FromImage(bmp) graphics__1.Clear(Color.White) Dim titleSize As SizeF = graphics__1.MeasureString(chart.Title, chart.ChartElement.TitleElement.Font, chart.Width) If chart.ChartElement.TitleElement.TextOrientation = Orientation.Vertical Then Dim swap As Single = titleSize.Height titleSize.Height = titleSize.Width titleSize.Width = swap End If Dim titleRect As New RadRect(0, 0, titleSize.Width, titleSize.Height) Dim legendRect As New RadRect(0, 0, size.Width, size.Height) Dim chartRect As RadRect = legendRect Select Case chart.ChartElement.TitlePosition Case TitlePosition.Top, TitlePosition.Bottom titleRect.Width = size.Width Exit Select Case TitlePosition.Right, TitlePosition.Left titleRect.Height = size.Height Exit Select End Select chartRect.X += chart.View.Margin.Left chartRect.Y += chart.View.Margin.Top chartRect.Width -= chart.View.Margin.Horizontal chartRect.Height -= chart.View.Margin.Vertical If chart.ShowTitle Then Select Case chart.ChartElement.TitlePosition Case TitlePosition.Top legendRect.Y += titleRect.Height chartRect.Y += titleRect.Height legendRect.Height -= titleRect.Height chartRect.Height -= titleRect.Height Exit Select Case TitlePosition.Right titleRect.X = size.Width - chart.ChartElement.TitleElement.Size.Width titleRect.Height = size.Height legendRect.Width -= titleRect.Width chartRect.Width -= titleRect.Width Exit Select Case TitlePosition.Bottom titleRect.Y = size.Height - chart.ChartElement.TitleElement.Size.Height titleRect.Width = size.Width legendRect.Height -= titleRect.Height chartRect.Height -= titleRect.Height Exit Select Case TitlePosition.Left titleRect.Height = size.Height legendRect.X += titleRect.Width chartRect.X += titleRect.Width legendRect.Width -= titleRect.Width chartRect.Width -= titleRect.Width Exit Select End Select End If If chart.ShowLegend Then Select Case chart.ChartElement.LegendPosition Case LegendPosition.Right If chart.ChartElement.TitlePosition = TitlePosition.Right Then legendRect.X = titleRect.X - chart.ChartElement.LegendElement.Size.Width Else legendRect.X = size.Width - chart.ChartElement.LegendElement.Size.Width End If legendRect.Width = chart.ChartElement.LegendElement.Size.Width chartRect.Width -= legendRect.Width + chart.View.Margin.Right Exit Select Case LegendPosition.Bottom If chart.ChartElement.TitlePosition = TitlePosition.Bottom Then legendRect.Y = titleRect.Y - chart.ChartElement.LegendElement.Size.Height Else legendRect.Y = size.Height - chart.ChartElement.LegendElement.Size.Height End If legendRect.Height = chart.ChartElement.LegendElement.Size.Height chartRect.Height -= legendRect.Height Exit Select Case LegendPosition.Left legendRect.Width = chart.ChartElement.LegendElement.Size.Width chartRect.X += legendRect.Width + chart.View.Margin.Left chartRect.Width -= legendRect.Width + chart.View.Margin.Left Exit Select Case LegendPosition.Top legendRect.Height = chart.ChartElement.LegendElement.Size.Height chartRect.Y += legendRect.Height chartRect.Height -= legendRect.Height Exit Select Case LegendPosition.Float legendRect.Width = chart.ChartElement.LegendElement.Size.Width legendRect.Height = chart.ChartElement.LegendElement.Size.Height Dim xRatio As Double = size.Width / Me.Size.Width Dim yRatio As Double = size.Height / Me.Size.Height legendRect.X = (chart.ChartElement.LegendOffset.X * xRatio) + (If((chart.ChartElement.TitlePosition = TitlePosition.Left), titleRect.Right, 0.0)) legendRect.Y = (chart.ChartElement.LegendOffset.Y * yRatio) + (If((chart.ChartElement.TitlePosition = TitlePosition.Top), titleRect.Bottom, 0.0F)) Exit Select End Select End If If chart.ShowLegend Then Dim xTransform As Single = CSng(legendRect.X) - chart.ChartElement.LegendElement.ControlBoundingRectangle.X + _ (CSng(legendRect.Width) - chart.ChartElement.LegendElement.ControlBoundingRectangle.Width) / 2.0F Dim yTransform As Single = CSng(legendRect.Y) - chart.ChartElement.LegendElement.ControlBoundingRectangle.Y + _ (CSng(legendRect.Height) - chart.ChartElement.LegendElement.ControlBoundingRectangle.Height) / 2.0F graphics__1.TranslateTransform(xTransform, yTransform) chart.ChartElement.LegendElement.Paint(New RadGdiGraphics(graphics__1), _ chart.ChartElement.LegendElement.ControlBoundingRectangle, 0.0F, New SizeF(1.0F, 1.0F), True) graphics__1.ResetTransform() End If Dim radGraphics As New RadGdiGraphics(graphics__1) If chart.ShowTitle Then radGraphics.DrawString(chart.Title, GetTitleDrawRectangle(ChartRenderer.ToRectangleF(titleRect), _ titleSize, chart.ChartElement.TitleElement.TextAlignment), chart.ChartElement.TitleElement.Font, _ chart.ChartElement.TitleElement.ForeColor, chart.ChartElement.TitleElement.TextParams.CreateStringFormat(), _ chart.ChartElement.TitleElement.TextOrientation, _ chart.ChartElement.TitleElement.FlipText) End If chart.View.Layout(chartRect) renderer.Draw(graphics__1) bmp.Save(stream, imageFormat) chart.View.Layout() End Sub Private Function GetTitleDrawRectangle(drawArea As RectangleF, textRect As SizeF, textAlignment As ContentAlignment) As RectangleF Select Case textAlignment Case ContentAlignment.BottomCenter Return New RectangleF(New PointF(drawArea.X + (drawArea.Width - textRect.Width) / 2.0F, drawArea.Bottom - textRect.Height), textRect) Case ContentAlignment.BottomLeft Return New RectangleF(New PointF(drawArea.X, drawArea.Bottom - textRect.Height), textRect) Case ContentAlignment.BottomRight Return New RectangleF(New PointF(drawArea.Right - textRect.Width, drawArea.Bottom - textRect.Height), textRect) Case ContentAlignment.MiddleCenter Return New RectangleF(New PointF(drawArea.X + (drawArea.Width - textRect.Width) / 2.0F, drawArea.Y + (drawArea.Height - textRect.Height) / 2.0F), textRect) Case ContentAlignment.MiddleLeft Return New RectangleF(New PointF(drawArea.X, drawArea.Y + (drawArea.Height - textRect.Height) / 2.0F), textRect) Case ContentAlignment.MiddleRight Return New RectangleF(New PointF(drawArea.Right - textRect.Width, drawArea.Y + (drawArea.Height - textRect.Height) / 2.0F), textRect) Case ContentAlignment.TopCenter Return New RectangleF(New PointF(drawArea.X + (drawArea.Width - textRect.Width) / 2, drawArea.Y), textRect) Case ContentAlignment.TopLeft Return New RectangleF(drawArea.Location, textRect) Case ContentAlignment.TopRight Return New RectangleF(New PointF(drawArea.Right - textRect.Width, drawArea.Y), textRect) Case Else Return New RectangleF(drawArea.Location, textRect) End Select End Function Dim renderer As CartesianRenderer Private Sub CreateRenderer(sender As Object, e As ChartViewCreateRendererEventArgs) e.Renderer = New CartesianRenderer(DirectCast(e.Area, CartesianArea)) renderer = e.Renderer End Sub
To reproduce: - Enable the Trackball - Use the following code: public RadForm1() { InitializeComponent(); ScatterLineSeries sls = radChartView1.Series[0] as ScatterLineSeries; sls.XValueMember = "X"; sls.YValueMember = "Y"; } private void timer1_Tick(object sender, EventArgs e) { DataTable dt = new DataTable(); dt.Columns.Add("X", typeof(double)); dt.Columns.Add("Y", typeof(double)); Random ran = new Random(); for (int i = 0; i < 100; i++) dt.Rows.Add(i, 1 + ran.NextDouble() / 10); radChartView1.Series[0].DataSource = dt; } Workaround: class MyChartTrackballController : ChartTrackballController { protected override string GetPointText(DataPoint point) { ChartSeries series = point.Presenter as ChartSeries; if (series == null) { return string.Empty; } return base.GetPointText(point); } }