I am trying to create a chart like this:
I am almost there but I am having issues with the columns not spreading over their respective ranges instead they are concentrated over the first range of my chart. How to resolve this?
I tried:
Extracts from aspx:
<asp:Chart ID="Chart2" runat="server" BackColor="DarkSlateBlue" BackGradientStyle="LeftRight"
BorderlineWidth="0" Height="440px" Palette="SeaGreen" PaletteCustomColors="24, 0, 0"
Width="560px" BorderlineColor="128, 128, 255" OnLoad="Chart2_Load">
<Titles>
<asp:Title Name="DefaultTitle" Font="Trebuchet MS, 15pt, style=Bold"
Text = "Students per Total Score Achieved" />
</Titles>
<%-- <Legends>
<asp:Legend Name="DefaultLegend" Enabled="True" Docking="Top" />
</Legends>--%>
<Series>
<asp:Series Name="Series1" IsValueShownAsLabel="true" YValuesPerPoint="1"></asp:Series>
</Series>
<ChartAreas>
<asp:ChartArea Name="ChartArea1" >
<AxisY Title="No of Students " Interval="5"></AxisY>
<AxisX Title="Score Achieved" Minimum="0" IntervalAutoMode="FixedCount" Interval="100" IntervalType="Number">
<LabelStyle Angle="-90" Interval="10" IntervalType="Number" />
</AxisX>
</asp:ChartArea>
</ChartAreas>
</asp:Chart>
Extracts from code-behind:
protected void DropDown_Subjects_SelectedIndexChanged(object sender, EventArgs e)
{
Chart2.Visible = true;
SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["Con"].ConnectionString);
SqlCommand cmd = new SqlCommand();
cmd.Connection = connection;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "sp_range";
cmd.Parameters.AddWithValue("@sub_code", DropDown_Subjects.SelectedItem.Value);
// cmd.ExecuteNonQuery();
connection.Open();
SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
Chart2.DataSource = dr;
Chart2.Series[0].XValueMember = "Score_Acheived";
Chart2.Series[0].YValueMembers = "No_of_Students";
Chart2.DataBind();
connection.Close();
}
protected void Chart2_Load(object sender, EventArgs e)
{
}
And my chart looks like:
Please see below your original ASPX modified to fit your desired result. Basically you need to make your major grid interval be the same as your score range and make each XValue
be the midpoint of each range. Also, in order to make your columns completely fill the gap you have to set custom property PointWidth=1
.
ASPX:
<asp:Chart ID="Chart2" runat="server" BackColor="DarkSlateBlue" BackGradientStyle="LeftRight"
BorderlineWidth="0" Height="440px" Palette="SeaGreen" PaletteCustomColors="24, 0, 0"
Width="560px" BorderlineColor="128, 128, 255" OnLoad="Chart2_Load">
<Titles>
<asp:Title Name="DefaultTitle" Font="Trebuchet MS, 15pt, style=Bold"
Text = "Students per Total Score Achieved" />
</Titles>
<%-- <Legends>
<asp:Legend Name="DefaultLegend" Enabled="True" Docking="Top" />
</Legends>--%>
<Series>
<asp:Series Name="Series1" YValuesPerPoint="1" CustomProperties="PointWidth=1">
<Points>
<asp:DataPoint Color="GreenYellow" XValue="15" YValues="25" />
<asp:DataPoint Color="255, 255, 128" XValue="25" YValues="15" />
<asp:DataPoint Color="0, 192, 192" XValue="35" YValues="10" />
<asp:DataPoint Color="Khaki" XValue="45" YValues="35" />
</Points>
</asp:Series>
</Series>
<ChartAreas>
<asp:ChartArea Name="ChartArea1" >
<AxisY Title="No of Students ">
<MajorGrid LineColor="DarkGray" LineDashStyle="Dot" />
</AxisY>
<AxisX Title="Score Achieved" Minimum="0" Enabled="True">
<MajorGrid Interval="10" IntervalOffset="Auto" IntervalOffsetType="Number" IntervalType="Number" LineColor="DarkGray" LineDashStyle="Dot" />
<MajorTickMark Interval="10" IntervalOffset="Auto" IntervalOffsetType="Number" IntervalType="Number" />
</AxisX>
<AxisY2>
<LabelStyle TruncatedLabels="True" />
</AxisY2>
</asp:ChartArea>
</ChartAreas>
</asp:Chart>
EDIT: Note that the color for each point is being explicitly assigned in the aspx file. You can do the same thing in code-behind by using pre-defined colors from a collection or generate random colors, like this:
Random r = new Random();
foreach (DataPoint dp in Chart2.Series[0].Points)
dp.Color = Color.FromArgb(255, r.Next(100, 255), r.Next(100, 255), r.Next(100, 255));
EDIT 2: This is exactly what my code looks like now:
ASPX:
<asp:Chart ID="Chart2" runat="server" BackColor="DarkSlateBlue" BackGradientStyle="LeftRight"
BorderlineWidth="0" Height="440px" Palette="SeaGreen" PaletteCustomColors="24, 0, 0"
Width="560px" BorderlineColor="128, 128, 255" OnLoad="Chart2_Load">
<Titles>
<asp:Title Name="DefaultTitle" Font="Trebuchet MS, 15pt, style=Bold"
Text = "Students per Total Score Achieved" />
</Titles>
<%-- <Legends>
<asp:Legend Name="DefaultLegend" Enabled="True" Docking="Top" />
</Legends>--%>
<Series>
<asp:Series Name="Series1" YValuesPerPoint="1" CustomProperties="PointWidth=1">
</asp:Series>
</Series>
<ChartAreas>
<asp:ChartArea Name="ChartArea1" >
<AxisY Title="No of Students ">
<MajorGrid LineColor="DarkGray" LineDashStyle="Dot" />
</AxisY>
<AxisX Title="Score Achieved" Minimum="0" Enabled="True">
<MajorGrid Interval="10" IntervalOffset="Auto" IntervalOffsetType="Number" IntervalType="Number" LineColor="DarkGray" LineDashStyle="Dot" />
<MajorTickMark Interval="10" IntervalOffset="Auto" IntervalOffsetType="Number" IntervalType="Number" />
</AxisX>
<AxisY2>
<LabelStyle TruncatedLabels="True" />
</AxisY2>
</asp:ChartArea>
</ChartAreas>
</asp:Chart>
CS:
protected void Chart2_Load(object sender, EventArgs e)
{
Chart2.Visible = true;
/*
SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["Con"].ConnectionString);
SqlCommand cmd = new SqlCommand();
cmd.Connection = connection;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "sp_range";
cmd.Parameters.AddWithValue("@sub_code", DropDown_Subjects.SelectedItem.Value);
// cmd.ExecuteNonQuery();
connection.Open();
SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
*/
Chart2.DataSource = dt;
Chart2.Series[0].XValueMember = "Score_Achieved";
Chart2.Series[0].YValueMembers = "No_of_Students";
Chart2.DataBind();
Random r = new Random();
foreach (DataPoint dp in Chart2.Series[0].Points)
dp.Color = Color.FromArgb(255, r.Next(100, 255), r.Next(100, 255), r.Next(100, 255));
//connection.Close();
}