Dynamic Chart Rendering in Razor View - javascript

I've data grouping in C# and trying to bind it from Razor view as follows with high charts:
//Dynamic Chart - Starts
#if (Model.aLstTopsideModuleGroupBy.ToList().Count > 0)
{
foreach (var item in Model.aLstTopsideModuleGroupBy)
{
foreach (var item2 in item)
{
int i = 0;
<text>
Highcharts.chart('container'#i, {
chart: {
type: 'column'
},
title: {
text: 'Demo Chart'
},
subtitle: {
text: ''
},
xAxis: {
categories: [
'Structural Primary',
'Structural Secondary',
'Mechanical',
'Piping',
'Electrical',
'Instrument',
'Telecommunication',
'Safety',
'Architectural ',
'Other/ Future Load ',
'Live Load'
],
crosshair: true
},
yAxis: {
min: 0,
title: {
text: 'Weight Data'
}
},
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}</b></td></tr>',
footerFormat: '</table>',
shared: true,
useHTML: true
},
plotOptions: {
column: {
pointPadding: 0,
borderWidth: 0
}
},
series: [
{
name: 'Dry',
data: '#item2.BaseDry'
}, {
name: 'Operating',
data: '#item2.BaseOp'
}]
});
</text>
i++;
}
}
}
//Dynamic Chart - Ends
The data grouping is something as follows:
Data 1
1, 2, 3, 4, 5
Data 2
1, 2, 3, 4, 5
The above I require to create two different charts depending upon the data set, that's why used the followg:
Highcharts.chart('container'#i, {});
In the frontend, trying to do the following:
<div class="container-fluid">
<div class="row">
<div class="col-sm-12 col-lg-12 col-md-12 col-xs-12">
#if (Model.aLstTopsideModuleGroupBy.ToList().Count > 0)
{
int i = 0;
foreach (var item in Model.aLstTopsideModuleGroupBy)
{
<div id="container" #i></div>
<p class="highcharts-description">
</p>
}
i++;
}
</div>
</div>
</div>
In the browser's inspect element, getting this exception:
Uncaught SyntaxError: missing ) after argument list
I was trying to follow this link but failed - Razor With JavaScript
Is there any way I can make the chart dynamic with Razor view rather Ajax call? This is what I am trying to implement:
High Charts

