ASE Home Page Products Download Purchase Support About ASE
ChartDirector Support
Forum HomeForum Home   SearchSearch

Message ListMessage List     Post MessagePost Message

  MVC 4 C# Razor engine
Posted by Arif on Feb-29-2016 19:16
Hi

I am trying to convert a webform which is based on ASP.Net to MVC 4 C# using Razor engine. I am now sure how I can use the below function in my Controller to use Chart Viewer.

Function is -

protected override void OnInit(EventArgs e)
        {
            WebChartViewer.OnPageInit(this);
        }

Please help me how I can use the above code in MVC 4 C# Controller.

Thanks

  Re: MVC 4 C# Razor engine
Posted by Peter Kwan on Mar-01-2016 03:14
Hi Arif,

From my understanding, the Razor engine does not support Web Form controls. To use ChartDirector in Razor, you may use it without using the Web Form controls. There is a simple example at:

http://www.chartdir.com/forum/download_thread.php?bn=chartdir_support&thread=1371626049#N1371708944

The following is a more complicated example showing the "Interactive Financial Chart" with Razor.

http://www.chartdir.com/forum/download_thread.php?bn=chartdir_support&thread=1435322452#N1435680126

Hope this can help.

Regards
Peter Kwan

  Re: MVC 4 C# Razor engine
Posted by Arif on Mar-01-2016 15:59
Hi Peter

Thanks for your reply. The link is not useful what I am trying to do. I have done everything except 'WebChartViewer.OnPageInit(this);'. I like to use this code in controller but did not find anyway to use this.

Could you please let me know how I can use this like of code in controller.

Thanks

  Re: MVC 4 C# Razor engine
Posted by Peter Kwan on Mar-02-2016 00:45
Hi Arif,

Is it possible to clarify how you can create the WebChartViewer object in ASP.NET MVC Razor, or provide a simple example (such as by modifying the Simple Bar Chart" sample code), so I can test it? I think the WebChartViewer needs to be added to a System.Web.UI.Page object to work, but this object is only available in ASP.NET MVC with the Web Form view engine. I am not sure how I can set up an example in ASP.NET MVC with the Razor view engine for testing.

Regards
Peter Kwan

  Re: MVC 4 C# Razor engine
Posted by Arif on Mar-02-2016 02:09
Hi Perter

All the code I just copied from the aspx code behind file to a controller and did nota any error. Just having error on 'WebChartViewer.OnPageInit();'. I tried to use like 'WebChartViewer.OnPageInit(System.Web.UI.Page);' in controller but getting error 'Error 29 'System.Web.UI.Page' is a 'type', which is not valid in the given context'.

I am not using any code in the view (chtml file). Everything in controller. Later on I can add the function in ViewBag if 'OnPageInit' is solved. Hope it will help.

Thanks

  Re: MVC 4 C# Razor engine
Posted by Peter Kwan on Mar-03-2016 01:21
Hi Arif,

The issue you encounter is the reason why I would like to know how you can use Web Form controls in Razor.

To be useful, a Web Form Control (such as WebChartViewer) must be put on a Web Form. You can either just put it on a Web Form at design time, or you can dynamically create the control and insert it in the Web Form (or in another control on the Web Form), like (in ASP.NET code-behind):

    WebChartViewer v = new WebChartViewer();
    Page.Controls.Add(v);

From my understanding, the Razor page and the Controller does not have a Web Form. So I am wondering how you can use WebChartViewer in your code. If you are creating it dynamically (like using "new WebChartViewer()"), would you mind to clarify how can you insert it into a Web Form? If you do not insert in into Web Form, the Web Form control will not work anyway. This is equivalent to using null as the Page "WebChartViewer.OnPageInit(null);", which would compile but would crash when the code run.

If you can add the control to a Web Form, which means you have the Page object, and you can use that object in OnPageInit.

Regards
Peter Kwan

  Re: MVC 4 C# Razor engine
Posted by Arif on Mar-04-2016 02:05
Hi Peter

All the value coming from dynamically. I tried the code you provided and doesn't work. Because I am using MVC C# Razor engine and don't support 'Page' property. How you think we can use this in Controller and View page.

Thanks

  Re: MVC 4 C# Razor engine
Posted by Peter Kwan on Mar-04-2016 05:09
Hi Arif,

You mentioned that you have tried the code provided but it didn't work. I am not too sure which code you are referring to. The code in my last message is the code to be used in a Web Form:

    WebChartViewer v = new WebChartViewer();
    Page.Controls.Add(v)

It is not the code I suggested in Razor. I am just trying to understand how you can put the WebChartViewer to the Razor without the Page object, as I think Razor does not have the Page object.

That is the reason why the earlier I suggested the code below. Note that the code below uses a subdirectory "/tmpcharts". Please make sure that subdirectory is created in your project and is readable and writable by the web server.

========================================

@{
  // The data for the line chart
  double[] data = {30, 28, 40, 55, 75, 68, 54, 60, 50, 62, 75, 65, 75, 91, 60, 55,
        53, 35, 50, 66, 56, 48, 52, 65, 62};

  // The labels for the line chart
  string[] labels = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11",
        "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24"}
      ;

  // Create a XYChart object of size 250 x 250 pixels
  ChartDirector.XYChart c = new ChartDirector.XYChart(250, 250);

  // Set the plotarea at (30, 20) and of size 200 x 200 pixels
  c.setPlotArea(30, 20, 200, 200);

  // Add a line chart layer using the given data
  c.addLineLayer(data);

  // Set the labels on the x axis.
  c.xAxis().setLabels(labels);

  // Display 1 out of 3 labels on the x-axis.
  c.xAxis().setLabelStep(3);

  string filename = c.makeTmpFile(Server.MapPath("/tmpcharts"));
  string url = "/tmpcharts/" + filename;

  // output the chart
  string imageMap = c.getHTMLImageMap("", "", "title='Hour {xLabel}: Traffic {value} GBytes'");
}

