Search code examples
c#winformstooltipmschart

Formatting Chart DataPoints and showing a Label ToolTip


This is how my chart looks right now:

enter image description here

I have these problems:

  1. The AxisX is a DateTime and formated as Diagramm.ChartAreas[0].AxisX.LabelStyle.Format = "dd.MM.yy HH";. This is working but as you can see if there are to many hours the label is cut off. How can I set a mouseover tooltip for each label of the X-axis?

  2. The series1 is placed on the secondary AxisY2: Diagramm.Series["S1"].YAxisType = AxisType.Secondary;. I formated the axis for currency with Diagramm.ChartAreas[0].AxisY2.LabelStyle.Format = "C0";

As I understand the given value 1088,55 should be rounded to 1089 € but as you can see it is converted to 108855 €. But why? The value is already given as a double...

Update for point 2: Thanks to TaW, converted the , to . and this works

  1. The tooltip for my series1 is created with:

    foreach (DataPoint dp in Diagramm.Series["S1"].Points) { if (dp.YValues[0] > 0) { dp.ToolTip = dp.YValues[0].ToString("C0") + " Umsatz für Stunde " + dp.AxisLabel.ToString() + ""; } else { dp.IsValueShownAsLabel = false; } }

I would like to have the hour from the AxisX which is formated as "dd.MM.yy HH". How can I access the hour instead of dp.AxisLabel.ToString() which is wrong?

Update for point 3: Thanks to TaW, DateTime.FromOADate(Convert.ToDouble(dp.XValue.ToString())).Hour is working

Thanks


Solution

  • Since parts 2&3 were resolved from the comments we are left with the big one: How can we get tooltips for axis labels.

    There are no predefined ones for axis labels it seems. The Axis itself does support a ToolTip but doesn't accept the Keywords like #VALX etc..

    So we need to set its tip value when we hit a Label. Here is how we can do that:

    We code the MouseMove event to test for hitting a Label. Then we use the data we find there to create a ToolTip string.

    It starts rather simple:

    • We do the HittTest
    • We check for having hit one of the AxisLabels
    • Then we cast the object to CustomLabel

    This is interesting: We are using plain, automatically created AxisLabels but what the HitTest returns are CustomLabels!!

    One of the consequences is that we don't have a Value but instead the ToPosition and FromPosition values. Since the labels were created automatically we can expect them to be arranged symmetrically; so to get the Value we can simply take the middle..

    Since your x-axis holds DateTime converted to double as usual we can now convert back to DateTime and format the tip with the same format string you used for the LabelStyle. If you want to you could of course pick another format here..

    private void chart_MouseMove(object sender, MouseEventArgs e)
    {
        HitTestResult hit = chart.HitTest(e.X, e.Y, ChartElementType.AxisLabels);
    
        if (hit != null && hit.ChartElementType == ChartElementType.AxisLabels)
        {
            Axis ax = chart.ChartAreas[0].AxisX;
            var lab = hit.Object as CustomLabel;
            if (lab == null || lab.Axis != ax) return;
            double d = (lab.ToPosition + lab.FromPosition) / 2d;
            DateTime dt = DateTime.FromOADate(d);
    
            string tip =  dt.ToString(ax.LabelStyle.Format);
            ax.ToolTip = tip; 
        }
    }
    

    One problem with this is that you need to hit the axis rather well or else the ToolTip won't fire.

    enter image description here

    You could avoid this by using a ToolTip of your own but this goes beyond the scope of this queston; it would involve a Timer you start/stop in the MouseMove. you would create the ToolTip string in the Tick event and would have to make sure the tip comes and goes nicely..