MS 图表数据值标签
MS Chart Data Value Labels
我正在 MVC 中使用 C# 通过 MS-Chart 构建一个 "Stacked Column" 图表。我的图表有 3 个系列。我试图让每个系列的数据值标签显示在 X 轴下方,而不是显示在每一列上。
我一直在网上搜索,希望能找到一些指向这种类似布局的指针,但 none 已经找到了 2 天。
有人可以指点一下如何完成数据值标签排列的相同位置吗?
这是最简单的解决方案。它的样式不是很好,但只需要几行:
var months = new[] { "Jan", "Feb", "Mar", "Apr", "May",
"Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
for (int i = 0; i < pointCount; i++)
{
double sum = 0;
string label = "";
for (int j = seriesCount - 1; j >= 0; j--)
{
sum += chart.Series[j].Points[i].YValues[0];
label += "\n" + +chart.Series[j].Points[i].YValues[0] ;
}
chart.Series[0].Points[i].AxisLabel = months[i] + "\n" + sum + label;
}
这会为第一个 Series
的每个 DataPoint
添加一个标签字符串。请注意,每个点只能显示一个这样的标签;稍后 Series
的标签将被忽略。
为标签的月份部分使用合适的计数器和任何你想要的东西。
要获得更好的外观,例如粗体字或彩色背景,您需要做更多的工作。
请注意,标签中的数字和系列中的数字是反向堆叠的,因此内部循环是向后的。
这适用于任意数量的系列。
这是使用 PostPaint
事件的变体:
private void chart1_PostPaint(object sender, ChartPaintEventArgs e)
{
if (chart1.Series[0].Points.Count <= 0) return;
Graphics g = e.ChartGraphics.Graphics;
ChartArea ca = chart1.ChartAreas[0];
Rectangle rip = Rectangle.Round(InnerPlotPositionClientRectangle(chart1, ca));
StringFormat fmt = new StringFormat()
{ Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center };
int cols = chart1.Series[0].Points.Count;
int sCount = chart1.Series.Count;
int w = rip.Width / (cols + 1); // there is ca. 1/2 column gap to the sides
for (int i = 0; i < cols; i++)
{
List<string> s = (List<string>)(chart1.Series[0].Points[i].Tag);
for (int j = 0; j < s.Count; j++)
{
// change magic numbers with your font!
Rectangle r = new Rectangle(rip.Left + i * w + w / 2,
rip.Bottom + 5 + 25 * j, w, 25);
// 1st row: header, 2nd row sum, rest moved up by and reversed
using (SolidBrush brush = new SolidBrush(j == 0 ? Color.Transparent
: j == 1 ? Color.Gray : chart1.Series[sCount + 1 - j].Color))
g.FillRectangle(brush, r);
g.DrawRectangle(Pens.White, r);
g.DrawString(s[j], ca.AxisX.LabelStyle.Font, Brushes.White, r, fmt);
}
}
}
它使用相同的例程来收集标签字符串,但不是设置 AxisLabels
,而是将它们添加到 DataPoints
:
的 Tags
string l = months[i] + "\n" + sum + label;
chart.Series[0].Points[i].Tag = l.Split('\n').ToList();
图表样式几乎占据了大部分代码:
chart.BackColor = Color.DarkSlateGray;
ChartArea ca = chart.ChartAreas[0];
chart.Legends[0].Alignment = StringAlignment.Center;
chart.Legends[0].Docking = Docking.Top;
chart.Legends[0].BackColor = chart.BackColor;
chart.Legends[0].ForeColor = Color.White;
Legend L = chart.Legends[0];
L.CustomItems.Add(Color.Silver, "Sum");
ca.BackColor = Color.LightSteelBlue;
ca.Position = new ElementPosition(2, 8, 93, 70); // make room
ca.Area3DStyle.Enable3D = true;
ca.Area3DStyle.PointDepth = 25;
ca.Area3DStyle.WallWidth = 0;
ca.AxisX.MajorGrid.Enabled = false;
ca.AxisY.MajorGrid.LineColor = Color.White;
ca.AxisY.LineColor = Color.White;
ca.AxisY.LabelStyle.ForeColor = Color.White;
ca.AxisY.MajorTickMark.LineColor = Color.White;
ca.AxisX.LabelStyle.Enabled = false;
ca.AxisX.LineColor = Color.White;
ca.AxisX.MajorTickMark.Enabled = false;
使用 Colors
创建 Series
后,您需要应用它们,以便可以在代码中访问它们:
chart1.ApplyPaletteColors();
Series
的漂亮圆角列是由 CustomProperty
创建的
s.SetCustomProperty("DrawingStyle", "Cylinder");
更多细节:
chart.Series[1].Color = Color.Crimson;
chart.Series[0].LegendText = "Hobbits";
..
更新:您需要包含我的其他一些帖子中的两个函数 InnerPlotPositionClientRectangle
和 ChartAreaClientRectangle
,例如 here or here!
为了做到这一点 work in ASP 你在 PageLoad
:
中连接事件
chart1.PostPaint += new EventHandler<ChartPaintEventArgs>(chart1_PostPaint);
我正在 MVC 中使用 C# 通过 MS-Chart 构建一个 "Stacked Column" 图表。我的图表有 3 个系列。我试图让每个系列的数据值标签显示在 X 轴下方,而不是显示在每一列上。
我一直在网上搜索,希望能找到一些指向这种类似布局的指针,但 none 已经找到了 2 天。
有人可以指点一下如何完成数据值标签排列的相同位置吗?
这是最简单的解决方案。它的样式不是很好,但只需要几行:
var months = new[] { "Jan", "Feb", "Mar", "Apr", "May",
"Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
for (int i = 0; i < pointCount; i++)
{
double sum = 0;
string label = "";
for (int j = seriesCount - 1; j >= 0; j--)
{
sum += chart.Series[j].Points[i].YValues[0];
label += "\n" + +chart.Series[j].Points[i].YValues[0] ;
}
chart.Series[0].Points[i].AxisLabel = months[i] + "\n" + sum + label;
}
这会为第一个 Series
的每个 DataPoint
添加一个标签字符串。请注意,每个点只能显示一个这样的标签;稍后 Series
的标签将被忽略。
为标签的月份部分使用合适的计数器和任何你想要的东西。
要获得更好的外观,例如粗体字或彩色背景,您需要做更多的工作。
请注意,标签中的数字和系列中的数字是反向堆叠的,因此内部循环是向后的。
这适用于任意数量的系列。
这是使用 PostPaint
事件的变体:
private void chart1_PostPaint(object sender, ChartPaintEventArgs e)
{
if (chart1.Series[0].Points.Count <= 0) return;
Graphics g = e.ChartGraphics.Graphics;
ChartArea ca = chart1.ChartAreas[0];
Rectangle rip = Rectangle.Round(InnerPlotPositionClientRectangle(chart1, ca));
StringFormat fmt = new StringFormat()
{ Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center };
int cols = chart1.Series[0].Points.Count;
int sCount = chart1.Series.Count;
int w = rip.Width / (cols + 1); // there is ca. 1/2 column gap to the sides
for (int i = 0; i < cols; i++)
{
List<string> s = (List<string>)(chart1.Series[0].Points[i].Tag);
for (int j = 0; j < s.Count; j++)
{
// change magic numbers with your font!
Rectangle r = new Rectangle(rip.Left + i * w + w / 2,
rip.Bottom + 5 + 25 * j, w, 25);
// 1st row: header, 2nd row sum, rest moved up by and reversed
using (SolidBrush brush = new SolidBrush(j == 0 ? Color.Transparent
: j == 1 ? Color.Gray : chart1.Series[sCount + 1 - j].Color))
g.FillRectangle(brush, r);
g.DrawRectangle(Pens.White, r);
g.DrawString(s[j], ca.AxisX.LabelStyle.Font, Brushes.White, r, fmt);
}
}
}
它使用相同的例程来收集标签字符串,但不是设置 AxisLabels
,而是将它们添加到 DataPoints
:
Tags
string l = months[i] + "\n" + sum + label;
chart.Series[0].Points[i].Tag = l.Split('\n').ToList();
图表样式几乎占据了大部分代码:
chart.BackColor = Color.DarkSlateGray;
ChartArea ca = chart.ChartAreas[0];
chart.Legends[0].Alignment = StringAlignment.Center;
chart.Legends[0].Docking = Docking.Top;
chart.Legends[0].BackColor = chart.BackColor;
chart.Legends[0].ForeColor = Color.White;
Legend L = chart.Legends[0];
L.CustomItems.Add(Color.Silver, "Sum");
ca.BackColor = Color.LightSteelBlue;
ca.Position = new ElementPosition(2, 8, 93, 70); // make room
ca.Area3DStyle.Enable3D = true;
ca.Area3DStyle.PointDepth = 25;
ca.Area3DStyle.WallWidth = 0;
ca.AxisX.MajorGrid.Enabled = false;
ca.AxisY.MajorGrid.LineColor = Color.White;
ca.AxisY.LineColor = Color.White;
ca.AxisY.LabelStyle.ForeColor = Color.White;
ca.AxisY.MajorTickMark.LineColor = Color.White;
ca.AxisX.LabelStyle.Enabled = false;
ca.AxisX.LineColor = Color.White;
ca.AxisX.MajorTickMark.Enabled = false;
使用 Colors
创建 Series
后,您需要应用它们,以便可以在代码中访问它们:
chart1.ApplyPaletteColors();
Series
的漂亮圆角列是由 CustomProperty
s.SetCustomProperty("DrawingStyle", "Cylinder");
更多细节:
chart.Series[1].Color = Color.Crimson;
chart.Series[0].LegendText = "Hobbits";
..
更新:您需要包含我的其他一些帖子中的两个函数 InnerPlotPositionClientRectangle
和 ChartAreaClientRectangle
,例如 here or here!
为了做到这一点 work in ASP 你在 PageLoad
:
chart1.PostPaint += new EventHandler<ChartPaintEventArgs>(chart1_PostPaint);