<img src="@url" usemap="#map1" border="0" /><map name="map1">@Html.Raw(imageMap)</map>

==========================================


The above code is just an example. You can freely move the code to the Controller if your like or to use dynamic data. In the simplest case, instead of using:

  double[] data = {30, 28, 40, 55, 75, 68, 54, 60, 50, 62, 75, 65, 75, 91, 60, 55,
        53, 35, 50, 66, 56, 48, 52, 65, 62};

You can use

  double[] data = ViewBag.Data;

where ViewBag.Data is created from your controller.

You can move all the code to the controller if you like:

  // The data for the line chart
  double[] data = {30, 28, 40, 55, 75, 68, 54, 60, 50, 62, 75, 65, 75, 91, 60, 55,
        53, 35, 50, 66, 56, 48, 52, 65, 62};

  // The labels for the line chart
  string[] labels = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11",
        "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24"}
      ;

  // Create a XYChart object of size 250 x 250 pixels
  ChartDirector.XYChart c = new ChartDirector.XYChart(250, 250);

  // Set the plotarea at (30, 20) and of size 200 x 200 pixels
  c.setPlotArea(30, 20, 200, 200);

  // Add a line chart layer using the given data
  c.addLineLayer(data);

  // Set the labels on the x axis.
  c.xAxis().setLabels(labels);

  // Display 1 out of 3 labels on the x-axis.
  c.xAxis().setLabelStep(3);

  string filename = c.makeTmpFile(Server.MapPath("/tmpcharts"));
  ViewBag.Url = "/tmpcharts/" + filename;

  // output the chart
  ViewBag.ImageMap = c.getHTMLImageMap("", "", "title='Hour {xLabel}: Traffic {value} GBytes'");


Then in the Razor page, you can use the same <IMG> tag, except to change the local variable into the ViewBag variable:


<img src="@ViewBag.Url" usemap="#map1" border="0" /><map name="map1">@Html.Raw(ViewBage.ImageMap)</map>


Hope this can help.

Regards
Peter Kwan

  Re: MVC 4 C# Razor engine
Posted by Peter Kwan on Mar-04-2016 05:10
Hi Arif,

