Reputation: 1157
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
Upvotes: 0
Views: 130
Reputation: 42453
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>
Upvotes: 1