如何在图形区域添加图像/文本以显示堆叠条形图 OfficeOpenXML 或 EPPlus C# 中每个图例的百分比值?

问题描述 投票:0回答:1

我有堆积条形图,因为我想显示每个标签的百分比(PDD1 标签为 80%)。 80 是我们可以在前 2 个条之间显示的数字(这里 3 个差异标签每个有 2 个条)。

注意:80% 值并非特定于第一个柱,它位于 2 个柱之间。

[![在此处输入图像描述][1]][1]

所以我添加了百分比记录,但无法从图表中隐藏并显示在每个标签区域的顶部中间。

我尝试了一些文章解决方案(https://stackoverflow.com/a/9036445/11010986),但我在OfficeOpenXml.Drawing.Chart中看不到LoadEntries选项

chart1.Legend.LoadEntries(chart1.Legend.LegendEntries().Count).Delete()

我看到了条目选项,但它是只读的。

编辑 1:图表数据:[![在此处输入图像描述][2]][2]

C# 代码块:


dynamic DataList5 = new
{
    label = new List<string>() { "PDD1", "PDD2", "PDD3" },
    modeler = new { Category1 = new List<int>() { 1, 1, 1 }, Category2 = new List<int>() { 0, 0, 0 } },
    tester = new { Category1 = new List<int>() { 2, 2, 2 }, Category2 = new List<int>() { 2, 2, 2 } },
    percentage = new List<int>() { 150, 200, 10 }
};


if (DataList5.label.Count > 0)
{
    int j = 0;
    for (int i = 0; i < DataList5.label.Count * 2; i++)
    {
        if (i % 2 == 0)
        {
            ws2.Cells[i + 2, 2].Value = DataList5.label[j];
            ws2.Cells[i + 2, 3].Value = "Category 1";
            ws2.Cells[i + 2, 4].Value = DataList5.modeler.Category1[j];
            ws2.Cells[i + 2, 5].Value = DataList5.tester.Category1[j];
            ws2.Cells[i + 2, 6].Value = DataList5.percentage[j];
        }
        else
        {
            ws2.Cells[i + 2, 3].Value = "Category 2";
            ws2.Cells[i + 2, 4].Value = DataList5.modeler.Category2[j];
            ws2.Cells[i + 2, 5].Value = DataList5.tester.Category2[j];
            j++;
        }
    }
}
else
{
    ws2.Cells[2, 2].Value = "No Data Found";
}
var chart1 = ws1.Drawings.AddChart("chart1", eChartType.ColumnStacked);
chart1.SetPosition(1, 0, 0, 0);
chart1.SetSize(1800, 400);
chart1.Style = eChartStyle.Style12;

if (DataList5.label.Count > 0)
{
    var series1 = chart1.Series.Add(ws2.Cells["D2:D" + (DataList5.label.Count * 2 + 1)], ws2.Cells["B2:C" + (DataList5.label.Count * 2 + 1)]);
    var series2 = chart1.Series.Add(ws2.Cells["E2:E" + (DataList5.label.Count * 2 + 1)], ws2.Cells["B2:C" + (DataList5.label.Count * 2 + 1)]);
//percentage series
    //var series3 = chart1.Series.Add(ws2.Cells["F2:F" + (DataList5.label.Count * 2 + 1)], ws2.Cells["B2:C" + (DataList5.label.Count * 2 + 1)]);


    series1.Fill.Color = Color.FromArgb(255, 0, 112, 192);
    series2.Fill.Color = Color.FromArgb(255, 239, 125, 49);

//Show percentage for each PDD1 label
    ////chart1.Legend.LoadEntries(chart1.Legend.LegendEntries().Count).Delete();

    series1.Header = "Modeler";
    series2.Header = "Tester";
    //series3.Header = "Percentage";

}
else
{
    var series1 = chart1.Series.Add(ws2.Cells["B2:C" + (DataList1.label.Count + 1)], ws2.Cells["B2:C" + (DataList1.label.Count + 1)]);
}```

chart1.Title.Text = "Stacked bar chart example";
Result is: [![enter image description here][3]][3]

Here showing percentage is problem for me.

even PDD1 should come between first 2 bars but that's not major concern here.

Edit 2: My question here is can we add text box that should show percentage value of each label as following:

[![enter image description here][4]][4]

Anyone has idea about solution in C# EPPlus or OfficeOpenXML?


  [1]: https://i.sstatic.net/wijHekfY.png
  [2]: https://i.sstatic.net/KPSPOf9G.png
  [3]: https://i.sstatic.net/pBG5RMAf.png
  [4]: https://i.sstatic.net/VgbspPth.png
c# excel epplus
1个回答
0
投票

我使用 Image 和 Stream 对象为每个图表动态创建了一个图像,并使用 Drawings.AddPicture 根据我的逻辑计算位置,将图像字节数组放置在 Excel 的确切位置(按值分割 = 图表大小/图例计数)。

注意:回答这个问题是因为我不想错误地结束我的问题[https://stackoverflow.com/q/79038452/11010986]。

为给定文本绘制图像的代码:

{

    //first, create a dummy bitmap just to get a graphics object
    Image img = new Bitmap(1, 1);
    Graphics drawing = Graphics.FromImage(img);

    //measure the string to see how big the image needs to be
    SizeF textSize = drawing.MeasureString(text, font);

    //free up the dummy image and old graphics object
    img.Dispose();
    drawing.Dispose();

    //create a new image of the right size
    img = new Bitmap((int)textSize.Width, (int)textSize.Height);

    drawing = Graphics.FromImage(img);

    //paint the background
    drawing.Clear(backColor);

    //create a brush for the text
    System.Drawing.Brush textBrush = new SolidBrush(textColor);

    drawing.DrawString(text, font, textBrush, 0, 0);

    drawing.Save();
    textBrush.Dispose();
    drawing.Dispose();

    ImageConverter _imageConverter = new ImageConverter();
    byte[] xByte = (byte[])_imageConverter.ConvertTo(img, typeof(byte[]));
    return xByte;

}

以及将上述方法 byte[] 插入 excel 的代码:

int PixelTop = 60;
int PixelLeft = 870;
int diff = 0;
if (count > 1)
{
    diff = 1800 / (count + 1);
    diff = diff / 2;
    PixelLeft = diff + (diff / 2);
}
for (int i = 0; i < count; i++)
{
    byte[] bytes = DrawText(DataList5.percentage[i] + "%", font, Color.Black, Color.White);
    Stream stream = new MemoryStream(bytes);
    ExcelPicture pic = ws1.Drawings.AddPicture(DataList5.label[i] + i, stream);
    pic.SetPosition(PixelTop, PixelLeft);
    //ws1.Protection.IsProtected = false;
    //ws1.Protection.AllowSelectLockedCells = false;
    PixelLeft += (diff * 2);
}
© www.soinside.com 2019 - 2024. All rights reserved.