I'm building a flask app in python and i return 2 arrays using render_template, names and deals to my HTML file. I know these work because of the code beneath that I tried, giving the right values.
{% for deal in deals %}
<p>Value: {{ deal }}</p>
{% endfor %}
This shows that I've got access to them in HTML. What I want to do next is get some graphics and see the values on the y-axel and the names as labels of each bar on the chart. I found a graph example from Chart.js and started working with it. But I am not getting anywhere, and the only thing I truly want is to change the data points, so instead of hardcoding it like this:
{ y: 233244, label: "Venezuela" }
it could be:
{ y: deals[i], label: names[i] }
This is the whole chart function.
<script>
window.onload = function () {
var chart = new CanvasJS.Chart("chartContainer", {
animationEnabled: true,
theme: "light2",
title:{
text: "Top Oil Reserves"
},
axisY: {
title: "Reserves(MMbbl)"
},
labels: names,
data: [{
type: "column",
showInLegend: true,
legendMarkerColor: "grey",
legendText: "MMbbl = one million barrels",
dataPoints: [
{ y: 233244, label: "Venezuela" },
{ y: 266455, label: "Saudi" },
{ y: 169709, label: "Canada" },
{ y: 158400, label: "Iran" },
{ y: 142503, label: "Iraq" },
{ y: 101500, label: "Kuwait" },
{ y: 97800, label: "UAE" },
{ y: 80000, label: "Russia" }
]
}]
});
chart.render();
}
</script>
</head>
<body>
<div id="chartContainer" style="height: 370px; width: 100%;"></div>
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
</body>
I SOLVED IT, this was the easiest and probably best way to achieve it in. I finally got through it and can claim both arrays in the graph. My solution looks like this:
var jsDeals = {{ deals|tojson }};
var jsNames = {{ names|tojson }};
var sum = {{ sum|tojson }};
var limit = jsDeals.length;
var dataP = [];
function parseDataPoints () {
for (var i = 0; i <= limit; i++)
dataP.push({y: jsDeals[i], label: jsNames[i]});
}
parseDataPoints();
its the tojson part that did the part. Thanks for your help!
You can create a script tag and declare the variables dynamically in the head of your HTML:
<script>
let chartData = { deals: [], names: [] };
{% for deal in deals %}
chartData.deals.push("{{ deal }}");
{% endfor %}
{% for name in names %}
chartData.names.push("{{ name }}");
{% endfor %}
chartData.dataPoints = chartData.deals.map((deal, index) => ({
y: deal,
label: chartData.names[index]
}));
</script>
Then change your existing code to simply use the created variables.
var chart = new CanvasJS.Chart("chartContainer", {
animationEnabled: true,
theme: "light2",
title:{
text: "Top Oil Reserves"
},
axisY: {
title: "Reserves(MMbbl)"
},
labels: names,
data: [{
type: "column",
showInLegend: true,
legendMarkerColor: "grey",
legendText: "MMbbl = one million barrels",
dataPoints: chartData.dataPoints
}]
});
chart.render();
}
Make your own function to do this. First, initialize the chart:
var chart = new CanvasJS.Chart("chartContainer", {
animationEnabled: true,
theme: "light2",
title:{
text: "Your title"
},
axisY: {
title: "Deals"
},
labels: names,
data: [{
type: "column",
showInLegend: true,
legendMarkerColor: "grey",
legendText: "MMbbl = one million barrels",
dataPoints: []
}]
});
Then, you could have a function to initialize your data:
function initData(deals, names, chart) {
var n = deals.length;
for(var i = 0; i < n; i++) {
chart.data[0].dataPoints.push({y: deals[i], label: names[i]})
}
chart.render();
}
After creating the new chart, simply call initData(deals,names,chart);
If you want to add more data to the chart after initializing it, use this function:
function addNewDeal(deal, name, chart) {
chart.data[0].dataPoints.push({y: deal, label: name});
chart.render();
}
Hope this answered your question. Remember, every time that you want to change the data, to see the change you must call chart.render().
edit:
The final result, including the html, should look something like:
<!DOCTYPE html>
<html>
<head>
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
<script>
function initData(deals, names, chart) {
var n = deals.length;
for(var i = 0; i < n; i++) {
chart.data[0].dataPoints
.push({ y: deals[i], label: names[i]});
}
chart.render();
}
window.onload = () => {
var chart = new CanvasJS.Chart("chartContainer", {
animationEnabled: true,
theme: "light2",
title:{
text: "Your title"
},
axisY: {
title: "Deals"
},
labels: names,
data: [{
type: "column",
showInLegend: true,
legendMarkerColor: "grey",
legendText: "MMbbl = one million barrels",
dataPoints: []
}]
});
chart.render()
var names = ["name1", "name2", "name3"];
var deals = [1,2,3];
initData(deals, names, chart);
}
</script>
</head>
<body>
<div id="chartContainer"></div>
</body>
</html>
Related
create updateBarChart(selectedDimension) function then
how to Create a bar chart that displays one of the numerical dimensions associated with each World Cup:
Average Attendance
Number of Goals
Number of Games
Number of Participants
Implement the bar chart such that it displays the dimension specified in the selectedDimension parameter.
then the bar-chart updates the data it shows depending on the selection of the drop-down box.
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="styles.css" />
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
</head>
<body>
<header>
<h1>Exploring FIFA World Cup Statistics</h1>
</header>
<div id="bar-chart" class="view">
<h2 class="">Bar Chart</h2>
<div id="plot-selector">
<label>Plot:</label>
<select id="dataset" onchange="chooseData()">
<option selected value="attendance">Attendance</option>
<option value="teams">Teams</option>
<option value="matches">Matches</option>
<option value="goals">Goals</option>
</select>
</div>
</div>
<div id="container" style="width:100%;max-width:900px;"></div>
<script>
window.onload = function () {
var chart = new CanvasJS.Chart("container", {
animationEnabled: true,
theme: "light1",
title: {
text: ""
},
axisY: {
title: "Attendance"
},
data: [{
type: "column",
showInLegend: true,
legendMarkerColor: "grey",
legendText: "Years",
dataPoints: [
{ y: 32808, label: "1930" },
{ y: 21352, label: "1934" },
{ y: 20872, label: "1938" },
{ y: 47511, label: "1950" },
{ y: 29561, label: "1954" },
{ y: 23423, label: "1958" },
{ y: 27911, label: "1962" },
{ y: 48847, label: "1966" },
{ y: 50124, label: "1970" },
{ y: 49098, label: "1974" },
{ y: 40678, label: "1978" },
{ y: 40571, label: "1982" },
{ y: 46039, label: "1986" },
{ y: 48388, label: "1990" },
{ y: 68991, label: "1994" },
{ y: 43517, label: "1998" },
{ y: 42268, label: "2002" },
{ y: 52491, label: "2006" },
{ y: 49669, label: "2010" },
{ y: 52918, label: "2014" }
]
}]
});
chart.render();
}
</script>
</body>
Make your chooseData() function do something like this:
if select value is attendance
var chart = new CanvasJS.Chart("container", {options_and_data_for_attendance});
else if select value is teams
var chart = new CanvasJS.Chart("container", {options_and_data_for_teams});
else if select value is matches
var chart = new CanvasJS.Chart("container", {options_and_data_for_matches});
else // select value is goals
var chart = new CanvasJS.Chart("container", {options_and_data_for_goals});
chart.render();
One of the ways, as described above is to change your ChooseData() function to switch between the charts, with the respective dropdowns.
Another way could be to add all the datasets into different Js arrays, and with different dropdowns, push the appropriate array into the datapoints object, hence effectively switching between the arrays, keeping one single chart.
In my code I'm getting an array of inputs arrayinput[] and an array of numbers arraynumber[] from my local storage. The length of the arrays can vary, but it's always arrayinput.length = arraynumber.length.
Now I want to create a horizontal bar chart with these arrays as data.
So arrayinput is on the y axis and arraynumbers on the x axis. But my problem is I don't know how to do that, because the arrays can have any length.
Is it possible to add the arrays to the chart dynamically?
Here I made an example of what I'm trying to do.
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script>
<div class="chartcontainer">
<canvas id="bar-chart-horizontal" ></canvas>
</div>
let arrayinput = ["apple", "banana", "pineapple", "cherry","peach"] ;
let arraynumber = ["5", "10", "3", "8", "1"];
var number=[];
for(var i=0;i<arrayinput.length;i++){
number[i] = parseInt(arraynumber[i]);
}
new Chart(document.getElementById("bar-chart-horizontal"), {
type: 'horizontalBar',
data: {
//here I want all elements of arrayinut
labels: ["apple", "banana", "pineapple", "cherry","peach"],
datasets: [
{
label: "Number of fruits",
//here I need to create arrayinput.length differnt colors but thats not that important now
backgroundColor: ["#3e95cd", "#8e5ea2","#3cba9f","#e8c3b9","#c45850"],
//here I want the elements of number
data: [5,10,3,8,1]
}
]
},
options: {
legend: { display: false },
title: {
display: true,
text: 'Fruits'
},
scales: {
xAxes: [{
ticks: {
beginAtZero: true
}
}]
},
}
});
Yes it is possible, although you are using a verry outdated version of the lib you might want to consider updating it
V2:
const chart = new Chart(document.getElementById("bar-chart-horizontal"), {
type: 'horizontalBar',
data: {
//here I want all elements of arrayinut
labels: [],
datasets: [{
label: "Number of fruits",
//here I need to create arrayinput.length differnt colors but thats not that important now
backgroundColor: ["#3e95cd", "#8e5ea2", "#3cba9f", "#e8c3b9", "#c45850"],
//here I want the elements of number
data: []
}]
},
options: {
legend: {
display: false
},
title: {
display: true,
text: 'Fruits'
},
scales: {
xAxes: [{
ticks: {
beginAtZero: true
}
}]
},
}
});
const addFruits = () => {
chart.data.labels = ["apple", "banana", "pineapple", "cherry", "peach"];
chart.data.datasets[0].data = [5, 10, 3, 8, 1];
chart.update();
}
addFruits()
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script>
<div class="chartcontainer">
<canvas id="bar-chart-horizontal"></canvas>
</div>
V3:
const chart = new Chart(document.getElementById("bar-chart-horizontal"), {
type: 'bar',
data: {
//here I want all elements of arrayinut
labels: [],
datasets: [{
label: "Number of fruits",
//here I need to create arrayinput.length differnt colors but thats not that important now
backgroundColor: ["#3e95cd", "#8e5ea2", "#3cba9f", "#e8c3b9", "#c45850"],
//here I want the elements of number
data: []
}]
},
options: {
indexAxis: 'y',
plugins: {
legend: {
display: false
},
title: {
display: true,
text: 'Fruits'
},
},
scales: {
y: {
beginAtZero: false
}
},
}
});
const addFruits = () => {
chart.data.labels = ["apple", "banana", "pineapple", "cherry", "peach"];
chart.data.datasets[0].data = [5, 10, 3, 8, 1];
chart.update();
}
addFruits()
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.0/chart.min.js"></script>
<div class="chartcontainer">
<canvas id="bar-chart-horizontal"></canvas>
</div>
You can directly use arrayinput inside the function, same for arraynumber.
HTML:
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script>
<div class="chartcontainer">
<canvas id="bar-chart-horizontal"></canvas>
</div>
Javascript:
var arrayinput = ["apple", "banana", "pineapple", "cherry","peach"] ;
var arraynumber = ["5", "10", "3", "8", "1"];
var number=[];
for(var i=0;i<arrayinput.length;i++){
number[i] = parseInt(arraynumber[i]);
}
new Chart(document.getElementById("bar-chart-horizontal"), {
type: 'horizontalBar',
data: {
//here I want all elements of arrayinut
labels: arrayinput,
datasets: [
{
label: "Number of fruits",
//here I need to create arrayinput.length differnt colors but thats not that important now
backgroundColor: ["#3e95cd", "#8e5ea2","#3cba9f","#e8c3b9","#c45850"],
//here I want the elements of number
data: arraynumber
}
]
},
options: {
legend: { display: false },
title: {
display: true,
text: 'Fruits'
},
scales: {
xAxes: [{
ticks: {
beginAtZero: true
}
}]
},
}
});
For using different colors for the chart, you can roughly estimate the maximum number of entries in arrayinput and generate the color array of that size. For example: If you know that entries in the arrayinput will never exceed 1000, you can make an array of 1000 colors, and can make a new array of out of this as per your requirement.
Like this:
var backgroundColor = ["#3e95cd", "#8e5ea2","#3cba9f","#e8c3b9","#c45850"];
var colorArray = [];
//Max value of arrayinput is say 5
for(var i=0; i<arrayinput.length; i++) {
colorArray.push(backgroundColor[i]);
}
Use this colorArray in the function directly same like arrayinput.
Live Demo Here: https://codepen.io/Hitesh_Vadher/pen/vYZmdMZ
I have some python code which sucessfully passes two array to my html template
#app.route('/line')
def line():
df= av_query(av_start_date,av_end_date,'44201')
df['dt']=pd.to_datetime(df['Date'])
df['RawValue']=np.where(df['Units']=='007',df['RawValue']*1000,df['RawValue'] )
temp_df=df[df['Site']=='SM']
dates = temp_df['dt']
values = temp_df['RawValue']
return render_template('line.html', title='Ozone Data',dates=dates[:5], values=values[:5], max_n=100)
and in my html template I have tested this plotting code
<center>
<h1>{{ title }}</h1>
<canvas id="myChart" width="600" height="400"></canvas>
<script>
var s1 = {
label: 's1',
borderColor: 'blue',
data: [
{ x: '2017-01-06 18:39:30', y: 100 },
{ x: '2017-01-07 18:39:28', y: 101 },
]
};
var s2 = {
label: 's2',
borderColor: 'red',
data: [
{ x: '2017-01-07 18:00:00', y: 90 },
{ x: '2017-01-08 18:00:00', y: 105 },
]
};
var ctx = document.getElementById('myChart').getContext('2d');
var chart = new Chart(ctx, {
type: 'line',
data: { datasets: [s1, s2] },
options: {
scales: {
xAxes: [{
type: 'time'
}]
}
}
});
</script>
</center>
How do I replace the dummy data in s1 and s2 with my data?
I tried to push each line to the dataset but that did not seem work.
var s1 = {
label: 's1',
borderColor: 'blue',
dates=dates
values=values
data: []
for (i=0; i<=dates.length; i++){
data.push({x:dates[i], y:values[i]})
}
};
I found the easiest way to do this is render a variable in the page using the template.
If your data is in an array or dictionary, make sure to convert it to json before passing it to the template, then pass it to the javascript when the template renders like so:
<script>
const data = {{ data|safe }};
</script>
JSON will natively render as Javascript and you can do with it what you will then.
Make sure you pass it through the safe filter or it will just be escaped.
I am trying to plot a graph using chart.js where y-axis values are numbers and x-axis values are strings. I have given the code that i have written, but it does not plot the string values.
Appreciate your help.
window.onload = function() {
var dataPoints7 = [];
var chart7 = new CanvasJS.Chart("chartContainer7", {
animationEnabled: true,
theme: "light2",
title: {
text: "Cases in States"
},
axisY: {
title: "Cases",
titleFontSize: 24
},
data: [{
type: "line",
yValueFormatString: "#,### Cases",
dataPoints: dataPoints7
}]
});
fetch("https://api.covid19india.org/data.json", {
"method": "GET"
})
.then(function(response) {
return response.json();
})
.then(function(data) {
for (var i = 1; i < data.statewise.length; i++) {
dataPoints7.push({
x: data.statewise[i].state,
y: parseInt(data.statewise[i].confirmed)
});
}
chart7.render();
});
}
<!DOCTYPE html>
<html lang="en">
<div id="chartContainer7" style="height: 370px; width: 100%;"></div>
<script src="https://canvasjs.com/assets/script/jquery-1.11.1.min.js"></script>
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
</html>
For your case you should supply label property not x value and also i believe you should use column charts for this purpose.
You might see some labels not showing up.You can either set the angle or increase the width of chart to make it visible.
Try running this snippet
window.onload = function() {
var dataPoints7 = [];
var chart7 = new CanvasJS.Chart("chartContainer7", {
animationEnabled: true,
theme: "light2",
title: {
text: "Cases in States"
},
axisY: {
title: "Cases",
titleFontSize: 24
},
axisX: {
labelAngle: 180
},
data: [{
type: "line",
yValueFormatString: "#,### Cases",
dataPoints: dataPoints7
}]
});
fetch("https://api.covid19india.org/data.json", {
"method": "GET"
})
.then(function(response) {
return response.json();
})
.then(function(data) {
for (var i = 1; i < data.statewise.length; i++) {
dataPoints7.push({
label: data.statewise[i].state,
y: parseInt(data.statewise[i].confirmed)
});
}
chart7.render();
});
}
<!DOCTYPE html>
<html lang="en">
<div id="chartContainer7" style="height: 370px; width: 100%;"></div>
<script src="https://canvasjs.com/assets/script/jquery-1.11.1.min.js"></script>
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
</html>
My Pie chart but actually i want this
type of chart
I want to display dynamically label and label values in pie chart using chart
js but according to my code which i have written ,it display all label in one
label. I don't know where is the issue in my code.I don't know as much about
js. Please guide me.Thanks in advance.
$("#get_data").click(function(){
var employees = $("#employees").val();
//var fairs = $("#fairs").val();
$.ajax({
url : 'php_script/chart_values.php',
method : 'POST',
data : {employees:employees},
success : function(data){
var obj = JSON.parse(data);
var a = obj[0]; // labele data "Negotiation on
proposal","Won","Contracted","Intersted",
var b = obj[1]; // label values "100","90","70"
var labeldata;
for( i=0; i<a.length;i++){ // loop to fetch label data one by one
labeldata += [a][i];
}
console.log(labeldata);
var chart = new CanvasJS.Chart("chartContainer", {
title: {
//text: "Worldwide Smartphone sales by brand - 2012",
fontSize:15
},
axisY: {
title: "Products in %"
},
legend :{
verticalAlign: "center",
horizontalAlign: "right"
},
data: [{
type: "pie",
showInLegend: true,
toolTipContent: "{label} <br/> {y} %",
indexLabel: "{y} %",
dataPoints: [
{
label: [labeldata],y:19 // dispaly lable data here
}
/*{ label: "Apple", y: 19.1, legendText: "Apple" },
{ label: "Huawei", y: 4.0, legendText: "Huawei" },
{ label: "LG", y: 3.8, legendText: "LG Electronics"},
{ label: "Lenovo", y: 3.2, legendText: "Lenovo" },
{ label: "Others", y: 39.6, legendText: "Others" } */
]
}
]
});
chart.render();
}
});
});
This is my complete code and this is working perfectly.
$("#get_data").click(function(){
var employees = $("#employees").val();
//var fairs = $("#fairs").val();
$.ajax({
url : 'php_script/chart_values.php',
method : 'POST',
data : {employees:employees},
success : function(data){
$("#page_content").fadeIn();
$("#bar_chart_div").fadeOut();
var obj = JSON.parse(data);
var a = obj[0]; // labele data "Won","Contracted","Intersted"
var b = obj[1]; // label values "100","90","70"
var labeldata=[];
for( i=0; i<a.length;i++){
labeldata.push({label:a[i],y:parseInt(b[i]),legendText:a[i]});
}
debugger;
console.log(JSON.stringify(labeldata));
var chart = new CanvasJS.Chart("chartContainer", {
title: {
fontSize:15
},
axisY: {
title: "Products in %"
},
legend :{
verticalAlign: "center",
horizontalAlign: "right"
},
data: [{
type: "pie",
showInLegend: true,
toolTipContent: "{label} <br/> {y} ",
indexLabel: "{y} %",
dataPoints: labeldata
}]
});
chart.render();
}
});
});