Blogs

Blogs

DevExpress XAF - Chart Module - Customisable Hover Values & Formatting on Stacked Bar Charts

The DevExpress XAF Charting module can be used to quickly create charts which can then be used on dashboards or reports. The module does contain a lot of built in functionality however there are some areas which require custom code to override and expand the functionality.

One of these areas is the hover values on stacked bar charts, by default when a use hovers over a stacked bar charts bars a hover screen appears listing the values within the chart, however we have found two issues with this which we needed to implement our own custom code to work how we desired.

One of these issues is that the values are not formatted e.g. if the value is a decimal which is from a calculation the value on the hover menu could be shown to as many decimal places as the actual value which isn't very user friendly and doesn't look the best, the other issue is that if there is only a single value being shown in the stacked bar char then the hover value menu only displays the value and not the argument within the series along with the value or the menu header like the hover menu does when there is more than one value to be displayed.

See screenshots below for examples of these described issues.

  

To overcome these issues we implemented a custom view controller to override and expand the hover values on initial chart creation when the screen is loaded, is it also necessary to run the same code when the screen is refreshed and the charts are reloaded. An example of this code is below.
//------------------------------------------------------------------------------------------------- 
// <copyright file="ChartViewController.cs" company="PSP">
//  Copyright (c) PSP. All rights reserved.
// </copyright>
//-------------------------------------------------------------------------------------------------
 
namespace Pspbs.Vision.Module.Controllers
{
    using System;
    using System.Linq;
    using DevExpress.Data.Filtering;
    using DevExpress.ExpressApp;
    using DevExpress.ExpressApp.Chart.Win;
    using DevExpress.ExpressApp.SystemModule;
    using DevExpress.ExpressApp.Win.Editors;
    using DevExpress.XtraCharts;
 
    /// <summary>
    /// Chart View Controller
    /// </summary>
    public partial class ChartViewController : ViewController
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="ChartViewController"/> class.
        /// </summary>
        public ChartViewController()
        {
            this.InitializeComponent();
            this.RegisterActions(this.components);
        }
 
        /// <summary>
        /// Called when [activated].
        /// </summary>
        protected override void OnActivated()
        {
            base.OnActivated();
            View.ObjectSpace.Reloaded += this.Reloaded; 
            Frame.GetController<FilterController>().SetFilterAction.Execute += this.Reloaded;
        }
 
        /// <summary>
        /// Called when [view controls created].
        /// </summary>
        protected override void OnViewControlsCreated()
        {
            base.OnViewControlsCreated();
 
            if (this.View != null)
            {
                if (View.Id == "ViewId")
                {
                    ChartListEditor chartListEditor = (ChartListEditor)((ListView)View).Editor;
                    chartListEditor.ChartControl.CustomDrawCrosshair += this.ChartControl_CustomDrawCrosshair;
                    chartListEditor.ChartControl.SeriesTemplate.CrosshairLabelPattern = "{S} {V:n2}";
                }
            }
        }
 
        /// <summary>
        /// Reloaded the specified sender.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        private void Reloaded(object sender, EventArgs e)
        {
            if (this.View != null)
            {
                if (View.Id == "ViewId")
                {
                    ChartListEditor chartListEditor = (ChartListEditor)((ListView)View).Editor;
                    chartListEditor.ChartControl.CustomDrawCrosshair += this.ChartControl_CustomDrawCrosshair;
                    chartListEditor.ChartControl.SeriesTemplate.CrosshairLabelPattern = "{S} {V:n2}";
                }
            }
        }
 
        /// <summary>
        /// Handles the CustomDrawCrosshair event of the ChartControl control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="DevExpress.XtraCharts.CustomDrawCrosshairEventArgs"/> instance containing the event data.</param>
        private void ChartControl_CustomDrawCrosshair(object sender, DevExpress.XtraCharts.CustomDrawCrosshairEventArgs e)
        {
            if (e.CrosshairElements.Count() == 1)
            {
                ChartListEditor chartListEditor = (ChartListEditor)((ListView)View).Editor;
                var header = e.CrosshairGroupHeaderElements.First();
                var point = header.SeriesPoints.First();
                header.Text = point.Argument;
            }
        }
    }
}
See screenshots below for the results of the view controller and how it effects the charts.

This website uses cookies to provide the best possible experience. By continuing to use our website you are agreeing to our use of cookies.