When using razon and javascript you need to be mindful that you can't really generate javascript code using razor. To the best of my knowledge you need to create a javascript function in the same view or a parent view if you are using a partial that creates the charts and have razor call it along with creating the div placeholder to display the chart, the data on the chart should be loaded via ajax calls.
The following code is an example and should not be copy and pasted without modification, you need to tweak it for your requirements, this is only to show the concept. If anyone else has a more elegant solution, please contribute.
async function createChart(containerName, dryArgument, operatingArgument){
let dryData = await fech(`#Url.Action("GetDryData")/?argument=${dryArgument}`)
let operatingData = await fech(`#Url.Action("GetOperatingData")/?argument=${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)
}]
});
}
Note that you need to create two ContenResult() actions in the controller to get the data.
To call them you can then use:
<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>

Related

Create multi bar/ muli series highchart in laravel

I want to make a chart with multi series/ multi data with highcharts in laravel, but I always fails, this is my expectations
enter image description here
Tokyo, London, etc. there are replaced with the name of my product category
this is my controller:
<?php
namespace App\Http\Controllers;
use App\Models\Category;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use PHPUnit\TextUI\XmlConfiguration\Group;
class DashboardController extends Controller
{
public function index()
{
$category = Category::select('name')->pluck("name");
$total = Category::select(DB::raw("SUM(total) as total"))->GroupBy(DB::raw('MONTH(created_at)'))->pluck('total');
$bulan = Category::select(DB::raw("MONTHNAME(created_at) as bulan"))->GroupBy(DB::raw('bulan'))->pluck('bulan');
return view('admin.dashboard', compact('category', 'total', 'bulan'));
}
}
and this is html and javacript code
#section('content')
<h1 class="gray">Dashboard</h1>
<figure class="highcharts-figure">
<div id="container"></div>
<p class="highcharts-description">
A basic column chart compares rainfall values between four cities.
Tokyo has the overall highest amount of rainfall, followed by New York.
The chart is making use of the axis crosshair feature, to highlight
months as they are hovered over.
</p>
</figure>
#section('javascript')
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script src="https://code.highcharts.com/modules/export-data.js"></script>
<script src="https://code.highcharts.com/modules/accessibility.js"></script>
<script type="text/javascript">
let category = <?php echo json_encode($category) ?>;
let total = <?php echo json_encode($total) ?>;
let month = <?php echo json_encode($month) ?>;
console.log(category, total, month);
Highcharts.chart('container', {
chart: {
type: 'column'
},
title: {
text: 'Monthly Average Rainfall'
},
subtitle: {
text: 'Source: WorldClimate.com'
},
xAxis: {
// categories: ["Jan", "Feb", "Mar", "Apr", "Mei", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
caegories : month,
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: category,
data: total
}]
});
</script>
#endsection
#endsection
and this is the result I get enter image description here
instead pluck it one by one just use one variable and setup query in it and parse it in the javascript :
so first one is set some query:
<?php
namespace App\Http\Controllers;
use App\Models\Category;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use PHPUnit\TextUI\XmlConfiguration\Group;
class DashboardController extends Controller
{
public function index()
{
$category = Category::select(
DB::raw("MONTHNAME(created_at) as bulan"),
DB::raw("SUM(total) as total1"),
DB::raw("SUM(total) as total2"),
DB::raw("SUM(total) as total3"),
)->groupBy('bulan')->get();
return view('admin.dashboard', compact('category'));
}
}
for the javascript do this :
Highcharts.chart('container', {
chart: {
type: 'column'
},
title: {
text: 'Monthly Average Rainfall'
},
subtitle: {
text: 'Source: WorldClimate.com'
},
xAxis: {
categories: [
#php
foreach($category as $categories){
echo "'$categories->bulan',";
}
#endphp
],
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: 'Total1',
data: [ #php
foreach($category as $categories){
echo "'$categories->total1',";
}
#endphp]
}, {
name: 'Total2',
data: [ #php
foreach($category as $categories){
echo "'$categories->total2',";
}
#endphp]
}, {
name: 'total3',
data: [ #php
foreach($category as $categories){
echo "'$categories->total3',";
}
#endphp]
}]
});
the point is just parse the query with foreach in each properties like this:
[ #php
foreach($category as $categories){
echo "'$categories->total1',";
}
#endphp]
Hope it helps i'm from indonesia also wkwk

How to dynamically remove the whole Column from a single series HighCharts column graph?

This is example for the simple column chart
$("#container").highcharts({
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: 'Tokyo',
data: [49.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
}]
});
I'm dynamically adding columns (points) like this
var chart = $("#container").highcharts();
chart.series[0].addPoint(["abc", 100]]);
So now I have to remove a column from the chart. I have dynamically added points by their names. So when I remove any particular added series name I need to remove that column from the chart.
When I add a new column (point) I create a button with its name with an 'x' mark so clicking that 'x' mark should remove that particular column from the chart. So all I have is its category name by which I need to remove it.
So I need to dynamically remove the column from the chart. Since it is all just a single series. I want the category to be removed with its respective data value. I'm not sure how to do that!
For example in the chart above I want to specifically remove 'Oct' from categories and its respective value from data '194.1'. And I just have its category value ('Oct'). Is that possible ?
I can't use this - chart.series[0].data[9].remove() because I don't know which index i'll have to remove since I only have its category value 'Oct'. Also it just removes the point from the chart and not the column as a whole (including its respective category value and reshifting the graph).
Does anyone know how I can do this?
You can create a function which filters your data and your categories and updated your chart.
Example:
function removeCategoryAndData (chart, categoryName) {
const { categories } = chart.xAxis[0]
const categoryIndex = categories.indexOf(categoryName)
const { data } = chart.series[0]
// Filter data and categories
const filteredData = data.map((p) => p.y).filter((v, i) => i !== categoryIndex)
const filterdCategories = categories.filter((v, i) => i !== categoryIndex)
// Update chart with filtered data and categories
chart.update({ xAxis: { categories: filterdCategories }, series: { data: filteredData } })
}
Live example:
https://jsfiddle.net/yy9bhvq2/

How to fetch json array data into highcharts in angularjs

I want to display a bar graph using highcharts.I am devoloping an app in play framework(play-java),in which I return a response from the java api which contains data in json format.It contains a field 'name' which contains data like 'Data','Gadgets','Others' etc.I want the x axis of the chart to take these values from json array which gets returned in response.
Here is the code for the response in .js
for(var i=0;i<response.data.result.length;i++)
{
$scope.total=$scope.total+parseInt(response.data.result[i].item_price);
}
var j=0;
console.log(response.data.result);
while(j<response.data.result.length)
{
$scope.jsonArray=[{
name:response.data.result[j].category_name,
y: (parseInt(response.data.result[j].item_price)/$scope.total)*100,
}]
$scope.renderChart();
}
The code for bar graph
$scope.renderChart = function()
{
Highcharts.chart('container', {
chart: {
type: 'column'
},
title: {
text: 'Your Expenses'
},
subtitle: {
text: 'Your total spent money is '+$scope.total+'.'
},
xAxis: {
type: 'category'
},
yAxis: {
title: {
text: 'Money spent in percentage'
}
},
legend: {
enabled: false
},
credits: {
enabled: false
},
plotOptions: {
series: {
borderWidth: 0,
dataLabels: {
enabled: true,
format: '{point.y:.1f}%'
}
}
},
tooltip: {
headerFormat: '<span style="font-size:11px">{series.name}</span><br>',
pointFormat: '<span style="color:{point.color}">{point.name}</span>: <b>{point.y:.2f}%</b> of total<br/>'
},
series: [{
name: 'Categories',
colorByPoint: true,
data:$scope.jsonArray
}]
});
}
I know that I can't use the while loop in the response code mentioned.That's where i am looking help for.The y axis should calculate the percentage value .I want to generate 'names' for x axis and percentage for y axis of the chart.Thanks in advance..
All we have to do is to just initialize the jsonArray as empty before doing the looping.Add a for loop so that it iterates through the array and assigns the values appropriately.
The changed code
$scope.jsonArray = [];
for(var i=0;i<response.data.result.length;i++)
{
$scope.jsonArray[i]={
name:response.data.result[i].category_name,
y: (parseInt(response.data.result[i].item_price)/$scope.total)*100,
}
$scope.renderChart();
console.log(response.data.result[i]);
}
console.log($scope.jsonArray);
})
Anyway thanks....

Creating graph on webpage using Highcharts

I need to create a bargraph on my webpage using Highcharts. I am using the following code but nothing is displayed. I am new to scripting webpages so I am not sure what is wrong.
<div id="container1" style="width:100%; height:400px;"></div>
function create_graph(graph) {
chart = new Highcharts.Chart ({
chart: {
height: 600,
width: 1200,
renderTo: container1,
type: 'column'
//reflow: false
},
title: {
text: graph["graphTitle"]
},
xAxis: {
categories: graph["xAxisLabels"]
},
yAxis: {
min: 0,
title: {
text: graph["yaxisTitle"]
}
},
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}</b></td></tr>',
footerFormat: '</table>',
shared: true,
useHTML: true
},
plotOptions: {
column: {
pointPadding: 0.2,
borderWidth: 0
}
},
series: generateLineData(graph)
});
}
graph = {"graphTitle": "Title" ,"xAxisLabels" : xAxisLabels, "xAxisTitle" : "Properties", "yAxisTitle" : "Average percentile", "yAxisValues" : array1}
You must have the javascript vars xAxisLabels , array1 initialized before creating object graph. Then, of course, following the logic of your code, you should have a call to create_graph(graph);. Finally, your generateLineData() function should look like the following:
function generateLineData(g) {
return [{ data: g["yAxisValues"] }];
}
if all these premises are fulfilled, then your graph should be displayed. You can verify it at this jsfiddle demo: http://jsfiddle.net/tgnu5941/2/

Highcharts with dynamic data $http.post angular js

$http.post(galileoServer + "actions.php", {
"action": "get-attendance-graph",
"user": window.localStorage.getItem("username")
}).success(function(result){
//console.log(result)
busyIndicator("hide");
$('#attendance-graph').highcharts({
credits: 0,
tooltip:{
enabled: false
},
chart: {
type: 'bar'
},
title: {
text: '',
style: {
display: "none"
}
},
xAxis: {
categories: ['June', 'July', 'Aug', 'Sept', 'Oct', 'Nov', 'Dec', 'Jan', 'Feb', 'Mar', 'Apr', 'May']
},
yAxis: {
min: 0,
title: {
text: 'No. of days'
},
gridLineWidth: 0,
minorGridLineWidth: 0,
labels: { //to disable points displayed
enabled: false
}
},
legend: {
reversed: true
},
plotOptions: {
series: {
stacking: 'normal',
dataLabels: {
enabled: true,
color: (Highcharts.theme && Highcharts.theme.dataLabelsColor) || 'white',
formatter: function() { //function to avoid displaying zero values
if (this.y != 0) {
return this.y;
} else {
return null;
}
}
/*style: {
textShadow: '0 0 3px black, 0 0 3px black'
}*/
}
}
},
series: [{
name: 'Absent',
data: [result.absentData]
}, {
name: 'Present',
data: [result.presentData]
}]
});
}).error(function(result, status){
alert(status + "\nCouldn't connect to Galileo server due to network problem")
});
I am trying to load the data via ajax but the graph doesn't gets loaded the graph loaded is blank.
The coding snippet is provided.
I also tried with the getJSON part, but it also didn't worked.
Kindly let me know the solution, as I'm unable to get the graph since last two days.
The console output is {"absentData":"0,0,2,0,0,1,0,0,0,0,0,0","presentData":"30,31,29,30,31,29,31,31,28,31,30,31"}
Your json is not properly formed for Highcharts. You want an array of numbers, what you are giving it is an array of one element a string:
data: ["0,0,2,0,0,1,0,0,0,0,0,0"] // an array of a single string...
It's better that you fix this in your PHP code. You'll need to build a php array of ints (do not build a concatenated string) and then use json_encode.
If you can't fix it in the PHP, you could do something like:
data: $.parseJSON("["+result.absentData+"]")
but this is somewhat ugly.

Categories

Resources