Create Multiple charts using c3 - javascript

I have an API where am sourcing the data from.
Html snippet:
<div id='chart'></div>
And the JavaScript:
function PlotChart(chart_name,type,columns){
var chart = c3.generate({
bindto: chart_name,
data: {
columns:columns,
type: type
},
size: {
width: 355.05
}
});
}
Using the above JavaScript as a skeleton for the charts, how do i pass in the API data into another function so that i can call the PlotChart() to create the multiple charts.
Create chart here:
function FirstOfTheManyCharts(){
//Consume api data here
plotChart('#chart', 'pie', columns);
}

function FirstOfTheManyCharts(){
//Consume api data here
function PlotChart(chart_name,type,columns){
var chart = c3.generate({
bindto: chart_name,
data: {
columns:columns,
type: type
},
size: {
width: 355.05
}
});
}
plotChart('#chart', 'pie', columns);
}

Related

How to create chart in google sheets with javascript?

I am using javascript to create Google-sheets-document with user data. The document is saved on the user's Drive.
I can't figure out how to make a graph from the data i have inserted. I am using vanilla javascript with the Google sheets API.
It would probably look something like this:
function createGraph() {
gapi.client.sheets.graph
.create({
properties: {
type(?): 'Pie'
spreadsheetid: //some id
range: 'A1:A10'
},
})
}
EDIT: To specify, i want to insert the graph to the sheets-document that i have created, not to the website.
If you want to add the chart to your spreadsheet, you can use Sheets API's AddChartRequest, as part of the spreadsheets.batchUpdate method.
Code snippet:
On broad terms, your request would look like this (check the reference below in order to build the request body in detail):
const payload = {
"requests": [
{
"addChart": {
"chart": {
"spec": { // Chart type, range source, etc.
"pieChart": { // Pie chart specification
// object (PieChartSpec)
}
// rest of ChartSpec properties
},
"position": { // Where the chart will be located
// object (EmbeddedObjectPosition)
}
}
}
}
]
}
const params = {
spreadsheetId = "YOUR-SPREADSHEET-ID",
body = payload
}
gapi.client.sheets.spreadsheets.batchUpdate(params);
Render chart in browsers and mobile devices:
In case you just wanted to render the chart in a browser, but not add it to your spreadsheet, you would use Google Charts (see Visualization: Pie Chart, for example).
Reference:
Sheets API > Charts
EmbeddedChart
ChartSpec
EmbeddedObjectPosition
PieChartSpec
Refer this example
<html>
<head>
<!--Load the AJAX API-->
<script
type="text/javascript"
src="https://www.gstatic.com/charts/loader.js"
></script>
<script type="text/javascript">
var data;
var chart;
// Load the Visualization API and the piechart package.
google.charts.load("current", { packages: ["corechart"] });
// Set a callback to run when the Google Visualization API is loaded.
google.charts.setOnLoadCallback(drawChart);
// Callback that creates and populates a data table,
// instantiates the pie chart, passes in the data and
// draws it.
function drawChart() {
// Create our data table.
data = new google.visualization.DataTable();
data.addColumn("string", "Topping");
data.addColumn("number", "Slices");
data.addRows([
["Mushrooms", 3],
["Onions", 1],
["Olives", 1],
["Zucchini", 1],
["Pepperoni", 2]
]);
// Set chart options
var options = {
title: "How Much Pizza I Ate Last Night",
width: 400,
height: 300
};
// Instantiate and draw our chart, passing in some options.
chart = new google.visualization.PieChart(
document.getElementById("chart_div")
);
chart.draw(data, options);
}
</script>
</head>
<body>
<!--Div that will hold the pie chart-->
<div id="chart_div" style="width: 400; height: 300;"></div>
</body>
</html>
Referred from
https://developers.google.com/chart/interactive/docs/drawing_charts
I solved it. Thanks for the help! This worked for me.
function createGraphv2(spreadsheetIdGraph, endIndex) {
var params = {
// The spreadsheet to apply the updates to.
spreadsheetId: spreadsheetIdGraph, // TODO: Update placeholder value.
};
var batchUpdateSpreadsheetRequestBody = {
// A list of updates to apply to the spreadsheet.
// Requests will be applied in the order they are specified.
// If any request is not valid, no requests will be applied.
requests: [
{
addChart: {
chart: {
spec: {
title: 'Rapport',
basicChart: {
chartType: 'COLUMN',
legendPosition: 'BOTTOM_LEGEND',
axis: [
//X-AXIS
{
position: "BOTTOM_AXIS",
title: "FORBRUK"
},
//Y-AXIS
{
position: "LEFT_AXIS",
title: "TID"
}
],
series: [
{
series: {
sourceRange: {
sources: [
{
sheetId: 0,
startRowIndex: 0,
endRowIndex: endIndex,
startColumnIndex: 5,
endColumnIndex: 6,
},
],
},
},
targetAxis: "LEFT_AXIS"
}
]
}
},
position : {
newSheet : 'True'
}
},
}
}
],
// TODO: Add desired properties to the request body.
};
var request = gapi.client.sheets.spreadsheets.batchUpdate(
params,
batchUpdateSpreadsheetRequestBody
);
request.then(
function (response) {
// TODO: Change code below to process the `response` object:
console.log(response.result);
},
function (reason) {
console.error("error: " + reason.result.error.message);
}
);
}

