0

Recently I posted on Hight Charts where I did like to create dynamic charts based on Razor view loop. Here's the link - Dynamic Chart

I tried one of the solution provided by a SO user as follows:

<script>
async function createChart(containerName, dryArgument, operatingArgument){
  let dryData = await fech(dryArgument)
  let operatingData = await fech(operatingArgument)
  Highcharts.chart(containerName, {
      chart: {
          type: 'column'
      },
      title: {
          text: 'Monthly Average Rainfall'
      },
      subtitle: {
          text: 'Source: WorldClimate.com'
      },
      xAxis: {
          categories: [
              'Jan',
              'Feb',
              'Mar',
              'Apr',
              'May',
              'Jun',
              'Jul',
              'Aug',
              'Sep',
              'Oct',
              'Nov',
              'Dec'
          ],
          crosshair: true
      },
      yAxis: {
          min: 0,
          title: {
              text: 'Rainfall (mm)'
          }
      },
      tooltip: {
          headerFormat: '<span style="font-size:10px">{point.key}</span><table>',
          pointFormat: '<tr><td style="color:{series.color};padding:0">{series.name}: </td>' +
              '<td style="padding:0"><b>{point.y:.1f} mm</b></td></tr>',
          footerFormat: '</table>',
          shared: true,
          useHTML: true
      },
      plotOptions: {
          column: {
              pointPadding: 0.2,
              borderWidth: 0
          }
      },
      series: [
        {
            name: 'Dry',
            data: JSON.parse(dryData)

        }, {
            name: 'Operating',
            data: JSON.parse(operatingData)

        }]
  });
}
</script>

In the front-end, used this:

<div class="container-fluid">
    <div class="row">
        <div class="col-sm-12 col-lg-12 col-md-12 col-xs-12">
            //Dynamic Chart - Starts
             @if (Model.aLstTopsideModuleGroupBy.ToList().Count > 0)
                 {
                     foreach (var item in Model.aLstTopsideModuleGroupBy)
                     {
                      foreach (var item2 in item)
                      {
                          int i = 0;
                     
                            <div id="container@i"></div>
                            <p class="highcharts-description">

                            </p>
                          
                          <script>
                            window.onload = function () {
                                createChart('#container@i',@item2.BaseDry,@item2.BaseOp);
                            };
                        </script>

                        i++;
                      }

                     }
                 }
                 //Dynamic Chart - Ends 
        </div>
    </div>
</div>

I am not sure if this is the correct way to do it, but got the following exception while trying:

Uncaught SyntaxError: missing ) after argument list

Is there any way to resolve the exception? I know, am doing something doing wrong here, any idea or suggestion would be appreciated.

Update 1: Exception

user8512043
  • 1,043
  • 12
  • 20
  • 2
    In your browser, if you hit F12 the console should show you where the error is in the rendered page. We need that info. – rene Feb 04 '23 at 19:29
  • They'll be an error somewhere that means it doesn't recognise your `)` - open page, view source, copy the *rendered* html+js into an IDE that does syntax highlighting. – freedomn-m Feb 05 '23 at 00:28
  • @rene see my updated post. Added a screenshot that's completely blank. – user8512043 Feb 05 '23 at 05:06
  • As you send strings to this function: `createChart('#container@i',@item2.BaseDry,@item2.BaseOp);` I expect that needs to be `createChart('#container@i','@item2.BaseDry','@item2.BaseOp');` – rene Feb 05 '23 at 07:16
  • This worked but no charts generated @rene. Do you have any idea or suggestion on this? – user8512043 Feb 05 '23 at 17:21
  • If you have nothing more then "doesn't work" then debugging is hard and we're left with guessing. Check the network tab of the developer console in the browser and see if those two `fetch` statements are called and return the data you expect. If that works, then go to codepen and recreate the Highcharts logic and html there and see if that works, then make adjustments in your actual markup. – rene Feb 05 '23 at 17:41
  • Can you please show me an example of dynamic charts using js (highchart preferable) and then with razor group by bind those data to js function that will create dynamic charts? @rene. – user8512043 Feb 05 '23 at 19:08

1 Answers1

1

You don't have your Java Script correctly set up.

First of all, fetch() does return a promise that will give you a response object once fulfilled. That response object has json() function returning a promise that will return the json as JavaScript object once fulfilled. Promises are best awaited. The start of your createChart function should look this:

async function createChart(containerName, dryArgument, operatingArgument){
  let dryData = await fetch(dryArgument) /* note you have a typo in your question */
  let dryJson = await dryData.json();
  let operatingData = await fetch(operatingArgument)
  let operatingJson = await operatingData.json();
  /* rest of code here */

In the series setup of HighCharts you now need to make these changes:

series: [
    {
        name: 'Dry',
        data: dryJson
    }, {
        name: 'Operating',
        data: operatingJson

    }]

This does assume that dryJson and operatingJson are single dimension javascript arrays with numbers in it (so [1,2,3] will work, ['1', '2', '3'] doesn't nor does {items:[{score:1}]}.

The exact setup in the Razor page is a task I leave at you, it shouldn't be that hard to verify if the outcome of the rendered page matches the actual need.

For testing purposes I created stack snippet where I use posts and users from the Stack API as Json sources. As those are a slightly different shape you see a map over its items array to get the desired array of numbers:

async function createChart(containerName, dryArgument, operatingArgument){
  let dryData = await fetch(dryArgument)
  let dryJson = await dryData.json();
  let operatingData = await fetch(operatingArgument)
  let operatingJson = await operatingData.json();
  Highcharts.chart(containerName, {
      chart: {
          type: 'column'
      },
      title: {
          text: 'Monthly Average Rainfall'
      },
      subtitle: {
          text: 'Source: WorldClimate.com'
      },
      xAxis: {
          categories: [
              'Jan',
              'Feb',
              'Mar',
              'Apr',
              'May',
              'Jun',
              'Jul',
              'Aug',
              'Sep',
              'Oct',
              'Nov',
              'Dec'
          ],
          crosshair: true
      },
      yAxis: {
          min: 0,
          title: {
              text: 'Rainfall (mm)'
          }
      },
      tooltip: {
          headerFormat: '<span style="font-size:10px">{point.key}</span><table>',
          pointFormat: '<tr><td style="color:{series.color};padding:0">{series.name}: </td>' +
              '<td style="padding:0"><b>{point.y:.1f} mm</b></td></tr>',
          footerFormat: '</table>',
          shared: true,
          useHTML: true
      },
      plotOptions: {
          column: {
              pointPadding: 0.2,
              borderWidth: 0
          }
      },
      series: [
        {
            name: 'Dry',
            data: dryJson.items.map(i => i.score)
        }, {
            name: 'Operating',
            data: operatingJson.items.map(i => i.reputation / 100)

        }]
  });
}

async function start() {
  var key = '1*tsYg4Q3UbK06qftc8VmQ(('
  await createChart('container1', 'https://api.stackexchange.com/2.3/posts?order=desc&sort=votes&pagesize=12&site=stackoverflow&key='+key, 'https://api.stackexchange.com/2.3/users?order=desc&sort=reputation&pagesize=12&site=stackoverflow&key='+key)
}

start()
<script src="https://cdnjs.cloudflare.com/ajax/libs/highcharts/10.3.3/highcharts.js"></script>
<div id="container1">
 loading ...
</div>
rene
  • 41,474
  • 78
  • 114
  • 152