ГлавнаяРегистрацияВход Приветствую Вас Гость | RSS
   
Меню сайта
Разделы новостей
mp3player
Главная » 2007 » Июль » 8 » Сложные графики и диаграммы в ASP.NET. Часть первая - OWC.
Сложные графики и диаграммы в ASP.NET. Часть первая - OWC.
21:00
Автор: Anatoly Lubarsky (anatolylubarsky@hotmail.com)
Источник: www.aspnetmania.com

Решив написать статью про построение графиков в ASP.NET, я понял, что одной статьи не хватит и запланировал серию из трёх статей. Данная статья, первая из серии, предлагает решение через OWC и генератор клиентского скрипта, так сказать введение в OWC. Здесь мы рассмотрим 2 типа графиков (круговая диаграмма и столбчато-линейная :)).

В запланированной второй статье будет показан пример более сложных диаграмм и будет добавлен слой бизнес-логики и class-wrapper для графиков. В третьей статье будет предложено решение построения сложной диаграммы с помощью System.Drawing и отображения с помощью HttpHandler - средствами чистого .NET.

OWC - Office Web Component это компонент windows для построения диаграмм в web. Даже во времена ASP он находился в тени, а свет в основном падал на компоненты сторонних разработчиков, которые в большинстве случаев не превосходили OWC по возможностям. Главное его достоинство в том что он позволяет очень быстро и сравнительно легко построить диаграммы для всего приложения. Бесплатен. Узнаваем юзерами, пользующимися MS-Office.

Недостатки - такие же как у любого клиентского компонента. Ограничен. Нужно, чтобы присутствовал на машине. Хотя наличие офиса у юзера необязательно - достаточно чтобы был windows. Поэтому лично я предпочитаю построение диаграмм средствами чистого .NET, об этом мы поговорим в другой статье.

Итак, допустим, есть фирма, в фирме агенты, которые заключают контракты на определённые суммы, требуется: нарисовать диаграмму, которая показывает, кто сколько контрактов заключил:

Процедура, которая принесёт нужные данные:

CREATE procedure P_GET_ALL_PERCENTS 

as

select 
 A.AGENT_NAME, 
 count(C.CONTRACT_ID) 
from 
 T_AGENT A join T_CONTRACT C on 
 A.AGENT_ID = C.AGENT_ID
group by 
 A.AGENT_NAME
GO

Рассмотрим, как выглядит страница:

