I try to create a graph using Chart.js and get the data from database, but I am confused how to pass the data to an array variable in view.
This is the Controller
public function ApiLaporanBulanan()
{
$data = DB::table("transaksipenjualan")->select(DB::raw('EXTRACT(MONTH FROM tanggaltransaksi) AS Bulan, SUM(total) as Pendapatan'))
->groupBy(DB::raw('EXTRACT(MONTH FROM tanggaltransaksi)'))
->get();
return response()->json($data);
//Accessing Data
dd($data[0]->Bulan);
}
This is the script in view
<script>
var url = "{{url('laporan/pendapatanAPI')}}";
var Bulan = [];
var Pendapatan = [];
$(document).ready(function(){
$.get(url, function(response){
response.forEach(function(data){
Bulan.push(data->Bulan);
Pendapatan.push(data->Pendapatan);
});
var ctx = document.getElementById("canvas").getContext('2d');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: Bulan,
datasets: [{
label: 'Nilai Pendapatan',
data: Pendapatan,
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
}
}
});
});
});
</script>
You can create two array in your controller.
$label = [];
$dataset = [];
and loop through your collection and push data to these arrays
foreach($data as $value){
$label[] = $value->data_field;
$dataset[] = $value->data_field;
}
And pass it to your blade and assign these array to your chart
...
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: Bulan,
datasets: [{
label: 'Nilai Pendapatan',// label data
data: Pendapatan, // dataset
borderWidth: 1
}]
},
....
Related
I am trying to draw a two-line chart with two datasets that share the same labels using chart.js on my ASP.NET MVC app.
I am only getting the data from "Value" plotted on the chart and not "Age" and I cannot find the reason why.
Relevant Controller code:
public ActionResult GetLineChartData()
{
List <LineChartData> dataForLineChart = new List <LineChartData> ();
dataForLineChart.Add(new LineChartData {
Date = DateTime.NOW, Value = 100, Age = 20
});
return Json(dataForLineChart, JsonRequestBehavior.AllowGet);
}
Relevant View code:
$.ajax({
type: "Post",
url: '#Url.Action("GetLineChartData", "Posts")',
contentType: false,
processData: false,
data: dataFromForm,
dataType: "json",
traditional: true,
success: function (data) {
console.log(data);
var labels = data.map(function (e) {
return e.Date;
});
var data = data.map(function (e) {
return e.Value;
});
var data2 = data.map(function (e) {
return e.Age;
});
var ctx = scatterChart.getContext('2d');
var config = {
type: 'line',
data: {
labels: labels,
datasets: [{
label: "Test"
data: data,
backgroundColor: 'rgba(0, 119, 204, 0.3)'
},
{
label: "Test",
data: data2,
backgroundColor: 'rgba(242, 204, 143, 1)'
}
]
}
};
}
});
(Some code I do not consider important is hidden)
Issue & Concern
Because the below line overwrites the original data value.
var data = data.map(function (e) {
return e.Value;
});
After the above line, now the data array was overwritten as an array of integers instead of an array of objects. Based on your sample response from API, the current value of data will be: [100].
var data2 = data.map(function (e) {
return e.Age;
});
From the above line, it can't find the Age property in the element. Hence the result of data2 will be: [undefined].
This is why the data2 is not rendered in the chart.
Solution
Create another variable for the data transformation to avoid overwriting the existing data value.
var dataset = data.map(function (e) {
return e.Value;
});
var dataset2 = data.map(function (e) {
return e.Age;
});
var config = {
type: 'line',
data: {
labels: labels,
datasets: [
{
label: 'Test',
data: dataset,
backgroundColor: 'rgba(0, 119, 204, 0.3)',
},
{
label: 'Test',
data: dataset2,
backgroundColor: 'rgba(242, 204, 143, 1)',
},
],
},
};
Demo # StackBlitz
I have managed to get a count of items in list by status, but cant seem to figure out how to add the data into Chart.js. I have tried referencing my dataset from within the chart but that does not seem to work. Any assistance would be greatly appreciated. I have pieced together some code to try to get this to work but cant seem to get this last piece. ps. This code is being used in content editor in SharePoint.
Thank you,
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<button onclick="GetListItems();" type="button">Get All List Items​</button>
<div>
<canvas id="myChart"></canvas>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
function GetListItems() {
var url = "https://contoso.sharepoint.com/sites/Mysite/_api/web/lists/getByTitle('Mylist')/items?$top=500";
$.ajax({
url: url,
type: "GET",
headers: {
"accept": "application/json; odata=verbose"
},
success: onSuccess
});
}
function onSuccess(data) {
var items = data.d.results;
const MyDataset = [];
var NewItems = items.filter(function(ItemStatus) {
return ItemStatus.Status == "New";
});
var InProcItems = items.filter(function(ItemStatus) {
return ItemStatus.Status == "In Process";
});
var CompItems = items.filter(function(ItemStatus) {
return ItemStatus.Status == "Completed";
});
MyDataset.push(NewItems.length);
MyDataset.push(InProcItems.length);
MyDataset.push(CompItems.length);
console.log(MyDataset);
}
const labels = ['New', 'Completed', 'Inproccess'];
const data = {
labels: labels,
datasets: [{
label: 'My First dataset',
backgroundColor: 'rgb(255, 99, 132)',
borderColor: 'rgb(255, 99, 132)',
data: [5, 5, 5, 2, 2, 30, 45],// use MyDataset here instead of random.
}]
};
const config = {
type: 'bar',
data: data,
options: {}
};
</script>
<script>
const myChart = new Chart(
document.getElementById('myChart'),
config
);
</script>
That should do what's you expect. I cannot test because data ajax call is not public.
<!-- External Lib -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<!-- HTML / Template -->
<button onclick="GetListItems();" type="button">Get All List Items​</button>
<div>
<canvas id="myChart"></canvas>
</div>
<!-- Javascript -->
<script>
function GetListItems() {
var url = "https://contoso.sharepoint.com/sites/Mysite/_api/web/lists/getByTitle('Mylist')/items?$top=500";
$.ajax({
url: url,
type: "GET",
headers: {
"accept": "application/json; odata=verbose"
},
success: onSuccess
});
}
function onSuccess(data) {
var items = data.d.results;
var MyDataset = [];
var NewItems = items.filter(function(ItemStatus) {
return ItemStatus.Status == "New";
});
var InProcItems = items.filter(function(ItemStatus) {
return ItemStatus.Status == "In Process";
});
var CompItems = items.filter(function(ItemStatus) {
return ItemStatus.Status == "Completed";
});
MyDataset.push(NewItems.length);
MyDataset.push(InProcItems.length);
MyDataset.push(CompItems.length);
console.log(MyDataset);
createChar(MyDataset);
}
function createChar(dataset) {
const labels = ['New', 'Inproccess', 'Completed'];
const data = {
labels: labels,
datasets: [{
label: 'My First dataset',
backgroundColor: 'rgb(255, 99, 132)',
borderColor: 'rgb(255, 99, 132)',
data:dataset
}]
};
const config = {
type: 'bar',
data: data,
options: {}
};
const myChart = new Chart(
document.getElementById('myChart'),
config
);
}
</script>
You specify 3 labels and provide 7 element in data.
To resolve your problem, try with a simple config
const config = {
type: 'bar',
labels: labels // Your array of label
data: {
datasets: [{
data: [1, 2, 3], // Random data
}],
}
};
When that display something, try to add complexity.
By guessing, I believe you want something like that
const config = {
type: 'bar',
labels: labels, // Your array of label
data: {
datasets: [{
data: [
{x:'New', y:1},{x:'Completed', y:10},{x:'Inproccess', y:100},
{x:'New', y:2},{x:'Completed', y:20},{x:'Inproccess', y:200},
{x:'New', y:3},{x:'Completed', y:30},{x:'Inproccess', y:300},
]
}]
}
};
It's hard to help you as you didn't specify what kind of result chart you want to see...
your code working (snippet)
const labels = ['New', 'Completed', 'Inproccess'];
const config = {
type: 'bar',
labels: labels,
data: {
datasets: [{
label : 'Chart1',
data: [
{x:'New', y:1},{x:'Completed', y:10},{x:'Inproccess', y:100},
{x:'New', y:2},{x:'Completed', y:20},{x:'Inproccess', y:200},
{x:'New', y:3},{x:'Completed', y:30},{x:'Inproccess', y:300},
]
}]
}
};
const myChart = new Chart(
document.getElementById('myChart'),
config
);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<div>
<canvas id="myChart"></canvas>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
I am beginner on this Chart.js and wanna ask, How can I hide the labels and 0 values in the bar Chart. I cannot just hide the whole Dataset since I am using a SQL Table to get the Values "into" Chart.Js. I just want the bar chart show only if the labels have the value. Need your help
sample chart
{
{
$.post("datachartasr.php",
function (data)
{
console.log(data);
var intake = [];
var active = [];
var inactive = [];
var deffered = [];
var widthdrawn = [];
var dis_ter_dereg = [];
var missing = [];
for (var i in data) {
intake.push(data[i].intake);
active.push(data[i].active);
inactive.push(data[i].inactive);
deffered.push(data[i].deffered);
widthdrawn.push(data[i].widthdrawn);
dis_ter_dereg.push(data[i].dis_ter_dereg);
missing.push(data[i].missing);
}
var chartdata = {
labels: intake,
datasets: [
{
label: 'Active Status',
backgroundColor: '#1E90FF',
borderColor: '#1E90FF',
hoverBackgroundColor: '#1E90FF',
hoverBorderColor: '#666666',
data: active
},
{
label: 'Deferred Status',
backgroundColor: '#708090',
borderColor: '#708090',
hoverBackgroundColor: '#708090',
hoverBorderColor: '#666666',
data: deffered
},
.....
.....
.....
]
};
var graphTarget = $("#graphCanvas");
var barGraph = new Chart(graphTarget, {
type: 'bar',
data: chartdata,
});
});
}
}
You can have the below function inside data labels to hide the Zero value:
options: {
plugins: {
datalabels: {
display: function(context) {
return context.dataset.data[context.dataIndex] !== 0; // or >= 1 or ...
}
}
}
}
See more on this issue here https://github.com/chartjs/chartjs-plugin-datalabels/issues/6
I am working on chart.js and I have data coming from JSON via ajax. See the example below:
[{"timestamp":"06:00:00.000000","true_count":2},{"timestamp":"07:00:00.000000","true_count":5},{"timestamp":"08:00:00.000000","true_count":7},{"timestamp":"09:00:00.000000","true_count":8},{"timestamp":"10:00:00.000000","true_count":12},{"timestamp":"11:00:00.000000","true_count":15},{"timestamp":"12:00:00.000000","true_count":20},{"timestamp":"13:00:00.000000","true_count":17},{"timestamp":"14:00:00.000000","true_count":14},{"timestamp":"16:00:00.000000","true_count":11},{"timestamp":"17:00:00.000000","true_count":19},{"timestamp":"18:00:00.000000","true_count":22},{"timestamp":"19:00:00.000000","true_count":16},{"timestamp":"20:00:00.000000","true_count":14},{"timestamp":"22:00:00.000000","true_count":7}]
The JS code i am using for my chart is below:
// create initial empty chart
var ctx_live = document.getElementById("chLine");
var myChart = new Chart(ctx_live, {
type: 'bar',
data: {
labels: [],
datasets: [{
data: [],
borderWidth: 1,
borderColor:'#00c0ef',
label: 'liveCount',
}]
},
options: {
responsive: true,
title: {
display: true,
text: "Count Per Hour",
},
legend: {
display: false
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true,
}
}]
}
}
});
// logic to get new data
var getData = function() {
var _data =[];
var _labels = [];
$.ajax({
url: 'chart_data',
type: "get",
success: function(data) {
full_data = JSON.parse(data);
full_data.forEach(function(key,index) {
_data.push(key.true_count);
_labels.push(key.hour);
});
myChart.data.labels = _labels;
myChart.data.datasets[0].data = _data;
myChart.update();
}
});
};
// get new data every 3 seconds
setInterval(getData, 3000);
Now, this is working fine and shows the true_count over time which is a one-hour basis. Now, the chart is showing only hours with count but what I would like to do is to set the static hours from 12 AM to 11 PM, and for hours for which I don't have data the true_count will be zero, and for those that I have data for, the true count will be assigned to that hour and show on the chart.
Any ideas on how do I do that?
Here is an example:
// create initial empty chart
var ctx_live = document.getElementById("chLine");
var myChart = new Chart(ctx_live, {
type: 'bar',
data: {
labels: [],
datasets: [{
data: [],
borderWidth: 1,
borderColor: '#00c0ef',
label: 'liveCount',
}]
},
options: {
responsive: true,
title: {
display: true,
text: "Count Per Hour",
},
legend: {
display: false
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true,
}
}]
}
}
});
// Some constants to be changed later:
const HOUR_TO_START = 0;
const HOUR_TO_END = 23;
// helper:
const intToAmPm = (i) =>
i==0 ? '12 AM' :
i==12 ? '12 PM' :
i < 12 ? i + ' AM' :
(i-12) + ' PM';
// logic to get new data
var getData = function() {
var _data = [];
var _labels = [];
$ajax({
url: 'chart_data',
type: "get",
success: function(data) {
full_data = JSON.parse(data);
let preparedData = {};
full_data.forEach(function(key, index) {
let hour = parseInt(String(key.timestamp).substring(0, 2));
preparedData[hour] = key.true_count;
});
for (let i = HOUR_TO_START; i <= HOUR_TO_END; i++) {
_data.push(preparedData[i] === undefined ? 0 : preparedData[i]);
_labels.push(intToAmPm(i));
}
myChart.data.labels = _labels;
myChart.data.datasets[0].data = _data;
myChart.update();
}
});
};
// get new data every 3 seconds
//setInterval(getData, 3000);
getData();
// THIS IS FOR TESTING. IMITATE BACKEND
function $ajax(param) {
param.success('[{"timestamp":"06:00:00.000000","true_count":2},{"timestamp":"07:00:00.000000","true_count":5},{"timestamp":"08:00:00.000000","true_count":7},{"timestamp":"09:00:00.000000","true_count":8},{"timestamp":"10:00:00.000000","true_count":12},{"timestamp":"11:00:00.000000","true_count":15},{"timestamp":"12:00:00.000000","true_count":20},{"timestamp":"13:00:00.000000","true_count":17},{"timestamp":"14:00:00.000000","true_count":14},{"timestamp":"16:00:00.000000","true_count":11},{"timestamp":"17:00:00.000000","true_count":19},{"timestamp":"18:00:00.000000","true_count":22},{"timestamp":"19:00:00.000000","true_count":16},{"timestamp":"20:00:00.000000","true_count":14},{"timestamp":"22:00:00.000000","true_count":7}]');
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="chLine"></canvas>
I wish to pass values of an array to the data and label fields of the chart.js dataset.
Here the code from success of ajax call made to fetch json data. I fetch the json data and store it into an array.
Data = jQuery.parseJSON(result);
var count = Data.length;
var counter = 0;
while(count > 0) {
LabelResult[counter] =[Data[counter].TIME];
counter++;
count --;
}
Now i wish to use this label values into the labels filed.
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: [LabelResult],
datasets: [{
label: '# of Votes',
data: [DataResult],
borderWidth: 1
}]
}
});
But there seems some issue and the data is not getting rendered on the chart
LabelResult is an array, change
labels: [LabelResult]
to
labels: LabelResult
Also:
data: [DataResult]
to
data: DataResult
Like:
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: LabelResult,
datasets: [{
label: '# of Votes',
data: DataResult,
borderWidth: 1
}]
}
});
I think you could try to remove some brackets.
while(count > 0){
LabelResult[counter] = Data[counter].TIME; // here removed brackets
counter++;
count --;
}
and
data: {
labels: LabelResult, // here removed brackets
datasets: [{
label: '# of Votes',
data: DataResult, // here removed brackets
borderWidth: 1
}]
},
I hope that will works.