How to add a second series in highcharts [duplicate]

This question already has an answer here:
Retrieving JSON data for Highcharts with multiple series?
(1 answer)
Closed 2 years ago.
I have been trying to display the second value of my json file in highcharts for two days.
my json file:
[[1591518187000,17.3,12.7],[1591518135000,17.2,12.7]...[1591518074000,17.2,12.6],[1591518020000,17.2,12.7]]
The time and the first value are displayed correctly.
my script in php file:
<script type="text/javascript">
var chart;
function requestData() {
$.getJSON('../****json.php',
function (data) {
var series = chart.series[0];
series.setData(data);
}
);
}
(document).ready(function() {
chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
defaultSeriesType: 'line',
marginRight: 10,
marginBottom: 25,
events: { load: requestData }
},
.....
series: [{
name: 'Temperatur',
data: []
},
{
name: "Taupunkt",
data: []
......
</script>
Does anyone happen to have a way of drawing the second values ​​as a line?
You could process your data and make two data sets for both series. Both data sets will have the same x values, but different y values. The code could look something like this:
$.getJSON('../****json.php',
function (data) {
var dataSetOne = [],
dataSetTwo = [];
data.forEach(function(point) {
dataSetOne.push([point[0], point[1]);
dataSetTwo.push([point[0], point[2]);
});
chart.series[0].setData(dataSetOne);
chart.series[1].setData(dataSetTwo);
}
);

Chart js old chart data not clearing

This question has been asked many times and I went through most of them but non of them helped me finding a solution.
I am generating couple of bar charts using a for loop as a part of reporting functionality.
I am using node.js with Express Handlebars.
My page looks like:
<div class="row report-charts">
<div class="col-md-12">
{{#buildings}}
<div class="col-md-6">
<h4>{{Name}}</h4>
<canvas id="{{idBuildings}}" width="200" height="80"></canvas>
</div>
{{/buildings}}
</div>
</div>
My js code looks like:
$('.case-report-btn').click(function(){
$.ajax({
type: 'post',
url: '/reports/cases/filter',
data : {
StartDate : $('.start-ms-time-hidden').val(),
EndDate : $('.end-ms-time-hidden').val(),
ReportKey : $('.cases-filter-type').val()
},
dataType: 'json',
success: function(res) {
$('.report-charts').show();
for(key in res) {
var innerObj = res[key]; //gives the inner obj
var ctx = document.getElementById(key); //the idBuildings
var labels = [];
var data = [];
var buildingName = innerObj.Name;
for(innerKey in innerObj) {
if(innerKey != 'Name' && innerKey != 'Total') {
labels.push(innerKey);
data.push(innerObj[innerKey]);
}
}
var options = {
type: 'bar',
data: {
labels: labels,
datasets: [{
label: buildingName,
data: data,
backgroundColor: 'rgba(255, 99, 132, 0.2)',
borderColor: 'rgba(255,99,132,1)',
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true,
fixedStepSize: 1
}
}]
}
}
}
var myChart = new Chart(ctx, options);
}
$('#pleaseWaitDialog').modal('hide');
},
error: function(err) {
$('#pleaseWaitDialog').modal('hide');
bootbox.alert('Error: ' + err);
}
});
});
So basically, I am using for loop to generate multiple charts on the page. Inside the loop I declared the chart variable, every time I change the report parameters and hit the button, the new chart is generated. But when I hover over it, the old one still shows up.
Now I am not sure where I should be putting the myChart.destroy() or myChart.clear() methods. I also tried moving the myChart declaration outside the for loop but it didn't help either.
Any suggestions on how to handle this?
I think there are a few ways to do it. You can update your chart data if the chart already exist. Here two functions you can use:
function removeData(chart) {
chart.data.labels.pop();
chart.data.datasets.forEach((dataset) => {
dataset.data.pop();
});
chart.update();
}
function addData(chart, label, data) {
chart.data.labels.push(label);
chart.data.datasets.forEach((dataset) => {
dataset.data.push(data);
});
chart.update();
}
First you have to remove all your data and then add the new data.
If you want to destroy the chart and create it again you have to save your variable as global. To do this you have yo declare your variable like window.myChart and then before create the new chart, something like this:
if (window.myChart) window.myChart.destroy();
window.myChart = new Chart(ctx, options);
Another way you can try is removing your canvas and creating another one. Something like this:
$('#your_canvas').remove();
$('#your_canvas_father').append('<canvas id="your_canvas"></canvas>');

ChartJS + twig symfony

I've got an issue, I'm trying to create a chart (pie) with ChartJS using twig data.
The chart label uses an array, so I'm giving a twig array to it like this :
var myChart = new Chart(ctx, {
type: 'pie',
data: {
labels: ({{array|json_encode()|raw}})
But it displays "object Object". For my purpose I want to display an attribute of that object, in that example : "intitule"
Thanks a lot.
I suggest you write an own Twig extension and add a filter function to it:
1. Create the extension class and add a filter with name chart:
// src/AppBundle/Twig/AppExtension.php
namespace AppBundle\Twig;
class AppExtension extends \Twig_Extension
{
public function getFilters()
{
return array(
new \Twig_SimpleFilter('chart', array($this, 'chartFilter')),
);
}
public function chartFilter($items, $key = 'intitule')
{
$output = [];
foreach ($items as $item {
if (array_key_exists($key, $item)) {
$output[] = $item[$key];
}
}
return json_encode($output));
}
}
2. Create service
Depending on your services.yml definition you may need to create a service for the extension:
app.twig_extension:
class: AppBundle\Twig\AppExtension
tags:
- { name: twig.extension }
3. Use the filter in your view
you can use the filter using it like this:
var myChart = new Chart(ctx, {
type: 'pie',
data: {
labels: ({{array|chart|raw}})

how do i set json data set as labels for graph plot with c3.js

I have a line graph generated with c3.js with json data
the current chart is very simple
var chart = c3.generate({
bindto: '.balanceChart',
data: {
url: '/data',
mimeType:'json'
}
});
json data:
{
data1: [1000,1240,1270,1250,1280]
data2: [1000,240,30,-20,30]
}
chart looks good and is there
but it is currently plotting both sets of data
what i would like is for data2 to be the tooltip value of the plot
You can hide data2 from displaying like so
data: {
...
hide: ['data2']
}
From http://c3js.org/reference.html#data-hide
And use tooltip.format.value to change the tooltip display
tooltip: {
format: {
value: function (value, ratio, id, index) {
// return chart.data.values("data2")[index]; // if still wanting to use data2
// or get rid of data2 completely using this
var vals = chart.data.values(id); // id will be 'data1', vals will then be data1 array
return vals[index] - (index === 0 ? 0 : vals[index - 1]);
}
}
}
http://c3js.org/reference.html#tooltip-format-value
tooltip.format.title and tooltip.format.name will also be useful here to communicate to a user the value isn't actually that of data1 (maybe just changing the title to "Delta Data1")

Categories