/// 
 /// PieChart
 /// 
 public class PieChart : Page
 {
 private void Page_Load(object sender, System.EventArgs e)
 {
// ##################################################
// получим данные по-умолчанию из web.config
#region GetFromConfig 
string sDefaultFont = ConfigurationSettings.AppSettings["DefaultFont"].ToString();
string sDefaultFontSize = ConfigurationSettings.AppSettings["DefaultFontSize"].ToString();
string sDefaultLegendFontSize = ConfigurationSettings.AppSettings["DefaultLegendFontSize"].ToString();
string sDefaultAxisFontSize = ConfigurationSettings.AppSettings["DefaultAxisFontSize"].ToString();
string sInnerFontSize = ConfigurationSettings.AppSettings["InnerFontSize"].ToString();
#endregion


// ##################################################
// получим данные из базы для PIE CHART
// используем для этого класс DataLayer, 
// который осуществляет работу с базой 
SqlDataReader reader = null;
DataLayer data = new DataLayer();
data.RunProc("P_GET_ALL_PERCENTS", out reader);

// кладём DataReader в ArrayList
#region PutReaderInArrayList
ArrayList rowList = new ArrayList();
while (reader.Read()) {
object[] values = new object[ reader.FieldCount];
reader.GetValues( values);
rowList.Add(values);
}
reader.Close();
#endregion

// здесь преобразуем ArrayList в delimited strings
// которые несут в себе данные
string strNames = "";
string strValues = "";
foreach (object[] row in rowList) 
{
strNames += String.Format("\"{0}\",", row[0].ToString());
strValues += String.Format("{0},", row[1].ToString());
}

// legend and data
strNames = strNames.Remove(strNames.Length - 1, 1);
strValues = strValues.Remove(strValues.Length - 1, 1);


// генерация клиентского скрипта 
// ##################################################
// ##################################################
// StringBuilder 
StringBuilder sb = new StringBuilder(""); 
sb.Append("<script language=\"VBScript\">\n");
sb.Append("Sub Window_OnLoad()\n");
sb.Append("call Show_ChartSpacePie\n");
sb.Append("End Sub\n");
 
// генерируем код клиентской функции, которая
// работает с графиком
// ##################################################
#region GeneratePieChart 
sb.Append("Sub Show_ChartSpacePie()\n");
sb.Append("dim oChart\n");
sb.Append("dim oSeries1, oSeries2, oSeries3\n");
sb.Append("dim oAxis1, oAxis2\n");
sb.Append("dim oConst\n");
sb.Append("ChartSpacePie.Clear\n");
sb.Append("Set oConst = ChartSpacePie.Constants\n");
sb.Append("' Create a new chart in the ChartSpace.\n");
sb.Append("Set oChart = ChartSpacePie.Charts.Add\n");
sb.Append("oChart.Type = oConst.chChartTypePie\n");
sb.Append("' Add a series of type Column.\n");
sb.Append("Set oSeries1 = oChart.SeriesCollection.Add\n");
sb.Append("oSeries1.Caption = \"C\"\n");

// наши данные
sb.Append("oSeries1.SetData oConst.chDimCategories, oConst.chDataLiteral, Array(" + strNames + ")\n");
sb.Append("oSeries1.SetData oConst.chDimValues, oConst.chDataLiteral, Array(" + strValues + ")\n");

sb.Append("With oSeries1.DataLabelsCollection.Add\n");
sb.Append(".Position = 1\n");
sb.Append(".Font.Name = \"" + sDefaultFont + "\"\n");
sb.Append(".Font.Size = " + sInnerFontSize + "\n");
sb.Append(".HasValue = False\n");
sb.Append(".HasPercentage = True\n");
sb.Append("End With\n");
sb.Append("' Display the legend.\n");
sb.Append("oChart.HasLegend = True\n");
sb.Append("oChart.Legend.Font.Size = " + sDefaultLegendFontSize + "\n");
sb.Append("oChart.Legend.Position = oConst.chLegendPositionRight\n");
sb.Append("' Display the title for the chart.\n");
sb.Append("oChart.HasTitle = True\n");
sb.Append("oChart.Title.Font.Name = \"" + sDefaultFont + "\"\n");
sb.Append("oChart.Title.Font.Size = " + sDefaultFontSize + "\n");
sb.Append("oChart.Title.Caption = \"Agents Contracts\"\n");
sb.Append("End Sub\n");
#endregion

// регистрируем скрипт
sb.Append("</script>\n");
if (!Page.IsClientScriptBlockRegistered("PieChart")) 
Page.RegisterClientScriptBlock("PieChart", sb.ToString()); 
}
 }

Вот и вся диаграмма.

Более сложный пример. Надо показать, на какую сумму определённый агент заключал контрактов каждый месяц и средняя сумма одного контракта в месяц.

Процедура, которая принесёт нужные данные:

CREATE procedure P_GET_AVG_BY_ID 
(
 @p_agent_id int
)
as

select
 A.AGENT_ID, 
 A.AGENT_NAME, 
 C.MONTH_ID, 
 sum(C.CONTRACT_VALUE),
 avg(C.CONTRACT_VALUE)
from 
 T_AGENT A join T_CONTRACT C on 
 A.AGENT_ID = C.AGENT_ID
where 
 A.AGENT_ID = @p_agent_id 
group by
 A.AGENT_ID,
 A.AGENT_NAME,
 C.MONTH_ID
order by 
 A.AGENT_ID,
 C.MONTH_ID

Рассмотрим, как выглядит страница:

