The Christmas is coming and I got idea to send electricity card (little program). Something like dropping snow would be fine. But it is little bit boring something nice extra effects would be nice. Then I find this little flash example.
http://wonderfl.net/code/71344f9a655053d9f793a32c68f00921c67f1977
But I don’t have idea how to convert theses lines (47-49) to C#.
this._forceMap = new BitmapData(465, 465, false, 0x0);
this._forceMap.draw(tf, tf.transform.matrix);
this._forceMap.applyFilter(this._forceMap,
this._forceMap.rect,
new Point(0, 0),
new BlurFilter(8, 8));
If the value of autosize is "left" and the text field line type is set to Multiline in the text Property inspector, then the text field expands or contracts its right and bottom sides to fit all contained text.
tf.autoSize = TextFieldAutoSize.LEFT;
tf.text = 'Wonderfl!!';
tf.x = (465 - tf.width) / 2; // tf.width = textfield.width
tf.y = (465 - tf.height) / 2; // tf.height = textfield.height
x = paddingleft
y = paddingtop
Related
I am trying to vertically align text in ActiveReports 13. I am creating this report in code. The example I am trying to match is this:
However, after my efforts to do it, my result ends up looking like this:
The spacing seems to break at odd spots, even though the text in the data source is correct. The code I am using is:
for (int i = 0; i < dataTable.Columns.Count; i++)
{
ctl = new GrapeCity.ActiveReports.SectionReportModel.TextBox();
ctl.Name = columnName;
ctl.Text = dt.Columns[i].ColumnName;
ctl.Location = new PointF((0.3f * i) + 1.7f, 0.4f);
ctl.Size = new SizeF(0.3f, 1.0f);
ctl.VerticalText = true;
ctl.VerticalAlignment = GrapeCity.ActiveReports.Drawing.VerticalTextAlignment.Middle;
}
Increasing the width doesn't help. If I narrow the Size value and adjust the CharacterSpacings, the text spacing problem improves, but the background is narrowed and the text alignment shifts - the characters are rotated 90 degrees:
Any suggestions?
I found the way to solve this was to convert the TextBox to a Label, and then change the Angle property to 2700. Setting the Alignment to "Right" also aligned the text just how I wanted it:
ctl = new GrapeCity.ActiveReports.SectionReportModel.Label();
ctl.Angle = 2700;
ctl.Alignment = GrapeCity.ActiveReports.Drawing.TextAlignment.Right;
i got a Little "Problem", i want to create a Chart looking like this:
So basically
Series 1 = Normal bar Chart. Color green if it Ends before the "time max" (series2) Series 2 = just a DataPoint / Marker on top of series 1 items.
I am struggling with this though...
my Code:
chart_TimeChart.Series.Clear();
string series_timeneeded = "Time Needed";
chart_TimeChart.Series.Add(series_timeneeded);
chart_TimeChart.Series[series_timeneeded]["PixelPointWidth"] = "5";
chart_TimeChart.ChartAreas[0].AxisY.ScrollBar.Size = 10;
chart_TimeChart.ChartAreas[0].AxisY.ScrollBar.ButtonStyle = ScrollBarButtonStyles.SmallScroll;
chart_TimeChart.ChartAreas[0].AxisY.ScrollBar.IsPositionedInside = true;
chart_TimeChart.ChartAreas[0].AxisY.ScrollBar.Enabled = true;
chart_TimeChart.Series[series_timeneeded].BorderWidth = 2;
chart_TimeChart.Series[series_timeneeded].ChartType = SeriesChartType.StackedBar;
chart_TimeChart.Series[series_timeneeded].YValueType = ChartValueType.Time;
chart_TimeChart.ChartAreas[0].AxisY.LabelStyle.Format = "HH:mm:ss";
chart_TimeChart.Series[series_timeneeded].XValueType = ChartValueType.String;
for (int i = 0; i < MaxNumber; i++)
{
chart_TimeChart.Series[series_timeneeded].Points.AddXY("item"+ " " + (i + 1).ToString(), DateTime.Now.Add(Timespans[i]));
}
chart_TimeChart.Series.Add(series_FinishTime);
chart_TimeChart.Series[series_FinishTime].ChartType = SeriesChartType.StackedBar;
chart_TimeChart.Series[series_FinishTime].BorderWidth = 0;
chart_TimeChart.Series[series_FinishTime].MarkerSize = 15;
chart_TimeChart.Series[series_FinishTime].MarkerStyle = MarkerStyle.Square;
chart_TimeChart.Series[series_FinishTime].MarkerColor = Color.Black;
chart_TimeChart.Series[series_FinishTime].YValueType = ChartValueType.DateTime;
chart_TimeChart.Series[series_FinishTime].XValueType = ChartValueType.String;
for (int i = 0; i < MaxNumber; i++)
{
DateTime YPosition = GetFinishTime(i);
chart_TimeChart.Series[series_FinishTime].Points.AddXY("item"+ " " +(i+1).ToString(), YPosition);
}
but this only Displays the 2nd series on top of the first one but the first one isnt visible anymore. The Maker of series 2 isnt shown but instead the bar is (eventhough i made borderwidth to 0). In my opinion/thinking i just have to make the "bar" of series 2 invisible and just Show the marker Points for series 2.
Any ideas?
Update:
string seriesname = Name+ i.ToString();
chart_TimeChart.Series.Add(seriesname);
chart_TimeChart.Series[seriesname].SetCustomProperty("DrawSideBySide", "false");
chart_TimeChart.Series[seriesname].SetCustomProperty("StackedGroupName", seriesname);
chart_TimeChart.Series[seriesname].ChartType = SeriesChartType.StackedBar; //Y and X are exchanged
chart_TimeChart.Series[seriesname].YValueType = ChartValueType.Time;
chart_TimeChart.ChartAreas[0].AxisY.LabelStyle.Format = "HH:mm:ss";
chart_TimeChart.Series[seriesname].XValueType = ChartValueType.String;
DateTime TimeNeeded = DateTime.Now.Add(List_AllLiniengroupsTimespans[k][i]);
DateTime TimeMax = GetFinishTime(k, i);
TimeSpan TimeDifference = TimeNeeded - TimeMax;
if (TimeNeeded > TimeMax) //All good
{
chart_TimeChart.Series[seriesname].Points.AddXY(seriesname, TimeNeeded); //Time till finish
chart_TimeChart.Series[seriesname].Points[0].Color = Color.Blue;
chart_TimeChart.Series[seriesname].Points[0].SetCustomProperty("StackedGroupName", seriesname);
chart_TimeChart.Series[seriesname].Points.AddXY(seriesname, TimeNeeded.Add(TimeDifference)); //time left
chart_TimeChart.Series[seriesname].Points[1].Color = Color.Red;
chart_TimeChart.Series[seriesname].Points[1].SetCustomProperty("StackedGroupName", seriesname);
}
else if (TimeMax > TimeNeeded) //wont make it in time
{
chart_TimeChart.Series[seriesname].Points.AddXY(seriesname, TimeNeeded); //time till still okay
chart_TimeChart.Series[seriesname].Points[0].Color = Color.Blue;
chart_TimeChart.Series[seriesname].Points[0].SetCustomProperty("StackedGroupName", seriesname);
chart_TimeChart.Series[seriesname].Points.AddXY(seriesname, TimeNeeded.Add(TimeDifference)); //Time that is too much
chart_TimeChart.Series[seriesname].Points[1].Color = Color.Green;
chart_TimeChart.Series[seriesname].Points[1].SetCustomProperty("StackedGroupName", seriesname);
}
else if (TimeMax == TimeNeeded) //fits exactly
{
chart_TimeChart.Series[seriesname].Points.AddXY(seriesname, TimeNeeded);
chart_TimeChart.Series[seriesname].Points[0].Color = Color.DarkOrange;
chart_TimeChart.Series[seriesname].Points[0].SetCustomProperty("StackedGroupName", seriesname);
}
the Code will be displayed as:
but i want it to look like this:
!! See the update below !!
If you really want to create a StackedBar chart, your chart has two issues:
If you want to stack datapoints they need to have meaningful x-values; without them how can it know what to stack on each other?
You add strings, which look fine but simply don't work. That is because the DataPoint.XValue field is double and when you add string into it it is set to 0 !! Your string is copied to the Label but otherwise lost.
So you need to come up with a suitable numeric value you use for the x-values..
And you also need to group the series you want to stack. For this there is a special property called StackedGroupName which serves to group those series that shall be stacked.
Here is how you can use it:
yourSeries1.SetCustomProperty("StackedGroupName", "Group1");
For a full example see this post !
It also shows one way of setting the Labels with string values of your choice..
This is the way to go for real StackedBar charts. Your workaround may or may not work. You could try to make the colors transparent or equal to the chart's backcolor; but it won't be more than a hack, imo.
Update
I guess I have misread the question. From what I see you do not really want to create a stacked chart.
Instead you struggle with these issues:
displaying bars at the same y-spot
making some bars invisible
displaying a vertical line as a marker
Let's tackle each:
Some column types including all Bars, Columns and then some have a little known special property called DrawSideBySide.
By default is is set to Auto, which will work like True. This is usually fine as we don't want bars to sit upon each other, effectively hiding all or part of the overlaid points.
But here we do want them to share the same y-position, so we need to set the property to false for at least one Series; the others (on Auto) will follow..:
You can do it either like this:
aSeries["DrawSideBySide"] = "false";
or like this:
aSeries.SetCustomProperty("DrawSideBySide", "false");
Next we hide the overlaid Series; this is simple:
aSeries.Color = Color.Transparent;
The last issue is displaying a line marker. There is no such MarkerStyle, so we need to use a custom style. For this we need to create a suitable bitmap and add it as a NamedImage to the chart's Images collection.
This sounds more complicated than it is; however the MarkerImage will not be scaled, so we need to created suitable sizes whenever we resize the Chart or add/remove points. I will ignore this complication for now..
int pointCount = 10;
Bitmap bmp = new Bitmap(2, chart.ClientSize.Height / pointCount - 5);
using (Graphics g = Graphics.FromImage(bmp)) g.Clear(Color.Black);
NamedImage marker = new NamedImage("marker", bmp);
chart.Images.Clear(); // quick & dirty
chart.Images.Add(marker);
Here is the result:
A few notes:
I would recommend to use variables for all chart elements you refer to repeatedly instead of using indexed references all the time. Less code, easier to read, a lot easier to maintain, and probably better performance.
Since your code called for the visible datapoints to be either red or green the Legend will not show a good representation. See here for an example of drawing a multi-colored legend item..
I used the chart height; this is not really recommended as there may be Titles or Legends or even more ChartAreas; instead you should use the height of the ChartArea, or even more precise, the height of the InnerPlotPosition. You would need to convert those from percentages to pixels. Not too hard, see below or see here
or here for more examples!
The markers should be adapted from the Resize and probably from the AxisViewChanged events. Putting it in a nice function to call (e.g. void setMarkerImage(Chart chart, Series s, string name, int width, Color c)) is always a good idea.
If you need to adapt the size of the marker image repeatedly, you may want to write better code for clearing the old one; this should include disposing of the Bitmap that was used before..
Here is an example:
var oldni = chart.Images.FindByName("marker");
if (oldni != null)
{
oldni.Image.Dispose();
chart.Images.Remove(oldni);
oldni.Dispose();
}
In some situations one needs to nudge the Chart to update some of its properties; RecalculateAxesScale is one such nudge.
Example for calculating a suitable marker height:
ChartArea ca = chart.ChartAreas[0];
ca.RecalculateAxesScale();
float cah = ca.Position.Height;
float iph = ca.InnerPlotPosition.Height;
float h = chart3.ClientSize.Height * cah / 100f * iph / 100f;
int mh = (int)(h / s.Points.Count);
Final note: The original answer stressed the importance of using meaningful x-values. Strings are useless! This was important for stacking bars; but it is equally important now, when we want bars to sit at the same vertical positions! Adding the x-values as strings is again resulting in nonsense..
(Since we have Bars the x-values go along the vertical axis and vice versa..)
So I use an open source .NET library for plotting: FPlot
Here's the function that I'm trying to draw:
f(x,y) = x^2+3*y^2+2*x*y
Here's what I want it to look like:
Clarification:
I don't need the exact same appearence as in the image, I just need the plot to be mathematically correct
There are only 10 conours in the picture, I need as much as can be fit on the screen
Here's how I tried to do this:
var graphFunction = new Function2D();
graphFunction.source = "return (pow(x,2)+3*pow(y,2)+2*x*y)/10;";
/* I'm dividing by 10 because otherwise the whole plot is solid color */
graphFunction.Compile(true);
That's how the FPlot generated plot looks up close:
This is exactly what I want, but when I zoom out here's what happens:
Theese extra ellipses are not supposed to be there, in fact they are not there, this is just a graphical artefact, because when you zoom into one of theese 'fake' ellipses this is what you see:
The problem can be in this line:
graphFunction.source = "return (pow(x,2)+3*pow(y,2)+2*x*y)/10;";
...or in the FPlot source code. Any Ideas?
UPDATE:
So, z value in graph seems to be the problem. When value of a function, z = f(x,y) in a graph exceeds the z1 (max z) value it resets to z = z%z1 (same happens when z is lower then z0), which causes these "lines" - they are not countour lines, like I thought.
So that means the solution is: set z0 to min f(x,y) on screen, and set z1 to max f(x,y) on screen.
Make the displaying borders of your FPlotLibrary.GraphControl have the same value in all 3 dimensions and the problem goes away:
graphControl1.x0 = -40;
graphControl1.x1 = 40;
graphControl1.y0 = -40;
graphControl1.y1 = 40;
graphControl1.z0 = -40;
graphControl1.z1 = 40;
Btw, the "problem" reproduces, for instance, if you do
graphControl1.x0 = -40;
graphControl1.x1 = 40;
graphControl1.y0 = -40;
graphControl1.y1 = 40;
graphControl1.z0 = -1;
graphControl1.z1 = 1;
I am trying to control the value labels for my zedgraph's x-axis. Before, the labels would "fly around" and not really stay put on the axis. They might move left or right on the axis and pop in and out of existence based on the data. Like in the picture below
I first tried to draw the labels myself when I finally found good documentation for the zedgraph library. There I found the [AXIS].Scale options of MajorStep MinorStep and BaseTic. Which if set correctly should cause the labels to stay in place and just change value as the data is added.
The issue I am running into though is that my x-axis scale is in XDate units. Which means I cannot do the simple math I was hoping to. So I have since figured a way that I think I can find the values I need using TimeSpan and DateTime. Below curMaxX and curMinX are XDate values of the current minimum and maximum x-axis values (curMinX should basically be DateTime.Now because this data is realtime)
// Setup
TimeSpan scaleDist = curMaxX.DateTime.Subtract(curMinX.DateTime);
TimeSpan major = new TimeSpan(scaleDist.Ticks / 5);
TimeSpan minor = new TimeSpan(major.Ticks / 5);
TimeSpan baseT = new TimeSpan(curMinX.DateTime.Ticks + major.Ticks);
// Setting the values
myPane.XAxis.Scale.MajorStep = new XDate(new DateTime(major.Ticks));
myPane.XAxis.Scale.MinorStep = new XDate(new DateTime(minor.Ticks));
myPane.XAxis.Scale.BaseTic = new XDate(new DateTime(baseT.Ticks));
// Print statement of the values
SDist: 00:00:10
Major: 00:00:02
Minor: 00:00:00.4000000
BaseT: 735382.07:32:34
BaseTAsDateTime: 5/30/2014 7:32:34 AM
CurMinX: 5/30/2014 7:32:32 AM
Though setting the values as such still does not achieve what I want. With this code my x-axis comes out looking like so
It is somewhat closer to what I am looking for but still off. Only a single major tic is shown, and no minor tics. I am not sure what other ways there might be to specify the values.
For the major and minor step documentation it says
For Date axes, this value is defined in units of Major/MinorUnit.
Which my MajorUnit is minutes and the MinorUnit is seconds, but I pass them a XDate value which specifies both minutes and seconds. Also, setting the values as fractions of a whole (so if I want MajorStep to be 2 seconds I'd set it as (2/60)), causes nothing to show up.
Any ideas/suggestions?
Well, I determined that it was a waste of time to try and use the default zedgraph tics, steps, etc. So I made my own method to do so based on the data currently on the graph.
After I posted this I realized trying to figure out the tics was a lost cause so I looked for other ways to do it. I was going to add text beside each point showing its values, but it became very cluttered, then I realized I can just draw the text at the bottom of the graph which is what I wanted all along. I also added a little label on the right showing the current value.
A little bit o code
private void setPointLabels()
{
// All hail the almighty pane.
GraphPane myPane = theGraph.GraphPane;
// Give us some room to draw labels
myPane.Margin.Right = 50;
myPane.Margin.Bottom = 20;
// Dont show the default stuff
myPane.XAxis.Scale.IsVisible = false;
myPane.XAxis.MajorTic.IsAllTics = false;
myPane.XAxis.MinorTic.IsAllTics = false;
// Remove the old labels
myPane.GraphObjList.Clear();
// Get the curve showing our data
LineItem myCurve = (LineItem)myPane.CurveList[0];
// Show a voltage value on the far right
PointPair pt = myCurve.Points[myCurve.Points.Count - 1];
TextObj text = new TextObj(" " + pt.Y.ToString("f2"), pt.X, pt.Y, CoordType.AxisXYScale, AlignH.Left, AlignV.Center);
text.ZOrder = ZOrder.A_InFront;
text.FontSpec.Border.IsVisible = false;
text.FontSpec.Fill.IsVisible = false;
myPane.GraphObjList.Add(text);
// Determine a hardcoded yOffset for the labels
double yOffset = -1.2;
// Determine if we need to fix the center label
int fixVal = 1;
if (xScaleSec == 10)
fixVal = 0;
// Loop over each point in the curve
for (int i = 0; i < myCurve.Points.Count; i++)
{
if (i == 0 ||
i == (myCurve.Points.Count/4) ||
i == ((myCurve.Points.Count/2)-fixVal) ||
i == ((3*myCurve.Points.Count)/4) ||
i == myCurve.Points.Count-1)
{
PointPair aPt = myCurve.Points[i];
// Add a text object just below the x-axis showing the point's x-value
XDate xVal = new XDate(aPt.X);
TextObj label = new TextObj(xVal.ToString("hh:mm.ss"), aPt.X, myPane.YAxis.Scale.Min + yOffset, CoordType.AxisXYScale, AlignH.Center, AlignV.Center);
label.ZOrder = ZOrder.A_InFront;
label.FontSpec.Fill.IsVisible = false;
label.FontSpec.Border.IsVisible = false;
myPane.GraphObjList.Add(label);
// Add a line object on the x-axis representing a tic mark
LineObj aTic = new LineObj(aPt.X, myPane.YAxis.Scale.Min - (yOffset / 4), aPt.X, myPane.YAxis.Scale.Min + (yOffset / 4));
myPane.GraphObjList.Add(aTic);
}
}
}
I'm building a chart to show items by volume by category. So far I've been succcessful in showing items by volume as it's a simple x/y chart, however I'd like to show y2 and I know MS Chart Controls has a built in AxisY2 however when I try anything with it the Chart get's all funky.
Here's what I'm looking for (in ascii art):
item1 |[][][][][].............| cat1
item2 |[][]...................| cat2
item3 |[][....................| cat1
item4 |[][][][][][][][........| cat1
|_______________________|
0 1 2 3 4 5
Like previously mentioned I can get Items and counts to show fine as that's relatively easy, it's the Categories that I can't seem to place.
Thanks
Here's what did it for me- after I created the chart I added the following lines:
chrtMain.Series[0].YAxisType = AxisType.Primary;
chrtMain.Series[1].YAxisType = AxisType.Secondary;
chrtMain.ChartAreas[0].AxisY2.LineColor = Color.Transparent;
chrtMain.ChartAreas[0].AxisY2.MajorGrid.Enabled = false;
chrtMain.ChartAreas[0].AxisY2.Enabled = AxisEnabled.True;
chrtMain.ChartAreas[0].AxisY2.IsStartedFromZero = chrtMain.ChartAreas[0].AxisY.IsStartedFromZero;
There was no need to superimpose two charts or anything!
It gets even better:
For using the second Y axis, there is no need for a second chart area. You can decide per serie which axis you want to use with the Series.YAxisType property.
Take a look at the documentation on http://msdn.microsoft.com/en-us/library/dd489216.aspx
Martijn
Short Answer first : According to MS Examples, there is no straight way to do that, but just a workaround trick : Plot your series on a second chartArea matching exactly your existing area position, (by performing a copy of your Series) having invisible primary X/Y Axis and a visible secondary Y Axis (AxisY2). And set the chartArea and the copied series's backcolors to transparent. (This can be applied to secondary X axis in case of column graphs rather that bars)
//Suppose you already have a ChartArea with the series plotted and the left Y Axis
//Add a fake Area where the only appearent thing is your secondary Y Axis
ChartArea area1 = chart.ChartAreas.Add("ChartAreaCopy_" + series.Name);
area1.BackColor = Color.Transparent;
area1.BorderColor = Color.Transparent;
area1.Position.FromRectangleF(area.Position.ToRectangleF());
area1.InnerPlotPosition.FromRectangleF(area.InnerPlotPosition.ToRectangleF());
area1.AxisX.MajorGrid.Enabled = false;
area1.AxisX.MajorTickMark.Enabled = false;
area1.AxisX.LabelStyle.Enabled = false;
area1.AxisY.MajorGrid.Enabled = false;
area1.AxisY.MajorTickMark.Enabled = false;
area1.AxisY.LabelStyle.Enabled = false;
area1.AxisY2.Enabled = AxisEnabled.True;
area1.AxisY2.LabelStyle.Enabled = true;
// Create a copy of specified series, and change Y Values to categories
Series seriesCopy = chart.Series.Add(series.Name + "_Copy");
seriesCopy.ChartType = series.ChartType;
foreach(DataPoint point in series.Points)
{
double category = getYourItemCategory(point.XValue);
seriesCopy.Points.AddXY(point.XValue, category);
}
// Hide copied series
seriesCopy.IsVisibleInLegend = false;
seriesCopy.Color = Color.Transparent;
seriesCopy.BorderColor = Color.Transparent;
//Drop it in the chart to make the area show (only the AxisY2 should appear)
seriesCopy.ChartArea = area1.Name;
PS : I've spent two nights awake messing with MS chart controls, trying to put two different Y axis on a Chart Area. I wanted to put two differently scaled series (same X scale, different Y Scales : one on the left for Series A , the other on the right for Series B).
In fact, this proved to be a real nightmare, when one could expect this to be pretty straightforward. The truth is that MS Chart Controls are definitely NOT adapted for this particular use case IMHO. The multiple Y axis sample suggested in the MSCC sample examples is an awful and very ugly workaround, which requires two chartareas on top of the default one, playing with visibility and transparency, to achieve the desired effect (which sounds like a very bad illusion magic trick).
While hoping for this to be enriched and fixed in a proper way in future versions, if you really need an efficient way to manage multiple Y-Axis, sitck to ZedGraph
You can add as many series on the Y axis as you want, below code is an extract from a chart I use that has more than 2 secondary y axes, code is for vb.net but i'm sure you can work it out:
ChartKPI.Series.Clear()
ChartKPI.Series.Add("Series1")
ChartKPI.Series("Series1").XValueMember = "Date"
ChartKPI.Series("Series1").YValueMembers = "HSDPA_Vol_MBy"
ChartKPI.Series("Series1").Name = "HSDPA_Vol_MBy"
ChartKPI.Series("HSDPA_Vol_MBy").ChartType = SeriesChartType.Column
ChartKPI.Series("HSDPA_Vol_MBy").ToolTip = "HSDPA MBytes: #VAL"
ChartKPI.Series.Add("Series2")
ChartKPI.Series("Series2").YAxisType = AxisType.Secondary
ChartKPI.Series("Series2").XValueMember = "Date"
ChartKPI.Series("Series2").YValueMembers = "cs_voice_traffic"
ChartKPI.Series("Series2").Name = "cs_voice_traffic"
ChartKPI.Series("cs_voice_traffic").ChartType = SeriesChartType.Line
ChartKPI.Series("cs_voice_traffic").BorderWidth = 3
ChartKPI.Series("cs_voice_traffic").ToolTip = "CS Voice Traffic: #VAL"
ChartKPI.Series.Add("Series3")
ChartKPI.Series("Series3").YAxisType = AxisType.Secondary
ChartKPI.Series("Series3").XValueMember = "Date"
ChartKPI.Series("Series3").YValueMembers = "cs_conv_traffic"
ChartKPI.Series("Series3").Name = "cs_conv_traffic"
ChartKPI.Series("cs_conv_traffic").ChartType = SeriesChartType.Line
ChartKPI.Series("cs_conv_traffic").BorderWidth = 3
ChartKPI.Series("cs_conv_traffic").ToolTip = "CS Conv Traffic: #VAL"
ChartKPI.Series.Add("Series4")
ChartKPI.Series("Series4").YAxisType = AxisType.Secondary
ChartKPI.Series("Series4").XValueMember = "Date"
ChartKPI.Series("Series4").YValueMembers = "ps_backg_traffic_ul"
ChartKPI.Series("Series4").Name = "ps_backg_traffic_ul"
ChartKPI.Series("ps_backg_traffic_ul").ChartType = SeriesChartType.Line
ChartKPI.Series("ps_backg_traffic_ul").BorderWidth = 3
ChartKPI.Series("ps_backg_traffic_ul").ToolTip = "PS Backg Traffic UL: #VAL"
ChartKPI.Series.Add("Series5")
ChartKPI.Series("Series5").YAxisType = AxisType.Secondary
ChartKPI.Series("Series5").XValueMember = "Date"
ChartKPI.Series("Series5").YValueMembers = "ps_backg_traffic_dl"
ChartKPI.Series("Series5").Name = "ps_backg_traffic_dl"
ChartKPI.Series("ps_backg_traffic_dl").ChartType = SeriesChartType.Line
ChartKPI.Series("ps_backg_traffic_dl").BorderWidth = 3
ChartKPI.Series("ps_backg_traffic_dl").ToolTip = "PS Backg Traffic DL: #VAL"
ChartKPI.ChartAreas("ChartArea1").AxisX.Title = "HSDPA Traffic (MB)"
ChartKPI.ChartAreas("ChartArea1").AxisX.MajorGrid.Interval = 1
ChartKPI.ChartAreas("ChartArea1").AxisX.LabelStyle.Interval = 1
ChartKPI.ChartAreas("ChartArea1").AxisY.Title = "RRC Attempts"
ChartKPI.ChartAreas("ChartArea1").AxisY2.Title = "R99 Traffic (Erlang)"
ChartKPI.DataBind()
Solution:
chart1.ChartAreas[1].AlignWithChartArea = chart1.ChartAreas[0].Name;
chart1.ChartAreas[1].AlignmentOrientation = AreaAlignmentOrientations.All;