2009-09-14 19 views
8

मुझे एक एक्सेल श्रृंखला में फ़िट होने की तुलना में अधिक अंक ग्राफिंग में मदद की ज़रूरत है।सी #/एक्सेल: चार्ट पर अधिकतम श्रृंखला आकार के आसपास काम करना

http://office.microsoft.com/en-us/excel/HP100738491033.aspx के अनुसार एक्सेल 2007 चार्ट पर प्रदर्शित अंकों की अधिकतम संख्या 256000 है। यह देखते हुए कि प्रत्येक श्रृंखला 32000 अंक पर समाप्त हो जाती है, 8 श्रृंखलाओं को पूर्ण 256000 अंक प्लॉट करने की आवश्यकता होती है। मेरे ग्राहक के साथ काम करने वाले बड़े डेटा सेट के कारण प्रति चार्ट की अधिकतम मात्रा की साजिश की आवश्यकता होती है।

मेरे पास सी #/एक्सेल इंटरऑप के साथ मध्यम अनुभव है इसलिए मैंने सोचा कि प्रोग्रामेटिक रूप से वर्कशीट बनाने और 32000 अंकों के प्रत्येक सेट के माध्यम से लूप करना आसान होगा और उन्हें एक श्रृंखला के रूप में ग्राफ में जोड़ना होगा, जब डेटा पूरी तरह से बंद हो जाएगा प्लॉट या 8 श्रृंखला प्लॉट की गई थी। यदि रंग सही ढंग से होता है, तो 8 श्रृंखला एक श्रृंखला से दृष्टिहीन रूप से अलग-अलग होगी।

दुर्भाग्य से यहां मैं हूं। मुख्य समस्या यह है कि मैं का सामना है:

(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

यह पॉप-अप, अजीब पर्याप्त, प्रकट होता है जब मैं लाइन पर अमल:

:

chart.ChartType = chartType (where chartType is xlXYScatterLines) http://img2.imageshack.us/img2/2413/linean.png

और के साथ है

Exception from HRESULT: 0x800AC472 http://img21.imageshack.us/img21/5153/exceptionb.png

मुझे समझ में नहीं आता कि मैं डेटा को निर्दिष्ट करने के लिए निर्दिष्ट करने से पहले मैं इस तरह के पॉपअप/चेतावनी/अपवाद कैसे उत्पन्न कर सकता हूं। क्या एक्सेल यहां चालाक होने की कोशिश कर रहा है?

एक अस्थायी कामकाज के रूप में, मैंने चार्ट डाल दिया है। चार्टटाइप = चार्ट टाइप स्टेटमेंट को एक कोशिश-पकड़ ब्लॉक में रखें ताकि मैं जा सकूं।

निम्न शो के रूप में, मेरा "खंडन" कोड इरादे के रूप में काम कर रहा है, लेकिन ग्राफ में डेटा जोड़ने का प्रयास करते समय भी मुझे एक ही समस्या आती है। एक्सेल का कहना है कि जब मैं स्पष्ट रूप से नहीं हूं तो मैं बहुत सारे अंक ग्राफ करने की कोशिश कर रहा हूं।

(full size image) code block with watch window http://img12.imageshack.us/img12/5360/snippet.png

मैं समझता हूँ कि मैं एक्स मान सही ढंग से अभी तक प्रत्येक श्रृंखला के साथ जुड़े नहीं हो सकता है, लेकिन मैं इससे पहले कि मैं आगे जाना है कि यह काम करने के लिए प्राप्त करने की कोशिश कर रहा हूँ।

किसी भी मदद की सराहना की जाएगी।

यहाँ पूर्ण कोड है:

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"); 
    } 

उत्तर

2

यदि सक्रिय सेल डेटा के ब्लॉक में है, तो Excel मान सकता है कि आप सीमा को प्लॉट करना चाहते हैं।

एक खाली सेल का चयन करें जो डेटा के बगल में नहीं है, फिर चार्ट डालें। यह पूर्वनिर्धारित के बजाय खाली होगा।

+0

धन्यवाद जॉन! मैंने अपने फ़ंक्शन के शीर्ष के पास निम्न को जोड़ा: रेंज tempRange = dataSheet.get_Range ("E1", "E2"); tempRange.Select(); जहां कॉलम ई खाली है (मेरा डेटा केवल कॉलम ए-सी में है)। इस बदलाव के साथ, सब कुछ ठीक से काम किया। फिर से धन्यवाद! – Vincent

2

अपने ग्राफ वास्तव में Excel में होना जरूरी है? कई डेटा बिंदुओं के साथ प्रदर्शन भयानक होगा।

ग्राफ उत्पन्न करने के लिए किसी तृतीय पक्ष घटक का उपयोग करने का सुझाव हो सकता है। इसे पूरा करने के लिए विशिष्ट तकनीक इस बात पर निर्भर करती है कि क्या आपको एक्सेल में डेटा देखने में सक्षम होना है या आउटपुट ग्राफ़ को कहीं और उपलब्ध होना चाहिए या नहीं।

