To reproduce:
- Add a polar chart with a selection controller.
- Click near the bottom right corner of the point (10 pixels away)
- The point is selected.
Workaround:
private void Chart_CreateRenderer(object sender, ChartViewCreateRendererEventArgs e)
{
e.Renderer = new MyPolarRenderer(e.Area as PolarArea);
}
class MyPolarRenderer : PolarRenderer
{
public MyPolarRenderer(PolarArea area) : base(area)
{ }
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 null;
}
}
To reproduce: please refer to the attached sample project and gif file.
Workaround:
CustomLassoSelectionController lassoSelectionController = new CustomLassoSelectionController();
this.radChartView1.Controllers.Add(lassoSelectionController);
public class CustomLassoSelectionController : LassoSelectionController
{
private IList<DataPoint> selectedPoints = null;
public CustomLassoSelectionController()
{
this.selectedPoints = new List<DataPoint>();
}
private Point ClipLocation(Point point)
{
CartesianArea area = this.Area.View.GetArea<CartesianArea>();
if (area != null)
{
RectangleF clipRect = GetCartesianClipRect(area);
if (point.X < clipRect.X)
{
point = new Point((int)clipRect.X, point.Y);
}
if (point.X > clipRect.Width + clipRect.X)
{
point = new Point((int)clipRect.Width + (int)clipRect.X, point.Y);
}
if (point.Y < clipRect.Y)
{
point = new Point(point.X, (int)clipRect.Y);
}
if (point.Y > clipRect.Height + clipRect.Y)
{
point = new Point(point.X, (int)clipRect.Height + (int)clipRect.Y);
}
}
return point;
}
internal RectangleF GetCartesianClipRect(CartesianArea area)
{
float x1, x2, y1, y2;
x1 = 0;
y1 = 0;
x2 = (float)area.View.Viewport.Right;
y2 = (float)area.View.Viewport.Bottom;
foreach (var axis in area.View.Axes)
{
if (axis.AxisType == AxisType.First)
{
if (axis.Model.VerticalLocation == AxisVerticalLocation.Bottom)
{
y2 = Math.Min(y2, (float)axis.Model.LayoutSlot.Y);
}
else
{
y1 = Math.Max(y1, (float)axis.Model.LayoutSlot.Bottom);
}
x1 = Math.Min(x1, (float)axis.Model.LayoutSlot.X);
x2 = Math.Min(x2, (float)axis.Model.LayoutSlot.Right);
}
else
{
if (axis.Model.HorizontalLocation == AxisHorizontalLocation.Left)
{
x1 = Math.Max(x1, (float)axis.Model.LayoutSlot.Right);
}
else
{
x2 = Math.Min(x2, (float)axis.Model.LayoutSlot.X);
}
y1 = Math.Max(y1, (float)axis.Model.LayoutSlot.Y);
y2 = Math.Min(y2, (float)axis.Model.LayoutSlot.Bottom);
}
}
RectangleF result = new RectangleF((float)area.View.Viewport.X + x1, (float)area.View.Viewport.Y + y1, x2 - x1 + 1, y2 - y1 + 1);
return result;
}
protected override ActionResult OnMouseUp(MouseEventArgs e)
{
if (e.Button != MouseButtons.Left || this.MouseDownLocation == Point.Empty || this.MouseMoveLocation == Point.Empty)
{
return base.OnMouseUp(e);
}
if (MouseDownLocation != MouseMoveLocation)
{
this.MouseMoveLocation = ClipLocation(e.Location);
CartesianArea area = this.Area.View.GetArea<CartesianArea>();
if (area != null)
{
this.selectedPoints.Clear();
RectangleF areaRect = RectangleF.Empty;
IChartView chartView = this.Area.View;
areaRect = GetCartesianClipRect(area);
Point topLeft = new Point(Math.Min(MouseDownLocation.X, e.X), Math.Min(MouseDownLocation.Y, e.Y));
Point lowerRight = new Point(Math.Max(MouseDownLocation.X, e.X), Math.Max(MouseDownLocation.Y, e.Y));
RectangleF lassoRect = new RectangleF(new PointF(topLeft.X - (float)chartView.PlotOriginX - area.View.Margin.Left, topLeft.Y - (float)chartView.PlotOriginY - area.View.Margin.Top), new SizeF(lowerRight.X - topLeft.X, lowerRight.Y - topLeft.Y));
foreach (var series in area.View.Series)
{
foreach (var dataPoint in series.DataPoints)
{
if (lassoRect.Contains(new PointF((float)dataPoint.LayoutSlot.Location.X, (float)dataPoint.LayoutSlot.Location.Y)))
{
dataPoint.IsSelected = true;
this.selectedPoints.Add(dataPoint);
}
else
{
dataPoint.IsSelected = false;
}
}
}
ChartDataPointsEventArgs changedArgs = new ChartDataPointsEventArgs(this.selectedPoints);
this.OnLassoSelectedPointsChanged(changedArgs);
}
MouseDownLocation = MouseMoveLocation = Point.Empty;
}
this.Result.ShouldInvalidate = true;
return this.Result;
}
}
The new controller should allow lasso selection of data points without zooming the view port.
To reproduce:
public RadForm1()
{
InitializeComponent();
this.radChartView1.AreaType = ChartAreaType.Polar;
PolarAreaSeries polarAreaSeries = new PolarAreaSeries();
PolarDataPoint polarPoint = new PolarDataPoint();
polarPoint.Value = 35;
polarPoint.Angle = 50;
polarAreaSeries.DataPoints.Add(polarPoint);
polarPoint = new PolarDataPoint();
polarPoint.Value = 40;
polarPoint.Angle = 200;
polarAreaSeries.DataPoints.Add(polarPoint);
polarPoint = new PolarDataPoint();
polarPoint.Value = 55;
polarPoint.Angle = 320;
polarAreaSeries.DataPoints.Add(polarPoint);
this.radChartView1.Series.Add(polarAreaSeries);
this.radChartView1.Axes[0].LabelFitMode = AxisLabelFitMode.Rotate;
AxisLabelElement gauche = this.radChartView1.Axes[0].Children[1] as AxisLabelElement;
gauche.Text = "IV Gestion des ressources" + Environment.NewLine + "humaines";
this.radChartView1.View.AxisLabelFormatting+=View_AxisLabelFormatting;
}
Font f = new Font("Arial", 10, FontStyle.Bold);
private void View_AxisLabelFormatting(object sender, ChartAxisLabelFormattingEventArgs e)
{
if (e.LabelElement.Text.Contains("IV"))
{
e.LabelElement.Font = f;
}
}
It would be great to be able to generate Box Plot graphics, both in the RadCharView control and in the Report.
Use attached to reproduce.
Workaround:
Use custom renderer:
private void RadChartView1_CreateRenderer(object sender, ChartViewCreateRendererEventArgs e)
{
e.Renderer = new CustomCartesianRenderer(e.Area as CartesianArea);
}
public class CustomCartesianRenderer : CartesianRenderer
{
public CustomCartesianRenderer(CartesianArea area)
: base(area)
{ }
protected override void Initialize()
{
base.Initialize();
for (int i = 0; i < this.DrawParts.Count; i++)
{
CartesianGridLineAnnotationDrawPart linePart = this.DrawParts[i] as CartesianGridLineAnnotationDrawPart;
if (linePart != null)
{
this.DrawParts[i] = new MyCartesianGridLineAnnotationDrawPart((CartesianGridLineAnnotation)linePart.Element, this);
}
}
}
}
class MyCartesianGridLineAnnotationDrawPart : CartesianGridLineAnnotationDrawPart
{
public MyCartesianGridLineAnnotationDrawPart(CartesianGridLineAnnotation element, CartesianRenderer renderer)
: base(element, renderer)
{ }
public override void Draw()
{
PropertyInfo modelProperty = typeof(CartesianGridLineAnnotation).GetProperty("Model",
System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
object model = modelProperty.GetValue(this.Element);
PropertyInfo layoutProperty = model.GetType().GetProperty("LayoutSlot", BindingFlags.Public | BindingFlags.Instance);
RadRect radRect = (RadRect)layoutProperty.GetValue(model);
RectangleF rect = ChartRenderer.ToRectangleF(radRect);
rect.Offset(this.ViewportOffsetX, this.ViewportOffsetY);
Graphics graphics = this.Renderer.Surface as Graphics;
RadGdiGraphics radGraphics = new RadGdiGraphics(graphics);
var clipRect = ChartRenderer.ToRectangle(this.Element.View.GetArea<CartesianArea>().AreaModel.PlotArea.LayoutSlot);
clipRect.Offset((int)this.ViewportOffsetX,(int) this.ViewportOffsetY);
graphics.SetClip(clipRect);
GraphicsPath path = new GraphicsPath();
path.AddLine(rect.Location, new PointF(rect.Right, rect.Bottom));
BorderPrimitiveImpl border = new BorderPrimitiveImpl(this.Element, null);
border.PaintBorder(radGraphics, null, path, rect);
rect.Size = graphics.MeasureString(this.Element.Label, this.Element.Font);
rect.Offset(this.Element.PositonOffset.Width + 1, this.Element.PositonOffset.Height + 1);
TextParams tp = new TextParams();
tp.font = this.Element.Font;
tp.foreColor = this.Element.ForeColor;
tp.paintingRectangle = rect;
tp.text = this.Element.Label;
TextPrimitiveHtmlImpl text = new TextPrimitiveHtmlImpl();
text.PaintPrimitive(radGraphics, 0f, new SizeF(1f, 1f), tp);
}
}
How to reproduce: check the attached project
Workaround:
private void button1_Click(object sender, EventArgs e)
{
this.radChartView1.DataSource = null;
foreach (ChartSeries series in this.radChartView1.Series)
{
series.DataSource = null;
}
this.radChartView1.Series.Clear();
}
I have use following code to use Both Scrollbar in RadChartView While Zoom. but it not scroll my chart . radchart1.HorizontalScroll.Enabled = true; radchart1.HorizontalScroll.Visible = true; radchart1.VerticalScroll.Enabled = true; radchart1.VerticalScroll.Visible = true; Please help me. Hello Kalpesh, Currently panning in RadChartView cannot be performed using the scrollbars. We have a feature request logged here: https://feedback.telerik.com/Project/154/Feedback/Details/111013-add-radchartview-add-a-scrollbar-that-controls-the-pan-and-zoom Please subscribe to the item so that you be updated when its status changes. For the time being I can suggest using a RadRangeSelector control to zoom and pan the chart. More information is available here: https://docs.telerik.com/devtools/winforms/rangeselector/overview Regards, Hristo
Workaround:
public class MyRadChartView : RadChartView
{
public override string ThemeClassName
{
get
{
return typeof(RadChartView).FullName;
}
}
protected override void Dispose(bool disposing)
{
base.Dispose(false);
}
}
https://demos.telerik.com/kendo-ui/radar-charts/radar-column The attached proejct shows a sample implementation.
To reproduce:
BarSeries barSeries = new BarSeries("Performance", "RepresentativeName");
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"));
this.radChartView1.Series.Add(barSeries);
LinearAxis verticalAxis = radChartView1.Axes.Get<LinearAxis>(1);
verticalAxis.MajorStep = 5;
LinearAxisModel axisModel = verticalAxis.Model as LinearAxisModel;
AxisScaleBreak scaleBreakItem = new AxisScaleBreak();
scaleBreakItem.Name = "Item1";
scaleBreakItem.From = 80d;
scaleBreakItem.To = 120d;
verticalAxis.ScaleBreaks.Add(scaleBreakItem);
When combining scalebreaks and series stacking, the rendered chart does not match the data. See attached solution: The bar of the category "1/2016" has a length of 105 (as indicated by the tooltips) -- but the corresponding axis labeling shows a value of 37. The scalebreak is off too (probably matching the wrong axis).
The new functionality should allow a display similar to the one in the WPF pie series: http://docs.telerik.com/devtools/wpf/controls/radchartview/features/labels/smart-labels#using-smart-labels-in-radpiechart
To reproduce: - Set the title and the offset: radChartView1.Title = "Test Title"; radChartView1.ShowTitle = true; radChartView1.ChartElement.TitleElement.PositionOffset = new SizeF(100, 100); - Export the chart.
To reproduce: Add stacked series with equal category that has negative values as well.
Use LogarithmicAxis and set the Minimum to 0.1 Workaround is availble in the atched project.
Workaround:
CartesianRenderer renderer = null;
public RadForm1()
{
InitializeComponent();
this.radChartView1.CreateRenderer += new ChartViewCreateRendererEventHandler(radChartView1_CreateRenderer);
LineSeries lineSeries = new LineSeries();
lineSeries.LegendTitle = "Line 1";
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"));
this.radChartView1.Series.Add(lineSeries);
LineSeries lineSeries2 = new LineSeries();
lineSeries2.LegendTitle = "Line 2";
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"));
this.radChartView1.Series.Add(lineSeries2);
this.radChartView1.ShowLegend = true;
this.radChartView1.ChartElement.LegendPosition = LegendPosition.Float;
this.radChartView1.ChartElement.LegendOffset = new Point(200, 95);
CartesianArea area = this.radChartView1.GetArea<CartesianArea>();
area.ShowGrid = true;
}
private void radChartView1_CreateRenderer(object sender, ChartViewCreateRendererEventArgs e)
{
renderer = new CartesianRenderer(e.Area as CartesianArea);
e.Renderer = renderer;
}
private void radButton1_Click(object sender, EventArgs e)
{
string filePath = @"..\..\..\exportedChart" + DateTime.Now.ToLongTimeString().Replace(":", "_") + ".png";
using (MemoryStream stream = new MemoryStream())
{
ExportToImage(this.radChartView1, stream, new Size(1000 ,500), ImageFormat.Png, filePath);
}
Process.Start(filePath);
}
public void ExportToImage(RadChartView chart, Stream stream, Size size, ImageFormat imageFormat, string filePath)
{
if (!this.IsLoaded)
{
this.LoadElementTree();
}
size = Telerik.WinControls.TelerikDpiHelper.ScaleSize(size, chart.ChartElement.DpiScaleFactor);
Bitmap bmp = new Bitmap(size.Width, size.Height);
Graphics graphics = Graphics.FromImage(bmp);
graphics.Clear(Color.White);
SizeF titleSize = graphics.MeasureString(chart.Title, chart.ChartElement.TitleElement.Font, this.Width);
if (chart.ChartElement.TitleElement.TextOrientation == Orientation.Vertical)
{
float swap = titleSize.Height;
titleSize.Height = titleSize.Width;
titleSize.Width = swap;
}
RadRect titleRect = new RadRect(0, 0, titleSize.Width, titleSize.Height);
RadRect legendRect = new RadRect(0, 0, size.Width, size.Height);
RadRect chartRect = legendRect;
switch (chart.ChartElement.TitlePosition)
{
case TitlePosition.Top:
case TitlePosition.Bottom:
titleRect.Width = size.Width;
break;
case TitlePosition.Right:
case TitlePosition.Left:
titleRect.Height = size.Height;
break;
}
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)
{
switch (chart.ChartElement.TitlePosition)
{
case TitlePosition.Top:
legendRect.Y += titleRect.Height;
chartRect.Y += titleRect.Height;
legendRect.Height -= titleRect.Height;
chartRect.Height -= titleRect.Height;
break;
case TitlePosition.Right:
titleRect.X = size.Width - chart.ChartElement.TitleElement.Size.Width;
titleRect.Height = size.Height;
legendRect.Width -= titleRect.Width;
chartRect.Width -= titleRect.Width;
break;
case TitlePosition.Bottom:
titleRect.Y = size.Height - chart.ChartElement.TitleElement.Size.Height;
titleRect.Width = size.Width;
legendRect.Height -= titleRect.Height;
chartRect.Height -= titleRect.Height;
break;
case TitlePosition.Left:
titleRect.Height = size.Height;
legendRect.X += titleRect.Width;
chartRect.X += titleRect.Width;
legendRect.Width -= titleRect.Width;
chartRect.Width -= titleRect.Width;
break;
}
}
chart.View.Layout(chartRect);
renderer.Draw(graphics);
if (chart.ShowLegend)
{
switch (chart.ChartElement.LegendPosition)
{
case LegendPosition.Right:
if (chart.ChartElement.TitlePosition == TitlePosition.Right)
{
legendRect.X = titleRect.X - chart.ChartElement.LegendElement.Size.Width;
}
else
{
legendRect.X = size.Width - chart.ChartElement.LegendElement.Size.Width;
}
legendRect.Width = chart.ChartElement.LegendElement.Size.Width;
chartRect.Width -= legendRect.Width;
break;
case LegendPosition.Bottom:
if (chart.ChartElement.TitlePosition == TitlePosition.Bottom)
{
legendRect.Y = titleRect.Y - chart.ChartElement.LegendElement.Size.Height;
}
else
{
legendRect.Y = size.Height - chart.ChartElement.LegendElement.Size.Height;
}
legendRect.Height = chart.ChartElement.LegendElement.Size.Height;
chartRect.Height -= legendRect.Height;
break;
case LegendPosition.Left:
legendRect.Width = chart.ChartElement.LegendElement.Size.Width;
chartRect.X += legendRect.Width;
chartRect.Width -= legendRect.Width;
break;
case LegendPosition.Top:
legendRect.Height = chart.ChartElement.LegendElement.Size.Height;
chartRect.Y += legendRect.Height;
chartRect.Height -= legendRect.Height;
break;
case LegendPosition.Float:
legendRect.Width = chart.ChartElement.LegendElement.Size.Width;
legendRect.Height = chart.ChartElement.LegendElement.Size.Height;
double xRatio = size.Width / this.Size.Width;
double yRatio = size.Height / this.Size.Height;
legendRect.X = (chart.ChartElement.LegendOffset.X * xRatio) + ((chart.ChartElement.TitlePosition == TitlePosition.Left)
? titleRect.Right : 0d);
legendRect.Y = (chart.ChartElement.LegendOffset.Y * yRatio) + ((chart.ChartElement.TitlePosition == TitlePosition.Top)
? titleRect.Bottom : 0f);
break;
}
}
if (chart.ShowLegend)
{
float xTransform = (float)legendRect.X - chart.ChartElement.LegendElement.ControlBoundingRectangle.X +
((float)legendRect.Width - chart.ChartElement.LegendElement.ControlBoundingRectangle.Width) / 2f;
float yTransform = (float)legendRect.Y - chart.ChartElement.LegendElement.ControlBoundingRectangle.Y +
((float)legendRect.Height - chart.ChartElement.LegendElement.ControlBoundingRectangle.Height) / 2f;
graphics.TranslateTransform(xTransform, yTransform);
chart.ChartElement.LegendElement.Paint(new RadGdiGraphics(graphics), chart.ChartElement.LegendElement.ControlBoundingRectangle, 0f,
new SizeF(1f, 1f), true);
graphics.ResetTransform();
}
RadGdiGraphics radGraphics = new RadGdiGraphics(graphics);
if (chart.ShowTitle)
{
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);
}
if (imageFormat == ImageFormat.Emf ||
imageFormat == ImageFormat.Wmf)
{
Metafile metafile = new Metafile(stream, graphics.GetHdc()); // file is created here
using (Graphics g = Graphics.FromImage(metafile))
{
g.DrawImage(bmp, Point.Empty);
}
metafile.Dispose();
graphics.ReleaseHdc();
}
else
{
bmp.Save(stream, imageFormat);
}
chart.View.Layout();
Image img = Image.FromStream(stream);
graphics.DrawImage(img, new Point(0, 0));
img.Save(filePath);
}
private RectangleF GetTitleDrawRectangle(RectangleF drawArea, SizeF textRect, ContentAlignment textAlignment)
{
switch (textAlignment)
{
case ContentAlignment.BottomCenter:
return new RectangleF(new PointF(drawArea.X + (drawArea.Width - textRect.Width) / 2f, 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) / 2f, drawArea.Y + (drawArea.Height - textRect.Height) / 2f),
textRect);
case ContentAlignment.MiddleLeft:
return new RectangleF(new PointF(drawArea.X, drawArea.Y + (drawArea.Height - textRect.Height) / 2f), textRect);
case ContentAlignment.MiddleRight:
return new RectangleF(new PointF(drawArea.Right - textRect.Width, drawArea.Y + (drawArea.Height - textRect.Height) / 2f), 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);
default:
return new RectangleF(drawArea.Location, textRect);
}
}
Use the attached project to reproduce. Workaround: Check for zero values.
How to reproduce:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.radChartView1.ShowLegend = true;
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"));
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"));
this.radChartView1.Series.Add(lineSeries2);
ChartPanZoomController panZoomController = new ChartPanZoomController();
panZoomController.PanZoomMode = ChartPanZoomMode.Horizontal;
radChartView1.Controllers.Add(panZoomController);
}
private void radButton1_Click(object sender, EventArgs e)
{
this.radChartView1.ExportToImage(@"..\..\image.png", this.radChartView1.Size, System.Drawing.Imaging.ImageFormat.Png);
}
}
Workaround: use a custom export to image method
public void ExportChartToImage(string filePath, Size size, ImageFormat imageFormat)
{
using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))
{
if (!this.radChartView1.IsLoaded)
{
this.radChartView1.LoadElementTree();
}
Bitmap bmp = new Bitmap(size.Width, size.Height);
Graphics graphics = Graphics.FromImage(bmp);
graphics.Clear(Color.White);
SizeF titleSize = graphics.MeasureString(this.radChartView1.Title, this.radChartView1.ChartElement.TitleElement.Font, this.Width);
if (this.radChartView1.ChartElement.TitleElement.TextOrientation == Orientation.Vertical)
{
float swap = titleSize.Height;
titleSize.Height = titleSize.Width;
titleSize.Width = swap;
}
RadRect titleRect = new RadRect(0, 0, titleSize.Width, titleSize.Height);
RadRect legendRect = new RadRect(0, 0, size.Width, size.Height);
RadRect chartRect = legendRect;
switch (this.radChartView1.ChartElement.TitlePosition)
{
case TitlePosition.Top:
case TitlePosition.Bottom:
titleRect.Width = size.Width;
break;
case TitlePosition.Right:
case TitlePosition.Left:
titleRect.Height = size.Height;
break;
}
chartRect.X += this.radChartView1.View.Margin.Left;
chartRect.Y += this.radChartView1.View.Margin.Top;
chartRect.Width -= this.radChartView1.View.Margin.Horizontal;
chartRect.Height -= this.radChartView1.View.Margin.Vertical;
if (this.radChartView1.ShowTitle)
{
switch (this.radChartView1.ChartElement.TitlePosition)
{
case TitlePosition.Top:
legendRect.Y += titleRect.Height;
chartRect.Y += titleRect.Height;
legendRect.Height -= titleRect.Height;
chartRect.Height -= titleRect.Height;
break;
case TitlePosition.Right:
titleRect.X = size.Width - this.radChartView1.ChartElement.TitleElement.Size.Width;
titleRect.Height = size.Height;
legendRect.Width -= titleRect.Width;
chartRect.Width -= titleRect.Width;
break;
case TitlePosition.Bottom:
titleRect.Y = size.Height - this.radChartView1.ChartElement.TitleElement.Size.Height;
titleRect.Width = size.Width;
legendRect.Height -= titleRect.Height;
chartRect.Height -= titleRect.Height;
break;
case TitlePosition.Left:
titleRect.Height = size.Height;
legendRect.X += titleRect.Width;
chartRect.X += titleRect.Width;
legendRect.Width -= titleRect.Width;
chartRect.Width -= titleRect.Width;
break;
}
}
if (this.radChartView1.ShowLegend)
{
switch (this.radChartView1.ChartElement.LegendPosition)
{
case LegendPosition.Right:
if (this.radChartView1.ChartElement.TitlePosition == TitlePosition.Right)
{
legendRect.X = titleRect.X - this.radChartView1.ChartElement.LegendElement.Size.Width;
}
else
{
legendRect.X = size.Width - this.radChartView1.ChartElement.LegendElement.Size.Width;
}
legendRect.Width = this.radChartView1.ChartElement.LegendElement.Size.Width;
chartRect.Width -= this.radChartView1.View.Margin.Right;
break;
case LegendPosition.Bottom:
if (this.radChartView1.ChartElement.TitlePosition == TitlePosition.Bottom)
{
legendRect.Y = titleRect.Y - this.radChartView1.ChartElement.LegendElement.Size.Height;
}
else
{
legendRect.Y = size.Height - this.radChartView1.ChartElement.LegendElement.Size.Height;
}
legendRect.Height = this.radChartView1.ChartElement.LegendElement.Size.Height;
chartRect.Height -= legendRect.Height;
break;
case LegendPosition.Left:
legendRect.Width = this.radChartView1.ChartElement.LegendElement.Size.Width;
chartRect.X += legendRect.Width + this.radChartView1.View.Margin.Left;
chartRect.Width -= legendRect.Width + this.radChartView1.View.Margin.Left;
break;
case LegendPosition.Top:
legendRect.Height = this.radChartView1.ChartElement.LegendElement.Size.Height;
chartRect.Y += legendRect.Height;
chartRect.Height -= legendRect.Height;
break;
case LegendPosition.Float:
legendRect.Width = this.radChartView1.ChartElement.LegendElement.Size.Width;
legendRect.Height = this.radChartView1.ChartElement.LegendElement.Size.Height;
double xRatio = size.Width / this.Size.Width;
double yRatio = size.Height / this.Size.Height;
legendRect.X = (this.radChartView1.ChartElement.LegendOffset.X * xRatio) + ((this.radChartView1.ChartElement.TitlePosition == TitlePosition.Left) ? titleRect.Right : 0d);
legendRect.Y = (this.radChartView1.ChartElement.LegendOffset.Y * yRatio) + ((this.radChartView1.ChartElement.TitlePosition == TitlePosition.Top) ? titleRect.Bottom : 0f);
break;
}
}
if (this.radChartView1.ShowLegend)
{
float xTransform = (float)legendRect.X - this.radChartView1.ChartElement.LegendElement.ControlBoundingRectangle.X + ((float)legendRect.Width - this.radChartView1.ChartElement.LegendElement.ControlBoundingRectangle.Width) / 2f;
float yTransform = (float)legendRect.Y - this.radChartView1.ChartElement.LegendElement.ControlBoundingRectangle.Y + ((float)legendRect.Height - this.radChartView1.ChartElement.LegendElement.ControlBoundingRectangle.Height) / 2f;
graphics.TranslateTransform(xTransform, yTransform);
this.radChartView1.ChartElement.LegendElement.Paint(new RadGdiGraphics(graphics), this.radChartView1.ChartElement.LegendElement.ControlBoundingRectangle, 0f, new SizeF(1f, 1f), true);
graphics.ResetTransform();
}
RadGdiGraphics radGraphics = new RadGdiGraphics(graphics);
if (this.radChartView1.ShowTitle)
{
object[] miParams = new object[] { ChartRenderer.ToRectangleF(titleRect), titleSize, this.radChartView1.ChartElement.TitleElement.TextAlignment };
radGraphics.DrawString(this.radChartView1.Title, (RectangleF)typeof(RadChartView).GetMethod("GetTitleDrawRectangle", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(this.radChartView1, miParams), this.radChartView1.ChartElement.TitleElement.Font,
this.radChartView1.ChartElement.TitleElement.ForeColor, this.radChartView1.ChartElement.TitleElement.TextParams.CreateStringFormat(), this.radChartView1.ChartElement.TitleElement.TextOrientation, this.radChartView1.ChartElement.TitleElement.FlipText);
}
this.radChartView1.View.Layout(chartRect);
IChartRenderer renderer = (IChartRenderer)typeof(ChartArea).GetProperty("Renderer", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(this.radChartView1.Area);//
renderer.Draw(graphics);
if (imageFormat == ImageFormat.Emf ||
imageFormat == ImageFormat.Wmf)
{
Metafile metafile = new Metafile(fs, graphics.GetHdc());
using (Graphics g = Graphics.FromImage(metafile))
{
g.DrawImage(bmp, Point.Empty);
}
metafile.Dispose();
graphics.ReleaseHdc();
}
else
{
bmp.Save(fs, imageFormat);
}
this.radChartView1.View.Layout();
}