I have just discovered a typo in my last message. The code:

ViewBage.ImageMap

should be:

ViewBag.ImageMap

Regards
Peter Kwan

  Re: MVC 4 C# Razor engine
Posted by Arif on Mar-04-2016 16:44
Hi Peter

Thanks for your reply. Like I said we are adding dynamically. Now problem I am facing when converting to MVC C# Razor is code behind and aspx web form. I like to use code behind similar code in controller and aspx in view on MVC.

My code behind code currently is -

protected override void OnInit(EventArgs e)
        {
            WebChartViewer.OnPageInit(this);
        }


protected void RptDataBnd(object sender, RepeaterItemEventArgs e)
        {
            if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
            {
                WebChartViewer wv = e.Item.FindControl("wvg") as WebChartViewer;
                wv.Image = _lt.WebImage; //_lt getting value dynamically
                wv.Visible = (wv.Image != null) ? true : false;
           }
      }

In aspx page (inside a Repeater controller) -
<chart:webchartviewer id="wvg" runat="server" />

This is the code now I need to use in MVC controller and view. I think it is giving you clear idea where I am getting problem.

Thanks in advance

  Re: MVC 4 C# Razor engine
Posted by Peter Kwan on Mar-05-2016 04:27
Hi Arif,

From my understanding, there is no repeater control (which is a Web Form control) in Razor. I am not sure how you are porting the reporter control to Razor. This will affect how you port the charting code.

One common method to port the repeater code is to use a loop in the Razor page to generate the tags in the table, where the data come from an array. If you are using this method, that means the charts are stored in an array.

The WebImage is to be used for Web Form controls. For Razor, you can simply store the URLs. An example is like:

ViewBag.arrayOfURLs = new string[number_of_rows];
for (int i = 0; i < number_of_rows; ++i)
{
   //..... create the charts .....

   string filename = c.makeTmpFile(Server.MapPath("/tmpcharts"));
   ViewBag.arrayOfURLs[i] = "/tmpcharts/" + filename;
}

In the Razor page, you can then use a loop to create the <IMG> tags with  ViewBag.arrayOfURLs[i] as the URL.

Note that the above is just an example which assumes you use the looping method handle the repeater control. You can adjust it to fit the acutal method you are using to handle the repeater control. In brief, you can create the charts you need in the controller as URLs (instead of as WebImage), and use them in the Razor page in <IMG> tags.

Hope this can help.

Regards
Peter Kwan

  Re: MVC 4 C# Razor engine
Posted by Arif on Mar-08-2016 01:11
Hi Peter

For testing purposes, as you said in your early reply, I have created a folder which is called tmpcharts inside the project and given full permission. Than added the below code into the Controller -

// The data for the line chart
            double[] data = {30, 28, 40, 55, 75, 68, 54, 60, 50, 62, 75, 65, 75, 91, 60, 55,
        53, 35, 50, 66, 56, 48, 52, 65, 62};

            // The labels for the line chart
            string[] labels = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11",
        "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24"}
                ;

            // Create a XYChart object of size 250 x 250 pixels
            ChartDirector.XYChart c = new ChartDirector.XYChart(250, 250);

            // Set the plotarea at (30, 20) and of size 200 x 200 pixels
            c.setPlotArea(30, 20, 200, 200);

            // Add a line chart layer using the given data
            c.addLineLayer(data);

            // Set the labels on the x axis.
            c.xAxis().setLabels(labels);

            // Display 1 out of 3 labels on the x-axis.
            c.xAxis().setLabelStep(3);

            string filename = c.makeTmpFile(Server.MapPath("/tmpcharts"));
            ViewBag.Url = "/tmpcharts/" + filename;

            // output the chart
            ViewBag.ImageMap = c.getHTMLImageMap("", "", "title='Hour {xLabel}: Traffic {value} GBytes'");

Added in View page below code -
<img src="@ViewBag.Url" usemap="#map1" border="0" /><map name="map1">@Html.Raw(ViewBag.ImageMap)</map>

When I run the project, it didn't load anything, but after sometimes its crushed. Could you please look the code, where it's getting problem.

