Tôi cần trợ giúp lập biểu đồ nhiều điểm hơn có thể phù hợp trong một chuỗi Excel.C#/Excel: Làm việc Xung quanh Kích thước Dòng Tối đa Trên Biểu đồ
Theo số http://office.microsoft.com/en-us/excel/HP100738491033.aspx số điểm tối đa có thể hiển thị trên biểu đồ Excel 2007 là 256000. Do mỗi chuỗi giới hạn ở 32000 điểm, 8 chuỗi được yêu cầu để vẽ toàn bộ 256000 điểm. Khách hàng của tôi yêu cầu vẽ số lượng điểm tối đa trên mỗi biểu đồ do các tập dữ liệu lớn mà chúng tôi làm việc.
Tôi có kinh nghiệm vừa phải với C#/Excel interop nên tôi nghĩ sẽ dễ dàng tạo lập một bảng tính và sau đó lặp qua từng bộ 32000 điểm và thêm chúng vào biểu đồ dưới dạng chuỗi, dừng khi dữ liệu hoàn toàn vẽ hoặc 8 loạt được vẽ. Nếu được tô màu đúng cách, chuỗi 8 sẽ không thể phân biệt bằng một chuỗi đơn.
Thật không may ở đây tôi. Vấn đề chính tôi gặp phải là:
(full size) The maximum number of datapoints you can use in a data series for a 2-D chart is 32,000... http://img14.imageshack.us/img14/9630/errormessagen.png
này pop-up, lạ đủ, xuất hiện khi tôi thực hiện các dòng:
và được đi kèm:
Exception from HRESULT: 0x800AC472 http://img21.imageshack.us/img21/5153/exceptionb.png
Tôi không hiểu làm thế nào tôi có thể tạo ra một popup/cảnh báo/ngoại lệ trước khi tôi thậm chí đã chỉ định dữ liệu được vẽ đồ thị. Excel có cố gắng thông minh ở đây không?
Là giải pháp tạm thời, tôi đã đặt biểu đồ.ChartType = chartType statement thành khối try-catch để tôi có thể tiếp tục.
Như sau đây cho thấy, mã "chunking" của tôi đang hoạt động như dự định, nhưng tôi vẫn gặp phải vấn đề tương tự khi cố gắng thêm dữ liệu vào biểu đồ. Excel nói rằng tôi đang cố gắng vẽ đồ thị quá nhiều điểm khi tôi không rõ ràng.
(full size image) code block with watch window http://img12.imageshack.us/img12/5360/snippet.png
Tôi hiểu rằng tôi không thể có giá trị X được liên kết một cách chính xác với từng loạt, nhưng tôi đang cố gắng để có được điều này để làm việc trước khi tôi đi xa hơn.
Mọi trợ giúp sẽ được đánh giá cao.
Dưới đây là đoạn code đầy đủ:
public void DrawScatterGraph(string xColumnLetter, string yColumnLetterStart, string yColumnLetterStop, string xAxisLabel, string yAxisLabel, string chartTitle, Microsoft.Office.Interop.Excel.XlChartType chartType, bool includeTrendline, bool includeLegend)
{
int totalRows = dataSheet.UsedRange.Rows.Count; //dataSheet is a private class variable that
//is already properly set to the worksheet
//we want to graph from
if (totalRows < 2) throw new Exception("Not generating graph for " + chartTitle.Replace('\n', ' ')
+ " because not enough data was present");
ChartObjects charts = (ChartObjects)dataSheet.ChartObjects(Type.Missing);
ChartObject chartObj = charts.Add(100, 300, 500, 300);
Chart chart = chartObj.Chart;
try { chart.ChartType = chartType; }
catch { } //i don't know why this is throwing an exception, but i'm
//going to bulldoze through this problem temporarily
if (totalRows < SizeOfSeries) //we can graph the data in a single series - yay!
{
Range xValues = dataSheet.get_Range(xColumnLetter + "2", xColumnLetter + totalRows.ToString());
Range yValues = dataSheet.get_Range(yColumnLetterStart + "1", yColumnLetterStop + totalRows.ToString());
chart.SetSourceData(yValues, XlRowCol.xlColumns);
SeriesCollection seriesCollection = (SeriesCollection)chart.SeriesCollection(Type.Missing);
foreach (Series s in seriesCollection)
{
s.XValues = xValues;
}
}
else // we need to split the data across multiple series -- this doesn't work yet
{
int startRow = 1;
while (startRow < totalRows)
{
int stopRow = (startRow + SizeOfSeries)-1;
if (stopRow > totalRows) stopRow = totalRows;
Range curRange = dataSheet.get_Range(yColumnLetterStart + startRow.ToString(), yColumnLetterStop + stopRow.ToString());
try
{
((SeriesCollection)chart.SeriesCollection(Type.Missing)).Add(curRange, XlRowCol.xlColumns,
Type.Missing, Type.Missing, Type.Missing);
}
catch (Exception exc)
{
throw new Exception(yColumnLetterStart + startRow.ToString() + "!" + yColumnLetterStop + stopRow.ToString() + "!" + exc.Message);
}
startRow = stopRow+1;
}
}
chart.HasLegend = includeLegend;
chart.HasTitle = true;
chart.ChartTitle.Text = chartTitle;
Axis axis;
axis = (Axis)chart.Axes(XlAxisType.xlCategory, XlAxisGroup.xlPrimary);
axis.HasTitle = true;
axis.AxisTitle.Text = xAxisLabel;
axis.HasMajorGridlines = false;
axis.HasMinorGridlines = false;
axis = (Axis)chart.Axes(XlAxisType.xlValue, XlAxisGroup.xlPrimary);
axis.HasTitle = true;
axis.AxisTitle.Text = yAxisLabel;
axis.HasMajorGridlines = true;
axis.HasMinorGridlines = false;
if (includeTrendline)
{
Trendlines t = (Trendlines)((Series)chart.SeriesCollection(1)).Trendlines(Type.Missing);
t.Add(XlTrendlineType.xlLinear, Type.Missing, Type.Missing, 0, 0, Type.Missing, false, false, "AutoTrendlineByChameleon");
}
chart.Location(XlChartLocation.xlLocationAsNewSheet, "Graph");
}
Cảm ơn bạn Jon! Tôi đã thêm phần sau gần đầu chức năng của mình: Phạm vi tempRange = dataSheet.get_Range ("E1", "E2"); tempRange.Select(); Trường hợp cột E trống (dữ liệu của tôi chỉ ở cột A - C). Với sự thay đổi này tại chỗ, mọi thứ hoạt động bình thường. Cảm ơn bạn một lần nữa! – Vincent