Introduce mechanism that will allow the vertical axis to appear at a certain position regardless of the size of its labels. For reference see Stock Series \ Indicators example.
To reproduce: WaterfallSeries series = new WaterfallSeries(); series.ShowLabels = true; series.DataPoints.Add(new WaterfallDataPoint(50000, false, false, "Beginning\nBalance")); series.DataPoints.Add(new WaterfallDataPoint(17000, false, false, "Jan")); series.DataPoints.Add(new WaterfallDataPoint(14000, false, false, "Feb")); series.DataPoints.Add(new WaterfallDataPoint(-12000, false, false, "Mar")); series.DataPoints.Add(new WaterfallDataPoint(69000, true, false, "Q1")); series.DataPoints.Add(new WaterfallDataPoint(-22000, false, false, "Apr")); series.DataPoints.Add(new WaterfallDataPoint(-18000, false, false, "May")); series.DataPoints.Add(new WaterfallDataPoint(500, false, false, "Jun")); series.DataPoints.Add(new WaterfallDataPoint(-30000, true, false, "Q2")); series.DataPoints.Add(new WaterfallDataPoint(39000, false, true, "Ending\nBalance")); this.radChartView1.Series.Add(series); CartesianGridLineAnnotation annotation1 = new CartesianGridLineAnnotation(); annotation1.Label = "Annotation"; annotation1.ForeColor = Color.Lime; annotation1.BackColor = Color.Black; this.radChartView1.Annotations.Add(annotation1); Workaround: public RadForm1() { InitializeComponent(); this.radChartView1.CreateRenderer += radChartView1_CreateRenderer; WaterfallSeries series = new WaterfallSeries(); series.ShowLabels = true; series.DataPoints.Add(new WaterfallDataPoint(50000, false, false, "Beginning\nBalance")); series.DataPoints.Add(new WaterfallDataPoint(17000, false, false, "Jan")); series.DataPoints.Add(new WaterfallDataPoint(14000, false, false, "Feb")); series.DataPoints.Add(new WaterfallDataPoint(-12000, false, false, "Mar")); series.DataPoints.Add(new WaterfallDataPoint(69000, true, false, "Q1")); series.DataPoints.Add(new WaterfallDataPoint(-22000, false, false, "Apr")); series.DataPoints.Add(new WaterfallDataPoint(-18000, false, false, "May")); series.DataPoints.Add(new WaterfallDataPoint(500, false, false, "Jun")); series.DataPoints.Add(new WaterfallDataPoint(-30000, true, false, "Q2")); series.DataPoints.Add(new WaterfallDataPoint(39000, false, true, "Ending\nBalance")); this.radChartView1.Series.Add(series); CartesianGridLineAnnotation annotation1 = new CartesianGridLineAnnotation(); annotation1.Label = "Annotation"; annotation1.ForeColor = Color.Lime; annotation1.BackColor = Color.Black; annotation1.PositonOffset = new SizeF(0, -20); annotation1.Axis = this.radChartView1.Axes[1] as CartesianAxis; annotation1.Value = 70000; annotation1.BorderColor = Color.Red; annotation1.BorderDashStyle = DashStyle.Solid; annotation1.BorderWidth = 1; this.radChartView1.Annotations.Add(annotation1); } 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 - 1; i++) { CartesianGridLineAnnotationDrawPart annotationPart = this.DrawParts[i] as CartesianGridLineAnnotationDrawPart; if (annotationPart != null) { this.DrawParts[i] = new CustomCartesianGridLineAnnotationDrawPart((CartesianGridLineAnnotation)annotationPart.Element, this); } } } } public class CustomCartesianGridLineAnnotationDrawPart : CartesianGridLineAnnotationDrawPart { public CustomCartesianGridLineAnnotationDrawPart(CartesianGridLineAnnotation element, CartesianRenderer renderer) : base(element, renderer) { } public override void Draw() { FieldInfo fi = typeof(CartesianGridLineAnnotation).GetField("model", BindingFlags.NonPublic | BindingFlags.Instance); ChartAnnotationModel model = fi.GetValue(this.Element) as ChartAnnotationModel; RectangleF rect = ChartRenderer.ToRectangleF(model.LayoutSlot); rect.Offset(this.ViewportOffsetX, this.ViewportOffsetY); Graphics graphics = this.Renderer.Surface as Graphics; RadGdiGraphics radGraphics = new RadGdiGraphics(graphics); Rectangle 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; FillPrimitiveImpl fill = new FillPrimitiveImpl(this.Element, null); fill.PaintFill(radGraphics, null, rect); TextPrimitiveHtmlImpl text = new TextPrimitiveHtmlImpl(); text.PaintPrimitive(radGraphics, 0f, new SizeF(1f, 1f), tp); } }
When trying to drill down PieChart on RadChartView the code throws exception. Workaround: private void radChartView_Drill(object sender, DrillEventArgs e){ e.View.Parent = this.radChartViewUsers.ChartElement.Wrapper; e.View.AreaType = ChartAreaType.Pie; //do drill logic}
Add RightToLeft support in DrillDownNavigator.
The Line Series cannot be clicked/selected and cannot be used in DrillDown scenarios.
We should add a way for users to bind a property in the data source that will be used as a legend title for pie data points. Resolution: Set the LegendTitleMember property to bind legend title of PieSeries.
Currently only axes labels can be rotated. There should be a way to rotate series labels as well. Resolution: Set the LabelRotationAngle property of the series to preferred angle.
Steps to reproduce: 1. Add chart to a form. 2. Add two bar series with CombineMode set to Stack100 3. Add two data points to the series with values 0.0 and identical category 4. Run the project an you will see an exception.
Add Scatter area series support for RadChartView.
Use the following setup:
private void RadForm1_Load(object sender, EventArgs e)
{
// TODO: This line of code loads data into the 'nwindDataSet.Orders' table. You can move, or remove it, as needed.this.ordersTableAdapter.Fill(this.nwindDataSet.Orders);
this.radPivotGrid1.RowGroupDescriptions.Add(new DateTimeGroupDescription() { PropertyName = "OrderDate", Step = DateTimeStep.Year, GroupComparer = new GroupNameComparer() });
this.radPivotGrid1.RowGroupDescriptions.Add(new DateTimeGroupDescription() { PropertyName = "OrderDate", Step = DateTimeStep.Quarter, GroupComparer = new GroupNameComparer() });
this.radPivotGrid1.RowGroupDescriptions.Add(new DateTim
eGroupDescription() { PropertyName = "OrderDate", Step = DateTimeStep.Month, GroupComparer = new GroupNameComparer() });
this.radPivotGrid1.ColumnGroupDescriptions.Add(new PropertyGroupDescription() { PropertyName = "EmployeeID", GroupComparer = new GrandTotalComparer() });
this.radPivotGrid1.AggregateDescriptions.Add(new PropertyAggregateDescription() { PropertyName = "Freight", AggregateFunction = AggregateFunctions.Sum });
this.radPivotGrid1.AggregateDescriptions.Add(new PropertyAggregateDescription() { PropertyName = "Freight", AggregateFunction = AggregateFunctions.Average });
this.radPivotGrid1.FilterDescriptions.Add(new PropertyFilterDescription() { PropertyName = "ShipCountry", CustomName = "Country" });
this.radPivotGrid1.DataSource = this.ordersBindingSource;
this.radPivotGrid1.ChartDataProvider.UpdateCompleted += radPivotGrid1_UpdateCompleted;
this.radChartView1.DataSource = this.radPivotGrid1;
}
private void radPivotGrid1_UpdateCompleted(object sender, EventArgs e)
{
foreach (CartesianSeries series inthis.radChartView1.Series)
{
series.ShowLabels = true;
series.LabelRotationAngle = 90;
}
}
Once you select "% of Grand Total" for one of the aggregates, it would be good the respective chart labels to be formatted in a similar way out of the box:
Desired Behavior:
Actual behavior:
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.
Before zoom:
After zoom:
Why exists the Crosshair feature only for the WPF version of the RadChartView and not for the WinForms implementation? Is there a plan to release that feature for WinForms too? Thx in advance Uli
To reproduce: - Use HTML- like text formatting in the chart title. - Export the chart to image. - The tags are shown in the text. Workaround: private void radButton1_Click(object sender, EventArgs e) { radChartView1.ShowTitle = false; TextPrimitiveHtmlImpl impl = new TextPrimitiveHtmlImpl(); TextParams textParams = this.radChartView1.ChartElement.TitleElement.TextParams; SizeF size = impl.MeasureOverride(new SizeF(500f, 200), textParams); using (MemoryStream stream = new MemoryStream()) { radChartView1.ExportToImage(stream, new Size(500, 500 - (int)size.Height)); Bitmap bmp = new Bitmap(500, 500); using (Graphics g = Graphics.FromImage(bmp)) { g.Clear(Color.White); textParams.paintingRectangle = new RectangleF(Point.Empty, size); impl.PaintPrimitive(new RadGdiGraphics(g), textParams); g.DrawImage(Image.FromStream(stream), 0, size.Height, 500, 500 - size.Height); } bmp.Save(@"D:\xfile.bmp"); } radChartView1.ShowTitle = true; }
To reproduce: BarSeries barSeries = new BarSeries("Performance", "RepresentativeName"); barSeries.Name = "Q1"; barSeries.CombineMode = ChartSeriesCombineMode.Stack; 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); BarSeries barSeries2 = new BarSeries("Performance", "RepresentativeName"); barSeries2.Name = "Q2"; barSeries2.CombineMode = ChartSeriesCombineMode.Stack; 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")); this.radChartView1.Series.Add(barSeries2); BarSeries barSeries3 = new BarSeries("Performance", "RepresentativeName"); barSeries3.Name = "Q3"; barSeries3.CombineMode = ChartSeriesCombineMode.Stack; barSeries3.DataPoints.Add(new CategoricalDataPoint(153, "Harley")); barSeries3.DataPoints.Add(new CategoricalDataPoint(141, "White")); barSeries3.DataPoints.Add(new CategoricalDataPoint(130, "Smith")); barSeries3.DataPoints.Add(new CategoricalDataPoint(88, "Jones")); barSeries3.DataPoints.Add(new CategoricalDataPoint(109, "Marshall")); this.radChartView1.Series.Add(barSeries3); this.radChartView1.ShowTrackBall = true; Note: the trackball labels should be displayed in the order the series are displayed in the chart view. Workaround: private void ChartTrackballController_TextNeeded(object sender, TextNeededEventArgs e) { string pattern = " \\d+.?\\d* "; StringBuilder sb = new StringBuilder("<html>"); List<DataPointInfo> points = new List<DataPointInfo>(); foreach (DataPointInfo dp in e.Points) { points.Add(dp); } points.Reverse(); foreach (DataPointInfo dp in points) { Color pointColor = this.GetColorForDataPoint(dp.Series, dp.DataPoint); string color = string.Format("{0},{1},{2},{3}", pointColor.A, pointColor.R, pointColor.G, pointColor.B); sb.AppendFormat("<color={0}>{1}", color, string.Format("{0} {1}", dp.Series.Name, ((CategoricalDataPoint)dp.DataPoint).Value)); sb.AppendLine(); } e.Text = sb.ToString(); } protected virtual Color GetColorForDataPoint(ChartSeries series, DataPoint point) { if (series is IndicatorBase) { return series.BorderColor; } foreach (UIChartElement element in series.Children) { DataPointElement pointElement = element as DataPointElement; if (pointElement != null) { if (pointElement.DataPoint.Equals(point)) { if (pointElement.BackColor.A > 0) { return pointElement.BackColor; } else { return pointElement.BorderColor; } } } } return Color.Black; }
Workaround: use the ChartTrackerballController.TextNeeded event.
To reproduce: - Use the attached file to reproduce. Workaround: - Reset the chart data source: THIS-OBJECT:radChartView1:DataSource = ?. THIS-OBJECT:radChartView1:DataSource = THIS-OBJECT:bindingSource1.
To reproduce: public RadForm1() { InitializeComponent(); this.radChartView1.AreaType = ChartAreaType.Pie; PieSeries series = new PieSeries(); series.DataPoints.Add(new PieDataPoint(50, "Germany")); series.DataPoints.Add(new PieDataPoint(70, "United States")); series.DataPoints.Add(new PieDataPoint(40, "France")); series.DataPoints.Add(new PieDataPoint(25, "United Kingdom")); series.ShowLabels = true; this.radChartView1.Series.Add(series); radChartView1.ShowLegend = true; } Random rnd = new Random(); private void radButton1_Click(object sender, EventArgs e) { this.radChartView1.Series[0].DataPoints.RemoveAt(0); this.radChartView1.Series[0].DataPoints.Add(new PieDataPoint(rnd.Next(100), rnd.Next(100).ToString())); } Workaround: private void radButton1_Click(object sender, EventArgs e) { this.radChartView1.Series[0].DataPoints.RemoveAt(0); this.radChartView1.Series[0].DataPoints.Add(new PieDataPoint(50, rnd.Next(100).ToString())); this.radChartView1.ChartElement.LegendElement.Items.Clear(); foreach (PieSeries series in radChartView1.Series) { for (int i = 0; i < series.DataPoints.Count; i++) { var dataPoint = series.DataPoints[i] as PieDataPoint; var element = series.Children[i] as PiePointElement; var legendItem = new LegendItem(element); legendItem.Title = dataPoint.LegendTitle; this.radChartView1.ChartElement.LegendElement.Items.Add(legendItem); } } }