Thanks

  Re: MVC 4 C# Razor engine
Posted by Arif on Mar-08-2016 01:19
Hi Peter

Please ignore my early reply, it is working. I added the temp folder in wrong place, this needed to be in the root folder. It is working now. Now I will try to connect the data dynamically and let you know the outcomes.

Thanks

  Re: MVC 4 C# Razor engine
Posted by Arif on Mar-08-2016 18:47
Hi Peter

I have another function where I am getting a chart, how can I use the same chart in MVC with C# Razor engine. This function has a return type and used inside another class not in the controller. I need to call this function in my controller and view page. My code is

public WebImage ChartNP()
        {
            WebImage opChartNP = null;
            prtQL rr = _li[0]; // I am getting value here

            XYChart c = new XYChart(1400, 400);


            ChartDirector.TextBox title = "test";

            double[] data = rr.GetData(); // I am getting value here
            string[] labels = rr.GetLabel(); // I am getting value here

            c.setPlotArea(500, 65, 450, 300, 0xffffff);

             c.swapXY();

            BarLayer barLayer = c.addBarLayer3(data);
            barLayer.set3D(10);
            barLayer.setBarShape(Chart.CircleShape);

            c.xAxis().setLabels(labels).setTruncate(300);

            c.xAxis().setReverse();

            c.xAxis().setTickOffset(0.5);

            c.syncYAxis();

            c.xAxis().setLabelStyle("Verdana", 8, 0x606060);
            c.yAxis().setLabelStyle("Verdana", 8, 0x606060);
            c.yAxis2().setLabelStyle("Verdana", 8, 0x606060);

            c.yAxis().setLabelFormat("{value}");
            c.yAxis2().setLabelFormat("{value}");

            c.yAxis().setMinTickInc(1);
            c.yAxis2().setMinTickInc(1);

            c.yAxis().setLabelStep(1, 1);
            c.yAxis2().setLabelStep(1, 1);

            // Output the chart
            opChartNP = c.makeWebImage(Chart.PNG);
            return opChartNP;
        }

Thanks in advance

  Re: MVC 4 C# Razor engine
Posted by Peter Kwan on Mar-09-2016 02:17
Hi Arif,

I suggest to modify you function to return a chart, not the WebImage, which is for Web Form Controls only. For example:


public BaseChart ChartNP()
{
    .....
    XYChart c = new XYChart(1400, 400);

    return c;
}


Then in the controller, you can use the same code as mentioned in my last message:


BaseChart c = ChartNP();

string filename = c.makeTmpFile(Server.MapPath("/tmpcharts"));
ViewBag.Url = "/tmpcharts/" + filename;

Hope this can help.

Regards
Peter Kwan

  Re: MVC 4 C# Razor engine
Posted by Arif on Mar-12-2016 00:38
Hi Peter

The code you provided above, is worked. Many thanks for your assistance.

  Re: MVC 4 C# Razor engine
Posted by Arif on Mar-22-2016 22:54
Hi Peter

Now I am facing another problem. I am generating some charts inside a loop. When I have checked the temp folder, I can see the 3/4 charts are created but it did not displaying any chart on the view. But when I am running outside the loop, it is displaying one chart. Could you please let me know where I am getting wrong.

Thanks

Arif

  Re: MVC 4 C# Razor engine
Posted by Arif on Mar-22-2016 23:02
In controller -

                        prtList strAll = new prtList();
                        strAll = dr.Value;
                        BaseChart crtAll = strAll.GetAllCharts();
                        string filename = crtAll.makeTmpFile(Server.MapPath("/tmpcharts"));
                        ViewBag.Url = "/tmpcharts/" + filename;
                        // output the chart
                        ViewBag.ImageMap = crtAll.getHTMLImageMap("", "", "title='Hour {xLabel}: Traffic {value} GBytes'");

In View -

<img src="@ViewBag.Url" usemap="#map3" border="0" /><map name="map3">@Html.Raw(ViewBag.ImageMapall)</map>

  Re: MVC 4 C# Razor engine
