简体   繁体   中英

C# chart with multiple series, each with different x axis

I'm trying to export data to excel file (working quite fine) and create a chart.

What I have: 3 columns - ID, value, date. There are multiple rows with same id, but different value and datetime.

Example:
ID - Value - Datetime
1 - 14 - 21.11.2017 2:17:08
1 - 15 - 22.11.2017 14:25:45
3 - 12.5 - 21.11.2017 15:12:12
3 - 18.7 - 21.11.2017 19:27:35
3 - 13 - 22.11.2017 0:47:17

What I want is a chart, where Value is Y axis, each ID is a series, and Datetime is X axis. However, the datetime is different for each ID.

This is how it should look, but with dates instead of numbers on the X axis. Chart Image .

I've been searching for a solution, and trying solutions from similar questions, but none had been "on point" yet. This is what I have so far:

Excel.ChartObjects ChartObjects = (Excel.ChartObjects)WS.ChartObjects();
Excel.ChartObject chartObject = ChartObjects.Add(400, 40, 450, 300);
chartObject.Chart.ChartType = Excel.XlChartType.xlXYScatterLines;
Excel.SeriesCollection oSeriesCollection = (Excel.SeriesCollection)chartObject.Chart.SeriesCollection();

Excel.Axis xAxis = (Excel.Axis)chartObject.Chart.Axes(Excel.XlAxisType.xlCategory, Excel.XlAxisGroup.xlPrimary);
xAxis.HasTitle = true;
xAxis.AxisTitle.Text = "Date";   

Excel.Axis yAxis = (Excel.Axis)chartObject.Chart.Axes(Excel.XlAxisType.xlValue, Excel.XlAxisGroup.xlPrimary);
yAxis.HasTitle = true;
yAxis.AxisTitle.Text = "Value";

int startPos = 4;
int endPos = 0;
int previousCount = 0;
for (int i = 0; i < Count; i++)
{
    startPos = startPos + previousCount;
    endPos = startPos + CountList[i].Count - 1;

    Excel.Series oSeries = oSeriesCollection.NewSeries();
    oSeries.Values = WS.Range["E" + startPos, "E" + endPos];
    //oSeries.XValues = WS.Range["F" + startPos, "F" + endPos];   //doesn't really do anything
    oSeries.Name = "id " + CountList[i].Number.ToString();
    previousCount = CountList[i].Count;
}

If it makes any difference, date is datetime in database, but is converted to string when storing it in List.

How can I set the x axis the way I need it to be? Is it possible?

I did something very similar using EPPlus. It was in asp.net MVC 5, so saving the document might need to be altered to suit your needs. In my case reading age is the value you want to display on Y axis and they have dates on X axis. Hopefully this will at least you give you something to build on. Notice the comment within, otherwise the chart did not work as intended for me.

        var results = GetResultsSomehow();

        ExcelPackage excel = new ExcelPackage();
        var workSheet = excel.Workbook.Worksheets.Add("Reading Ages");

        workSheet.TabColor = System.Drawing.Color.Black;

        var scatterChart = (ExcelScatterChart)workSheet.Drawings.AddChart("Reading Ages", eChartType.XYScatterSmooth);
        scatterChart.SetPosition(3, 1, 4, 1);
        scatterChart.SetSize(800, 500);
        scatterChart.XAxis.Format = "dd/mm/yyyy";
        // must display hidden data and empty as gaps, otherwise the date axis will explode 
        scatterChart.ShowHiddenData = true;
        scatterChart.DisplayBlanksAs = eDisplayBlanksAs.Gap;

        int rowIndex = 4;
        int stopIndex = 4;
        foreach (var student in results.Select(a=> a.Student).Distinct())
        {
            int start = rowIndex;
            int stop = start + stopIndex;

            workSheet.Cells[rowIndex, 1].Value = student.Surname;
            foreach(var row in results.Where(a=> a.Student == student))
            {
                workSheet.Cells[rowIndex, 2].Value = row.Age;
                workSheet.Cells[rowIndex, 3].Value = row.Date;

                rowIndex++;
                stopIndex++;
            }

            stop = rowIndex;
            var series = scatterChart.Series.Add(workSheet.Cells[start, 2, stop - 1, 2], workSheet.Cells[start, 3, stop - 1, 3]);
            series.Header = student.Surname;           
        }

        string excelName = identifier + " reading ages";
        using (var memoryStream = new MemoryStream())
        {
            Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
            Response.AddHeader("content-disposition", "attachment; filename=" + excelName + ".xlsx");
            excel.SaveAs(memoryStream);
            memoryStream.WriteTo(Response.OutputStream);
            Response.Flush();
            Response.End();
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM