为了账号安全,请及时绑定邮箱和手机立即绑定

如何在 C# 中的柱形图顶部添加百分比

如何在 C# 中的柱形图顶部添加百分比

C#
桃花长相依 2022-01-09 10:06:20
所以,这就是问题所在。我有一个图表,使用以下循环显示跨多种工作类型的已完成和未完成两列:foreach (var workType in model.WorkTypes)        {            decimal completed = 0;            decimal uncompleted = 0;            decimal workSubmitted = 0;            decimal completionRate= 0;            foreach (var rec in model.JobList.Where(x => x.jobType== workType.Id))            {                uncompleted += model.JobList.SingleOrDefault(x => x.recID== rec.recID && x.jobType == workType.Id).Uncompleted;                completed += model.JobList.SingleOrDefault(x => x.recID == rec.recID && x.jobType == workType.Id).Completed;            }            workSubmitted = uncompleted + completed;            if (uncompleted != 0)            {                completionRate= (completed/ workSubmitted) * 100;            }                            myChart.Series["Uncompleted"].Points.AddXY(workType.TypeName, uncompleted );            myChart.Series["Completed"].Points.AddXY(workType.TypeName, completed);        }我想要做的是让它在两列上方显示一个标签,将completionRate 值显示为每个workType 的百分比。任何帮助或建议将不胜感激。这是图表的当前外观:
查看完整描述

1 回答

?
胡说叔叔

TA贡献1804条经验 获得超8个赞

默认情况下Labels显示 y 值,但您可以Label为每个设置任意值,DataPoint例如当您添加这样的点时:


int p = myChart.Series["Uncompleted"].Points.AddXY(workType.TypeName, rejections);

myChart.Series["Uncompleted"].Points[p].Label = sometext;

当然,您可以根据需要计算标签的文本,例如:


string sometext = (workSubmitted / rejections * 100).ToString("0.00") + "%";

请注意,您必须Label在更改计算中的值后更新。不支持自动表达式!


更新


正如我所写,Label 以列共享的 x 值为中心是很难甚至是不可能的;那是因为 aLabel属于单个数据点。这是柱形(和条形)类型图表的一个独特问题,因为这里系列的点以群集的形式显示在公共 x 值周围。(我们可以通过将标签添加到中点来解决当且仅当我们有奇数个系列时)


所以我们需要使用Annotations. 这是一个函数,它将TextAnnotation以 x 值和两个数据点的较大 y 值的高度为中心放置..:


void setCenterAnnotation(Chart chart, ChartArea ca, 

                         DataPoint dp1, DataPoint dp2, string lbl)

{

        TextAnnotation ta = new TextAnnotation();

        ta.Alignment = ContentAlignment.BottomCenter;

        ta.AnchorAlignment = ContentAlignment.TopCenter;

        DataPoint dp = dp1.YValues[0] > dp2.YValues[0] ? dp1 : dp2;

        ta.Height = 0.36f;

        ta.AxisX = ca.AxisX;

        ta.AxisY = ca.AxisY;

        ta.AnchorDataPoint = dp;

        ta.AnchorX = dp1.XValue;

        ta.Text =  lbl;

        chart.Annotations.Add(ta);

}

如果你有两个以上,Series你最好确定锚点,即之前值较大的那个,然后传递它而不是我在这里传递的两个点。

放置/锚定注释并不是很明显,所以这里有一些注意事项:

  • 锚定到 aDataPoint以使其显示在其 y 值的高度。

  • 要使用(轴)值进行锚定,必须为其分配一个或两个轴。

  • 然后我(顺序很重要!)设置AnchorX属性,使其不以一个点为中心,而是以公共 x 值为中心。

  • 我还设置了一些Height,否则文本不会在列顶部移动;不太清楚这里的理由是什么..

结果如下:

//img1.sycdn.imooc.com//61da434c0001b40906570309.jpg

我在添加点时添加了注释:


int ix = s1.Points.AddXY(i, rnd.Next(i+7));

s2.Points.AddXY(i, rnd.Next(i+4)+3);

double vmax = Math.Max(s1.Points[ix].YValues[0], s2.Points[ix].YValues[0]);

string lbl = (vmax / 123f).ToString("0.0") + "%";

setCenterAnnotation(chart12, ca, s1.Points[ix], s2.Points[ix], lbl );


查看完整回答
反对 回复 2022-01-09
  • 1 回答
  • 0 关注
  • 351 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信