Posted by Arif on Mar-23-2016 02:02
My type mistake on view [@Html.Raw(ViewBag.ImageMap)]

Thanks

  Re: MVC 4 C# Razor engine
Posted by Peter Kwan on Mar-23-2016 03:32
Hi Arif,

From your code, I can only see one chart. I am not too sure how you generate many charts.

If your code is like:

for (int i = 0; i < 4; ++i)   // or some other looping method
{
    BaseChart crtAll = strAll.GetAllCharts();
    string filename = crtAll.makeTmpFile(Server.MapPath("/tmpcharts"));
    ViewBag.Url = "/tmpcharts/" + filename;
    .....
}

then the above code only creates one chart for the view. You probably are aware that the code ViewBag.Url = "/tmpcharts/" + filename; means to overwrite the previous ViewBag.Url with the "/tmpcharts/" + filename. So everytime your code creates a new chart, the Url of the previous chart is overwritten, so there is only the Url of one chart.

If you need multiple charts, please do not overwrite the previous charts. An example is:

ViewBag.Url = new string[4];

for (int i = 0; i < 4; ++i)   // or some other looping method
{
    BaseChart crtAll = strAll.GetAllCharts();
    string filename = crtAll.makeTmpFile(Server.MapPath("/tmpcharts"));
    ViewBag.Url[i] = "/tmpcharts/" + filename;
    .....
}

With the above, the 4 charts Urls will be in ViewBag.Url[0], ViewBag.Url[1], ViewBag.Url[2] and ViewBag.Url[3].

To display 4 charts, you need 4 <img> tags, which is like:

@for(int i = 0; i < 4; i++) {
   <img src="@ViewBag.Url[i]" />
}

(Note: For simplicity, I have not included the image map code above. Please add them back by using an array similar to how the Urls are handled.)

Regards
Peter Kwan

  Re: MVC 4 C# Razor engine
Posted by Arif on Mar-23-2016 21:06
Hi Peter

I am trying to achieve what you explained in your previous post. I tried the below code but still getting the same image 3 times but in the temp folder, I can see 3 different charts. My controller is -

                ViewBag.Url = new string[3];
                ViewBag.ImageMap = new string[3];
                for (int i = 0; i < 3; ++i)
                {
                    prtList strAll = new prtList();
                    strAll = dr.Value;
                    BaseChart crtAll = strAll.GetAllCharts();
                    string filename = crtAll.makeTmpFile(Server.MapPath("/tmpcharts"));
                    ViewBag.Url[i] = "/tmpcharts/" + filename;
                    ViewBag.ImageMap[i] = crtAll.getHTMLImageMap("", "", "title='Hour {xLabel}: Traffic {value} GBytes'");
                }

View -
@for (int i = 0; i < 3; i++)
                {
                 <img src="@ViewBag.Url[i]" />@Html.Raw(ViewBag.ImageMap[i])
                }

Thanks in advance
Arif

  Re: MVC 4 C# Razor engine
Posted by Peter Kwan on Mar-23-2016 23:39
Hi Arif,

If you see 3 chart images in the temp folder, have you viewed them with Windows Paint or other viewer by double clicking on them, and are the chart images the same?

In your code, the charts are generated using:

   strAll = dr.Value;
   BaseChart crtAll = strAll.GetAllCharts();

My understanding is the strAll.GetAllCharts() only returns one single chart, because only one chart object is returned. If it returned multiple chart objects, then the return value should be an array of BaseChart, not just a BaseChart.

So in your code, the loop runs 3 times, and each time one single chart is returned. However, in your code, it seems dr.Value was not changed in the loop. Is it possible you are always using the same data in your loop, so all the charts generated in your loop are the same?

If you need further help, would you mind to clarify how your loop generates different charts, given that the dr.Value does not seem to change in the loop, and GetAllCharts only returns one single chart?

Regards
Peter Kwan

  Re: MVC 4 C# Razor engine
Posted by Arif on Mar-24-2016 01:52
Hi Peter

It was in the Basechart and I put this in a loop, now getting all the images. Many thanks for your assistance.

Regards

Arif