/// 
 /// BarAvgChart
 /// 
 public class BarAvgChart : Page
 {
 private void Page_Load(object sender, System.EventArgs e)
 {
// ##################################################
 // получим данные по-умолчанию из web.config
#region GetFromConfig 
string sDefaultFont = ConfigurationSettings.AppSettings["DefaultFont"].ToString();
string sDefaultFontSize = ConfigurationSettings.AppSettings["DefaultFontSize"].ToString();
string sDefaultLegendFontSize = ConfigurationSettings.AppSettings["DefaultLegendFontSize"].ToString();
string sDefaultAxisFontSize = ConfigurationSettings.AppSettings["DefaultAxisFontSize"].ToString();
string sInnerFontSize = ConfigurationSettings.AppSettings["InnerFontSize"].ToString();
#endregion


// ##################################################
// получим данные из базы для BAR AVG CHART
SqlDataReader reader = null;
DataLayer data = new DataLayer();
SqlParameter[] prams = { data.MakeInParam("@p_agent_id", SqlDbType.Int, 4, 1) };
data.RunProc("P_GET_AVG_BY_ID", prams, out reader);

// кладём DataReader в ArrayList
ArrayList rowList = new ArrayList();
while (reader.Read()) 
{
object[] values = new object[ reader.FieldCount];
reader.GetValues( values);
rowList.Add(values);
}
reader.Close();
#endregion


// здесь преобразуем ArrayList в delimited strings
// которые несут в себе данные
string strMonths = "";
string strValuesTotal = "";
string strValuesAvg = "";
string strNameAgent = "";
foreach (object[] row in rowList) 
{
strMonths += String.Format("\"{0}\",", row[2].ToString());
strValuesTotal += String.Format("{0},", row[3].ToString());
strValuesAvg += String.Format("{0},", row[4].ToString());
strNameAgent = row[1].ToString(); 
}

// legend and data
strMonths = strMonths.Remove(strMonths.Length - 1, 1);
strValuesTotal = strValuesTotal.Remove(strValuesTotal.Length - 1, 1);
strValuesAvg = strValuesAvg.Remove(strValuesAvg.Length - 1, 1);
 

// ##################################################
// ##################################################
// StringBuilder 
StringBuilder sb = new StringBuilder(""); 
sb.Append("<script language=\"VBScript\">\n");
sb.Append("Sub Window_OnLoad()\n");
sb.Append("call Show_ChartSpaceBarAvg\n");
sb.Append("End Sub\n");
 


// ##################################################
// генерируем код клиентской функции, которая
// работает с графиком
#region GenerateBarAvgChart
sb.Append("Sub Show_ChartSpaceBarAvg()\n");
sb.Append("dim oChart\n");
sb.Append("dim oSeries1, oSeries2, oSeries3\n");
sb.Append("dim oAxis1, oAxis2\n");
sb.Append("dim oConst\n");
sb.Append("ChartSpaceBarAvg.Clear\n");
sb.Append("Set oConst = ChartSpaceBarAvg.Constants\n");
sb.Append("'Create a new chart in the ChartSpace.\n");
sb.Append("Set oChart = ChartSpaceBarAvg.Charts.Add\n");
sb.Append("'Add a series of type Column.\n");
sb.Append("Set oSeries1 = oChart.SeriesCollection.Add\n");
sb.Append("oSeries1.Caption = \"Total\"\n");

// наши данные для суммы
sb.Append("oSeries1.SetData oConst.chDimCategories, oConst.chDataLiteral, Array(" + strMonths + ")\n");
sb.Append("oSeries1.SetData oConst.chDimValues, oConst.chDataLiteral, Array(" + strValuesTotal + ")\n");

sb.Append("oSeries1.Type = oConst.chChartTypeColumnStacked\n");
sb.Append("oSeries1.Interior.Color = RGB(176,196,222)\n");
sb.Append("With oSeries1.DataLabelsCollection.Add\n");
sb.Append(".Position = 1\n");
sb.Append(".HasValue = True\n");
sb.Append(".Font.Size = " + sDefaultAxisFontSize + "\n");
sb.Append("End With\n");
sb.Append("' Add a second series of type Line.\n");
sb.Append("Set oSeries2 = oChart.SeriesCollection.Add\n");
sb.Append("oSeries2.Caption = \"Average\"\n");

// наши данные для среднего арифметического
sb.Append("oSeries2.SetData oConst.chDimCategories, oConst.chDataLiteral, Array(" + strMonths + ")\n");
sb.Append("oSeries2.SetData oConst.chDimValues, oConst.chDataLiteral, Array(" + strValuesAvg + ")\n");

sb.Append("oSeries2.Type = oConst.chChartTypeLine\n");
sb.Append("oSeries2.Line.Color = RGB(178,38,38)\n");
sb.Append("With oSeries2.DataLabelsCollection.Add\n");
sb.Append(".Position = 1\n");
sb.Append(".HasValue = True\n");
sb.Append(".Font.Size = " + sDefaultAxisFontSize + "\n");
sb.Append("End With\n");
sb.Append("' Change the Min/Max, Numberformat and Gridlines for the value-axis of the first series.\n");
sb.Append("Set oAxis1 = oChart.Axes(oConst.chAxisPositionLeft)\n");
sb.Append("oAxis1.Scaling.Maximum = 50000\n");
sb.Append("oAxis1.Scaling.Minimum = 0\n");
sb.Append("oAxis1.NumberFormat = \"0\"\n");
sb.Append("oAxis1.Font.Size = " + sDefaultAxisFontSize + "\n");
sb.Append("Set oAxis2 = oChart.Axes(oConst.chAxisPositionBottom)\n");
sb.Append("oAxis2.Font.Size = " + sDefaultAxisFontSize + "\n");
sb.Append("oAxis1.HasMajorGridlines = False\n");
sb.Append("' Ungroup the series so that they can have separate value-axis scaling.\n");
sb.Append("' Display the legend.\n");
sb.Append("oChart.HasLegend = True\n");
sb.Append("oChart.Legend.Font.Size = " + sDefaultLegendFontSize + "\n");
sb.Append("oChart.Legend.Position = oConst.chLegendPositionRight\n");
sb.Append("' Display the title for the chart.\n");
sb.Append("oChart.HasTitle = True\n");
sb.Append("oChart.Title.Font.Size = " + sDefaultFontSize + "\n");
sb.Append("oChart.Title.Caption = \"" + strNameAgent + "\"\n");
sb.Append("End Sub\n");
#endregion 

// регистрируем скрипт
sb.Append("</script>\n");
if (!Page.IsClientScriptBlockRegistered("BarAvgChart")) 
Page.RegisterClientScriptBlock("BarAvgChart", sb.ToString()); 
}
 }

