nissl-lab / npoi

a .NET library that can read/write Office formats without Microsoft Office installed. No COM+, no interop.
Apache License 2.0
5.74k stars 1.43k forks source link

To set Colors to each column in ColumnChart in NPOI package #1298

Closed yazh21 closed 7 months ago

yazh21 commented 8 months ago
 using NPOI.SS.UserModel;
 using NPOI.SS.UserModel.Charts;
 using NPOI.SS.Util;
 using NPOI.XSSF.UserModel;
 using System;
 using System.IO;

 namespace ColumnChart
 {
 class Program
 {
const int NUM_OF_ROWS = 4;
const int NUM_OF_COLUMNS = 2;
private static void CreateChart(ISheet sheet, IDrawing drawing, IClientAnchor anchor, string serieTitle, int startDataRow, int endDataRow, int columnIndex)
{
    XSSFChart chart = (XSSFChart)drawing.CreateChart(anchor);

    IColumnChartData<string, double> columnChartData = chart.ChartDataFactory.CreateColumnChartData<string, double>();
    IChartLegend legend = chart.GetOrCreateLegend();
    legend.Position = LegendPosition.Bottom;

    IChartAxis bottomAxis = chart.ChartAxisFactory.CreateCategoryAxis(AxisPosition.Bottom);
    bottomAxis.MajorTickMark = AxisTickMark.None;
    IValueAxis leftAxis = chart.ChartAxisFactory.CreateValueAxis(AxisPosition.Left);
    leftAxis.Crosses = AxisCrosses.AutoZero;
    leftAxis.SetCrossBetween(AxisCrossBetween.Between);

    IChartDataSource<string> categoryAxis = DataSources.FromStringCellRange(sheet, new CellRangeAddress(startDataRow, endDataRow, 0, 0));
    IChartDataSource<double> valueAxis = DataSources.FromNumericCellRange(sheet, new CellRangeAddress(startDataRow, endDataRow, columnIndex, columnIndex));
    var serie = columnChartData.AddSeries(categoryAxis, valueAxis);
    serie.SetTitle("Categories of Risk Associated");

    chart.Plot(columnChartData, bottomAxis, leftAxis);
}
static void Main(string[] args)
{
    using (IWorkbook wb = new XSSFWorkbook())
    {
        ISheet sheet = wb.CreateSheet();

        IRow row;
        ICell cell;
        for (int rowIndex = 0; rowIndex < NUM_OF_ROWS; rowIndex++)
        {
            row = sheet.CreateRow((short)rowIndex);
            for (int colIndex = 0; colIndex < NUM_OF_COLUMNS; colIndex++)
            {
                cell = row.CreateCell((short)colIndex);
                if (colIndex == 0)
                    cell.SetCellValue("X" + rowIndex);
                else
                {
                    var x = colIndex * (rowIndex + 1);
                    cell.SetCellValue(x * x + 2 * x + 1);
                }
            }
        }
        XSSFDrawing drawing = (XSSFDrawing)sheet.CreateDrawingPatriarch();
        XSSFClientAnchor anchor = (XSSFClientAnchor)drawing.CreateAnchor(0, 0, 0, 0, 3, 3, 10, 12);

        CreateChart(sheet, drawing, anchor, "s1", 0, 9, 1);
        using (FileStream fs = File.Create("C:\\Users\\lenovo\\Downloads\\columnChart.xlsx"))
        {
            wb.Write(fs, false);
        }
        Console.WriteLine("Done!");
        Console.ReadLine();
      }
    }
  }
 }

I have code to Generate Excel File where with my data on excel sheet , it creates Column Chart using Npoi package. In that I have 4 columns in my column chart where all columns color is blue by default. I want to set custom colors for each Column in Column chart that is 4 different colors for 4 columns in column chart.How to Achieve this? This is sample of Chart Generated ColumnchartBlue

This is sample of Chart Wanted

ColumnchartColor

https://github.com/artem-iron/AreaAndPieChartsExample

Originally posted by @artem-iron in https://github.com/nissl-lab/npoi/issues/866#issuecomment-1183971051

Bykiev commented 8 months ago

Hi, you can use this code right after chart.Plot() call:

byte[][] colors = new byte[][] {
  new byte[] {127,(byte)255, 127},
  new byte[] {(byte)200, (byte)200, (byte)200},
  new byte[] {(byte)255,(byte)255, 127},
  new byte[] {(byte)255, 127, 127},
  new byte[] {(byte)255, 0, 0},
  new byte[] {0, (byte)255, 0},
  new byte[] {0, 0, (byte)255},
  new byte[] {80, 80, 80},
  new byte[] {90, 80, 80},
  new byte[] {100, 80, 80}
};

int pointCount = serie.GetCategoryAxisData().PointCount;

var plotArea = chart.GetCTChart().plotArea;
plotArea.barChart[0].ser[0].dPt = new System.Collections.Generic.List<NPOI.OpenXmlFormats.Dml.Chart.CT_DPt>();

for (int i = 0; i < pointCount; i++)
{
    plotArea.barChart[0].ser[0].dPt.Add(new NPOI.OpenXmlFormats.Dml.Chart.CT_DPt());
    plotArea.barChart[0].ser[0].dPt[i].idx = new NPOI.OpenXmlFormats.Dml.Chart.CT_UnsignedInt() { val = (uint)i};
    plotArea.barChart[0].ser[0].dPt[i].spPr = new NPOI.OpenXmlFormats.Dml.Chart.CT_ShapeProperties();
    plotArea.barChart[0].ser[0].dPt[i].spPr.AddNewSolidFill().AddNewSrgbClr().val = colors[i];
}

You can also use theme colors: chart.GetCTChart().plotArea.barChart[0].varyColors = new NPOI.OpenXmlFormats.Dml.Chart.CT_Boolean() { val = 1 };