I set x-axis as logarithmic scale, but it only displays the major labels, exp : 1E000, 1E001, 1E002, etc... Now i also want to display the minor values, for example : 2E000, 3E000, 4E000,..., 2E001, 3E001, .....
it should look like the graph below :
It seems a simple question but i can't find the way to solve this problem. Can anyone help me ?
Thanks in advance.
This question is similar to this one.
It took me a long time to solve this one, but:
If you if you set the MinorGrid Interval to 1, then you get the traditional Logarithmic grid marks, ten per decade:
aChart.ChartAreas[0].AxisX.IsLogarithmic = true;
aChart.ChartAreas[0].AxisX.MinorGrid.Interval = 1;
aChart.ChartAreas[0].AxisX.MinorGrid.Enabled = true;
As far as I know, the only way to do this is by setting the interval property of the axis.LabelStyle e.g.:
this.chart1.ChartAreas[0].AxisX.LabelStyle.Interval = 0.1;
For example, setting 0.1 in a logaritmic scale, the labels show will be 10^0.1, 10^0.2, 10^0.3 ...
If you need something more particular, I suggest you to create the labels manually using the property axis.CustomLabels, even if is not so intuitive...
Related
I'm trying to draw minor gridlines in the center between major gridlines.
chart1.ChartAreas[0].AxisX.MajorGrid.Interval = 4;
chart1.ChartAreas[0].AxisX.MinorGrid.Enabled = true;
chart1.ChartAreas[0].AxisX.MinorGrid.Interval = 3;
chart1.ChartAreas[0].AxisX.MinorGrid.LineColor = Color.Cornsilk;
chart1.ChartAreas[0].AxisX.MinorGrid.LineDashStyle= ChartDashStyle.Solid;
I tried to set different values of chart1.ChartAreas[0].AxisX.MinorGrid.Interval but didn't get expected result.Here what I got so far.
Arrow points to right located minor gridline
I tried to change chart1.ChartAreas[0].AxisX.MinorGrid.IntervalOffset property but it does not change anything. Has someone any suggestions? Thank you in advance.
EDIT
Based on TaW's answer tried to set intervals
chart1.ChartAreas[0].AxisX.MajorGrid.Interval = 4;
chart1.ChartAreas[0].AxisX.MinorGrid.Interval = 2;
got
EDIT 2
It was a good idea proposed by TaW, but since for me was not important LineDashStyle and custom labels are used, I decided to abandon minor lines and instead use major lines and custom labels, plotted for each second line.
Issue resolved
If you want the MinorGrid lines centered between the MajorGrid their Interval ought to be half their value:
Axix ax = chart1.ChartAreas[0].AxisX;
ax.MajorGrid.Interval = 4;
ax.MinorGrid.Interval = ax.MajorGrid.Interval / 2;
If you want more MinorGrid lines the MajorGrid.Interval still should be divisible by MinorGrid.Interval.
In case you really want to set an Offset, both should have the same !
Since your X-Values are DateTimes, you also will want to control the IntervalTypes:
ax.MajorGrid.IntervalType = DateTimeIntervalType.Days;
ax.MinorGrid.IntervalType = DateTimeIntervalType.Days;
Note that, as usual, every other major line overwrites a minor one. If this is a problem you can make the Intervals the same and offset one by half an Interval; but normally it will not matter.
Now I'd like to draw a candlestick chart in C#. Problem I have is how to skip certain time of the x Axis. Say, the data starts from 9:00 and ends at 11:30. Then restart at 13:00 and ends in 15:00. If I fill data in it, period 11:30 to 13:00 will also be shown as a line. How to skip it and make it a consequence chart?
Set series.IsXValueIndexed to true, that should fix your problem
series.IsXValueIndexed = true;
All data points in a series use sequential indices, and if this
property is true then data points will be plotted sequentially,
regardless of their associated X-values. This means that there will be
no "missing" data points.
Take a look at documentation for more info.
I had same problem but after setting series.IsXValueIndexed = true, it not worked for me.
So I've found another way of achieving this.
series.XAxisType = AxisType.Secondary;
series.IsXValueIndexed = true;
Has anyone any idea how to use Excel.XlLegendPosition.xlLegendPositionCustom to specifically position the legend of a chart? Currently, I'm using
chart.Legend.Position = Excel.XlLegendPosition.xlLegendPositionBottom;
which does exactly what one would expect. Right up until the time when you try and print the chart. THEN it places the legend pretty much where ever it wants -- which isn't where I need it to be.
I've checked the MSDN and every other site I could think of. The best Microsoft can come up with is as follows:
xlLegendPositionCustom: A custom position.
There are no examples that I could find that show how to use this.
Thanks for any help.
Okay, it doesn't seem as if anyone has encountered this particular issue -- or needed to use the command. No worries, I appreciate folks taking the time to look at the question.
I did find a workaround that allows you to position the legend using points. It appears if you use the preset positioning options (like Excel.XlLegendPosition.xlLegendPositionBottom), Excel positions the legend based on whatever magic MS uses to figure these things out. Since I couldn't figure out how to use the Excel.XlLegendPosition.xlLegendPositionCustom, I played around with the other commands and found these:
chart.Legend.Left = 375;
chart.Legend.Top = 450;
Those commands will take an int (I used 374 and 450) and using them, you can force the position of the legend to anywhere on the chart.
I don't think you can set it to xlLegendPositionCustom, it's read-only, i.e. when you 'ask'(Debug.Print ActiveChart.Legend.Position), after setting ActiveChart.Legend.Left/ActiveChart.Legend.Top you get -4161 which is xlLegendPositionCustom.
I'm currently using the charting within .NET using System.Windows.Forms.DataVisualization.Charting.Chart. Thus far it seems very powerful, and works great. However, there is a huge problem in terms of how it is auto-calculating intervals. I use a lot of double values, and in libraries like ZedGraph, it handles this perfectly. It selects min/max/interval just fine. However, in MS Chart, it may select 206.3334539832 as a minimum, and intervals of a similar decimal precision. Obviously this looks quite ugly.
So, I tried simply making the axis format {0.00} and it works great when it loads the chart. Except when you zoom in, you need greater precision, maybe at 4 decimal places instead of 2. It seems I'm either stuck with 9 decimal places all the time, or else a constant fixed number that may break when someone requires greater precision. I'd rather it pick up the precision based on the level of zoom currently applied. Libraries like ZedGraph and Dundas (which I believe MS is even using!) tend to pick good values that change as you zoom in and out.
Is there any way to have the intervals change precision as the zoom frame changes? It's probably some simple property I have set wrong, but it's hard to tell with the millions of properties this thing has (especially when there's about 14 places that represent the concept of Interval).
I had the exact same problem when zooming. I added code to format the axis labels and call it from the Paint handler. The Axis View objects have an IsZoomed property and have functions to get the current axis limits (GetViewMinimum/Maximum). I set the Axis LabelStyle.Format to "N" for all cases unless the Max-Min=range is less than 1. Then I set the format to "F#" where # is calculated based on the axis range.
# = Convert.ToInt32(Math.Abs(Math.Log10(range) - .5)) + 1;
Having played around with the chart control I haven't been able to find a simple solution to your problem. However the following may help:
Have you considered setting the maximum and minimum values for the axes yourself? If you round the actual maximum and minimum values to the nearest sensible "round" number (5, 10, 0.5, 0.01) this should make the calculated intervals a bit more friendly.
I understand this is not an ideal solution but by carefully choosing the maximum and/or minimum values you can ensure the intervals are "nicer" numbers. If the range of your axes is say divisible by 2, 5 & 10 it should result in fairly nice intervals.
Why not modify number format string.
Create format string
string formatString = "{0.00";
Identify zoom level, say zoomLevel = 2;
formatString = formatString.PadRight(5+zoomLevel, '0');
formatString += "}";
Now use this format on axis legend. Use string builder or some better way to modify the format string.
To provide the result with minimal cost you can use exponential scientific format
You can attach to customize event.
From there, you can modify the labels on x-axis:
var xAxisLabels = chart1.ChartAreas[0].AxisX.CustomLabels;
...
xAxisLabels[0].Text = ...
set min. and max. values:
chart1.ChartAreas[0].AxisX.Maximum = ...;
etc.
you can dynamically update the max and min based on your data set. each time user zooms in, you do a FOREACH on every point and get the stats and based on that set your max and min
It helps to set the IntervalOffset of the axis, here an example:
Private Sub chMap_AxisViewChanged(sender As System.Object, e As System.Windows.Forms.DataVisualization.Charting.ViewEventArgs) Handles chMap.AxisViewChanged
'the grid ticks are rounded values
e.Axis.IntervalOffset = -e.Axis.ScaleView.ViewMinimum
End Sub
I'm implementing a scatter plot using the MS Chart Control .NET 3.5, WinForms, C#. My x-axis data is DateTime and noticed I couldn't zoom in smaller than a resolution of 1 day, despite setting the ScaleView as follows:
chart1.ChartAreas["MyChart"].AxisX.ScaleView.MinSize = 4;
chart1.ChartAreas["MyChart"].AxisX.ScaleView.MinSizeType = DateTimeIntervalType.Hours;
Has anyone else had this issue? Any ideas?
Figured this out... perhaps I didn't RTFM close enough, but it wasn't obvious from the interactive demo.
Set
chart1.ChartAreas["MyChart"].CursorX.Interval = 0;
and then it allowed me to zoom along the x-axis just fine.
Works Great !
Very handy and mandatory if you want to have smooth Zooming behavior.
Didn't stumble upon it, though I did RTFM :-)
However, if you handle doubles or floats instead of integer based types (such as hours or days), setting the interval to Zero may be a little bit extreme : While zooming, you will end up having overly precise labels such as 2,907343253253235
A good combination is to use these two properties :
chartArea1.AxisY.ScaleView.MinSize = 0;
chartArea1.CursorY.Interval = 0.001;
this way you can zoom as much as you want, while still controlling precision at a reasonable level