यदि ग्राफ को Excel के भीतर दिखाई देने की आवश्यकता नहीं है, तो बस डेटा बिंदुएं पास करें और चित्र को ग्राफ़िंग एप्लिकेशन या वेब ब्राउज़र में देखें।

यदि आपको एक्सेल के साथ ग्राफ देखने की आवश्यकता है, तो आप बाहरी ग्राफिंग एप्लिकेशन पर कॉल कर सकते हैं और इसे डेटा पॉइंट्स का संग्रह पास कर सकते हैं। जब यह छवि लौटाता है तो इसे एक्सा में एक्सा में डालें।

यदि आपको आवश्यकता हो तो मैं आपको दोनों दृष्टिकोणों पर अधिक जानकारी दे सकता हूं।

इसके अलावा, अन्य विचारों में शामिल हो सकता है कि आपको ग्राफ पर क्षमता को कम करने की आवश्यकता है या नहीं। इस कई डेटा बिंदुओं के साथ, मैं कल्पना नहीं कर सकता कि आप करेंगे।


यदि आप निम्नलिखित प्रश्नों का उत्तर दे सकते हैं, तो यह लोगों को बेहतर उत्तरों को तैयार करने में मदद कर सकता है।

  1. इन वस्तुओं के आउटपुट का किस प्रकार का यूजर इंटरफेस पेश करेगा? (उदाहरण के लिए एक्सेल, एएसपी.नेट वेब एप्लीकेशन, विंडोज फॉर्म, डब्ल्यूपीएफ, सिल्वरलाइट, अन्य।)

  2. क्या ये ग्राफ किसी उपयोगकर्ता के अनुरोध पर वास्तविक समय में जेनरेट किए जाने चाहिए या वे जेनरेट और संग्रहीत हैं? यदि वे मांग पर उत्पन्न होते हैं, तो आपके उपयोगकर्ताओं को प्रतीक्षा करने के लिए स्वीकार्य माना जाने वाला अधिकतम समय क्या होगा?

  3. आप वास्तव में Excel का उपयोग करना कितना महत्वपूर्ण है? क्या आप इसका उपयोग कर रहे हैं क्योंकि यह प्रदर्शन के लिए एक आवश्यकता है, या यह सिर्फ आसान है?

  4. ग्राफ के प्रदर्शन के लिए "वाह कारक" कितना महत्वपूर्ण है? क्या बस ग्राफ हैं, या क्या उन्हें बेहद सुंदर होना है?

  5. क्या उपयोगकर्ताओं को ग्राफ में ड्रिल करने की क्षमता की आवश्यकता होती है, या बस छवि को पर्याप्त रूप से देखने में सक्षम है?

+0

इनपुट, एंथोनी के लिए धन्यवाद। जॉन ने सलाह दी थी कि मैं अन्य विकल्पों पर विचार करने के बिंदु के करीब आ रहा था। एफवाईआई, मैंने एक्सेल के साथ काम करना शुरू कर दिया क्योंकि 1) यह आसानी से मेरे "दीवार वाले बगीचे" उपयोगकर्ता आधार पर उपलब्ध है और 2) कभी-कभी ग्राफ को ऑटो-पीढ़ी के बाद हाथ से ट्विक करने की आवश्यकता होती है और उपयोगकर्ताओं को एक्सेल में प्रशिक्षित किया जाता है। – Vincent

1

किसी को जो भविष्य में इस भर आता है के लिए, यहां जॉन की ठीक से पूरा समारोह है:

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"); 

     dataSheet.get_Range("Z1", "Z2").Select(); //we need to select some empty space 
                //so Excel doesn't try to jam the 
                //potentially large data set into the 
                //chart automatically 

     ChartObjects charts = (ChartObjects)dataSheet.ChartObjects(Type.Missing); 
     ChartObject chartObj = charts.Add(100, 300, 500, 300); 
     Chart chart = chartObj.Chart; 
     chart.ChartType = chartType; 
     SeriesCollection seriesCollection = (SeriesCollection)chart.SeriesCollection(Type.Missing); 

     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); 

      foreach (Series s in seriesCollection) 
      { 
       s.XValues = xValues; 
      } 
     } 
     else // we need to split the data across multiple series 
     { 
      int startRow = 2; 

      while (startRow < totalRows) 
      { 
       int stopRow = (startRow + SizeOfSeries)-1; 
       if (stopRow > totalRows) stopRow = totalRows; 

       Series s = seriesCollection.NewSeries(); 
       s.Name = "ChunkStartingAt" + startRow.ToString(); 
       s.XValues = dataSheet.get_Range(xColumnLetter + startRow.ToString(), xColumnLetter + stopRow.ToString()); 
       s.Values = dataSheet.get_Range(yColumnLetterStart + startRow.ToString(), yColumnLetterStop + stopRow.ToString()); 

       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"); 
    }