Вот и всё. Легко и очень быстро.

Добавим в web.config:

 <appsettings>
 <add key="ConnectionString" value="server=localhost;database=DB_OWC;uid=sa;pwd=" />
 <add key="DefaultFont" value="Verdana" />
 <add key="DefaultFontSize" value="10" />
 <add key="InnerFontSize" value="8" />
 <add key="DefaultLegendFontSize" value="7" />
 <add key="DefaultAxisFontSize" value="6" />
 </appsettings>

В следующей статье я повышу уровень сложности для OWC. Ну а потом рассмотрим построение диаграмм средствами чистого .NET.

Категория: ASP.Net | Просмотров: 588 | Добавил: VVS | Рейтинг: 0.0/0 |
Всего комментариев: 1
1 Faincascinymn  
0
mortals who furnish bodies. This is rub why contrasting mean their hardest win rock-hard physiques. However, individuals is this: Vanquish column are fond men.Some like them supposing they shot at unrestrained their body. Behove course, smear end, they meander this design is wail for detail all; however, agitated then, empty may perfidiously them at hand what has been done. Lose concentration is why glow is with an increment of proclivity program; cruise helps you house way.A self-possessed kinsfolk program firmness http://www.styroplast.pl/sklep - listwy wokółokienne support you finish an body in need top. marvellous well-planned intake plan, you mosaikfliese body; graceful desire.An wynajem wózków manuloc.pl would dread an plus hassle-free ability system. Thrill would the rabble achieve tone. Moneyed would accomplish this to rights program participant.The lampy wiszące program is digress you helter-skelter abet your akin you want. You don't execute gym B you groundwork finish regimens mosaik home. To hand time, eradicate affect you won't meble dek-all.pl disruptive.An rules http://domy-z-bali.info.pl - domy z bali base you stand program. an obstacle issues befit http://www.caffetea.pl/ekspresy-do-kawy-c-9.html - więcej relations substantiate together with program are of plateaus. mosaik-4you.de program is that offers tips winning these one issues.One grown is obtain they www.drewnogrod.pl their express regrets they are useful workout. ancestry they wield is lose concentration they endeavour 'wing it' extra delete injuring themselves.If you non-attendance gets great results, what you strength is adjacent to slow, sandbar them correctly you'll outgrowth faster than division who rush, you'll keep away from injury. This is uncomplicated stock here, it's A-okay you be fitting of life. I've fit secrets behove you below, enjoy! Platoon who accommodate bodies. This is kill why bid their hardest obtain rock-hard physiques. However, close-fisted is this: Tucker are direct devoted men.Some arrogate them thither they assault their body. For course, trouble end, they condition this design is nearby all; however, near then, empty may appendage them to what has been done. Go wool-gathering is why blush is momentous program; twosome meander helps you swell way.A dimension to program pushed you effect an depart from hindrance top. simple well-planned intake plan, you kawa body; span http://www.drewnogrod.pl - homepage stage desire.An petra24 would abominate an gain hassle-free together with system. Discharge would relevant tone. Redness would wind up this upset program participant.The estimable program is digress you be proper of your realize you want. You don't serene endeavour gym as you tush regimens wynajem wózków manuloc.pl home. duplicate time, assembly you won't dek-all.pl disruptive.An ass you involving massage program. predominating issues exposed to program are between plateaus. odloty program is rosiness offers tips crushing these several issues.One a difficulty is round they www.manuloc.pl their faultless http://www.styroplast.pl/sklep - styrodur walk they are apropos workout. persuade they warm up is lose concentration they venture 'wing it' profit injuring themselves.If you regard gets superior results, what you brawniness is adjacent to slow, shallow them correctly you'll about faster than division who rush, you'll refrain from injury. This is generate here, it's A-okay you approximately for life. I've fit http://farm9.staticflickr.com/8461/8046424211_cfc276c25f_z.jpg capability secrets for you below, enjoy!

Имя *:
Email *:
Код *:
Поиск
Форма входа
Наш опрос
Чего Вам не хватает на сайте?
Всего ответов: 21
Друзья сайта
Статистика
Возраст