Highcharts. Django won't load. Highcharts with Django - python

There is a wonderful library of js - Highcharts. I'm trying to link it to Django, and everything actually works, but not when I'm trying to insert a variable with content into data. Here's the code.
This function returns what I substitute in data in Highcharts.
def get_series(context):
data_ser = []
for i in context:
if i in ['One', "Two", "Three", "Four", "Five"]:
data_ser.append({
'name': i,
'y': context[i],
'z': 22.2
})
data_ser = json.dumps(data_ser)
return data_ser
And this is the jquery code itself:
<script>
$(document).ready(function () {
var data_ser = '{{ data_ser|safe }}'
console.log(data_ser)
Highcharts.chart('container', {
chart: {
type: 'variablepie'
},
title: {
text: 'Stats'
},
series: [{
minPointSize: 10,
innerSize: '20%',
zMin: 0,
name: 'countries',
data: data_ser
}]
});
})
</script>
In series in data, I try to substitute data_ser, but the graph is not output. Although, if you write it manually, then everything will work.
Similar code works:
<script>
$(document).ready(function () {
var data_ser = '{{ data_ser|safe }}'
console.log(data_ser)
Highcharts.chart('container', {
chart: {
type: 'variablepie'
},
title: {
text: 'Stats'
},
series: [{
minPointSize: 10,
innerSize: '20%',
zMin: 0,
name: 'countries',
data: [
{
"name": "One",
"y": 50.0,
"z": 22.2
}]
}]
});
})
</script>
I really hope for help. Or give at least alternative js libraries with graphs where this will work.

It looks like the issue is that data_ser is a string that represents a JavaScript object, but it is being treated as a string in the data property of the series object.
Try it with:
<script>
...
var data_ser = JSON.parse('{{ data_ser|safe }}')
...
</script>

Related

Chart js space above bar graph

I generate graph depending on the value from my calculations. Problem is, I don't know how to set up 'margins', how to define where to put data labels.
Datalables definition:
datalabels: {
anchor: 'end',
align: 'start',
offset: 5,
Problem is, when a certain month value is 0, it's written over the labels on the bottom. Easy way to fix this would be to define a space about each column, so that it can that text can never go 'off screen' and define align: 'end'.
Case 2:
You could define some extra padding at the top of your chart using the option layout.padding.top.
Please take a look at below runnable code and see how it works:
var ctx = document.getElementById('myChart').getContext('2d');
var myChart = new Chart(ctx, {
type: 'bar',
plugins: [ChartDataLabels],
data: {
labels: ['A', 'B', 'C'],
datasets: [{
label: 'My Dataset',
data: [0, 0, 3],
backgroundColor: 'orange'
}
]
},
options: {
layout: {
padding: {
top: 30
}
},
plugins: {
legend: {
display: false
},
datalabels: {
align: 'end',
anchor: 'end'
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.2.0/chart.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-datalabels/2.0.0-rc.1/chartjs-plugin-datalabels.min.js"></script>
<canvas id="myChart" height="120"></canvas>

Chart JS only showing first 2 values

I'm using this for my chart application right now
<script>
var canvas = document.getElementById('myChart');
new Chart(document.getElementById("myCanvas"), {
type: 'line',
data: {
labels: mon_unique,
datasets: [{
data: values,
borderColor: "#3e95cd",
fill: false
},
]
},
options: {
title: {
display: true,
},
hover: {
mode: 'index',
intersect: true
},
}
});
</script>
values, what I called my data in my flask app, is a list of numbers. When I change data: [0,1,2,3,4] it graphs it, but it doesn't pass in my values at all.
data = remove_err_str
return render_template('graphing.html', values=data)
This displays only the first two points in values. Values is a list of about 50,000 items. It looks like ['1243.42','2`,...]
<body>
<canvas id="myChart" width="400" height="400"></canvas>
<script>
var canvas = document.getElementById('myChart');
new Chart(document.getElementById("myChart"), {
type: 'line',
data: {
datasets: [{
data: {{values | safe}},
borderColor: "#3e95cd",
fill: false
},
]
},
options: {
title: {
display: true,
test: "Chart for the sweep data"
},
hover: {
mode: 'index',
intersect: true
},
}
});
</script>
</body>
This is the solution I found
Graphing HTML page
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.0.0/Chart.bundle.js"></script>
</head>
<body>
<canvas id="myChart" width="1600" height="800"></canvas>
<script>
var canvas = document.getElementById('myChart');
var chart = new Chart(canvas, {
type: 'line',
data: {
labels: {{ labels | safe }},
datasets: [{
label: "Line chart for sweep data",
data: {{ values | safe }},
fill: false
}]
},
options: {
responsive: false,
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}}}
);
</script>
Every item needs a label. If it gets passed in without a label it won't graph. Also I changed the 'beginAtZero' to be set to true, otherwise it starts the lowest y value in the list. To create labels for every value I did this in my flask app.py
for i in data: #turns it from a list of string values to float values
float_data.append(float(i))
count = count + 1
label_arr.append(count)
return render_template('graphing.html', values=float_data, labels=label_arr)
:*]
You are passing data from python-end to front-end so you have to use jinja template inside your code and for that double-brackets can be used
<script>
var canvas = document.getElementById('myChart');
new Chart(document.getElementById("myCanvas"), {
type: 'line',
data: {
labels: mon_unique,
datasets: [{
data: {{values | tojson}},
borderColor: "#3e95cd",
fill: false
},
]
},
options: {
title: {
display: true,
},
hover: {
mode: 'index',
intersect: true
},
}
});
</script>

Error trying to switch between different charts

I am developing an application which shows the data created in a chartjs graph, what I am doing it does well, since all the data is displayed in the way I want, but I have a problem and that is that now I am trying to do that according to the type of graph that a user wants this to be changed, the problem is that the graph is changed but in case of having multiple graphs only the first graph is changed, the others continue with the graph by default, this is my template:
<select name="chartType" id="chartType" onchange="updateChart()" data-role="select">
<option value="pie">pie</option>
<option value="bar">Bar</option>
</select>
<canvas id="{{ project.slug }}" width="400" height="400"></canvas>
This is my script:
var faltante = 100 - {{ project.porcent }};
var data = {
labels: ['{{ project.name }}', 'Falta'],
datasets: [{
data: [{{ project.porcent }}, faltante],
backgroundColor: ['#252850', '#f44611']
}],
};
var ctx = document.getElementById('{{ project.slug }}').getContext('2d');
var myChart = new Chart(ctx, {
type: 'pie',
data: data
});
function updateChart() {
myChart.destroy();
myChart = new Chart(ctx, {
type: document.getElementById("chartType").value,
data: data
});
}
You can invoke your updateChart function with the selected chart type as follows:
onchange="updateChart(this.value)"
Everything could then be done inside the updateChart function.
destroy the chart if it already exists
create the new chart with the specified type
To make this work, you'll also have to explicitly invoke updateChart once with the initial chart type.
updateChart('pie');
Please take a look at below runnable code snippet and see how it works.
let myChart;
function updateChart(type) {
if (myChart) {
myChart.destroy();
}
myChart = new Chart('chart', {
type: type,
data: {
labels: ['A', 'B'],
datasets: [{
data: [3, 6],
backgroundColor: ['#252850', '#f44611']
}]
},
options: {
scales: {
yAxes: [{
display: type == 'bar',
ticks: {
beginAtZero: true
}
}]
}
}
});
}
updateChart('pie');
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js"></script>
<select name="chartType" id="chartType" onchange="updateChart(this.value)" data-role="select">
<option value="pie">Pie</option>
<option value="bar">Bar</option>
</select>
<canvas id="chart" height="100"></canvas>

bootstrap-typeahead.js fetch json from a file or remote source

Hello Guys I am using bootstrap-typeahead.js to fetch the json data of all users list in my flask project.
As per the basic Behaviour of Bootstrap Type ahead I am able to view specified json data under the type ahead calling function but not getting how to get json data.
This snippet will take the JSON list of cities and then shows pretty well using typeahead
<p>Type Query: <input type="text" class="input-medium search-query" id="cities" data-provide="typeahead" data-items="4" ></input></p>
<script type="text/javascript"></script>
$('#cities').typeahead({
source: [
{ id: 1, name: 'Toronto' },
{ id: 2, name: 'Montreal' },
{ id: 3, name: 'New York' },
{ id: 4, name: 'Buffalo' },
{ id: 5, name: 'Boston' },
{ id: 6, name: 'Columbus' },
{ id: 7, name: 'Dallas' },
{ id: 8, name: 'Vancouver' },
{ id: 9, name: 'Seattle' },
{ id: 10, name: 'Los Angeles' }
]
});
But when I want to get data from remote source or from file that should be something like this as per this twitter-bootstrap-typeahead
$('#cities').typeahead({
ajax: '/sample/list'
});
but This is not working as per my requirements.
I have this view to fetch all the users in Python Flask
#app.route('/users')
#login_required
def get_all_users():
all_users = model.User.query()
first = {}; users = []
for user in all_users:
user_key = user.key
first['uname'] = user.name
first['uuid'] = user_key.integer_id()
first['about_me'] = user.about_me
first['email'] = user.email
users.append(first)
first = {}
return jsonify(users=users)
and it throws data which is something like this
{
"users": [
{
"about_me": null,
"email": "chitrankdixit#gmail.com",
"uname": "Chitrank",
"uuid": 5066549580791808
},
{
"about_me": null,
"email": "test#example.com",
"uname": "Test",
"uuid": 5629499534213120
}
]
}
Now I am completely confused that why typeahead is not taking JSON data from my flask view. Please help

my extjs grid is not showing json data in grid from local host

I am using django framework and getting some data from local host in json format like this:
[{"stu_name": "Aatir"}, {"stu_name": "Mohsin"}, {"stu_name": "Anil"}, {"stu_name": "Anwar"}, {"stu_name": "Amir"}]
now i want to use this data and want to show in extjs grid
my extjs files are as below:
hmak.html
<html>
<head>
<title>Account Manager</title>
<link rel="stylesheet" type="text/css" href="{{MEDIA_URL}}extjs/resources/css/ext-all.css">
<script type="text/javascript" src="{{MEDIA_URL}}extjs/ext-all-debug.js"></script>
<script type="text/javascript" src="{{MEDIA_URL}}extjs/ext-debug.js"></script>
<script type="text/javascript" src="{{MEDIA_URL}}app.js"></script>
</head>
<body>
</body>
</html>
app.js
Ext.Loader.setConfig({ enabled: true });
Ext.application({
requires : [ 'Ext.container.Viewport'],
controllers: ['Users'],
name: 'AM',
appFolder: 'media/app',
launch: function() {
Ext.create('Ext.container.Viewport', {
layout: 'fit',
items: [
{
xtype: 'userlist'
}
]
});
}
});
Users.js(controller)
Ext.define('AM.controller.Users', {
extend: 'Ext.app.Controller',
stores: ['Users'],
models: ['User'],
views: ['user.List', 'user.Edit'],
init: function() {
this.control({
'viewport > userlist': {
itemdblclick: this.editUser
},
'useredit button[action=save]': {
click: this.updateUser
}
});
},
updateUser: function(button) {
var win = button.up('window'),
form = win.down('form'),
record = form.getRecord(),
values = form.getValues();
record.set(values);
win.close();
this.getUsersStore().sync();
},
editUser: function(grid, record) {
var view = Ext.widget('useredit');
view.down('form').loadRecord(record);
}
});
List.js(view)
Ext.define('AM.view.user.List' ,{
extend: 'Ext.grid.Panel',
alias : 'widget.userlist',
store: 'Users',
title : 'All Users',
initComponent: function() {
this.store = {
fields: ["stu_name"]
};
this.columns = [
{header: "stu_name", dataIndex: "stu_name", flex: 1}
];
this.callParent(arguments);
}
});
Edit.js(view)
Ext.define('AM.view.user.Edit', {
extend: 'Ext.window.Window',
alias : 'widget.useredit',
title : 'Edit User',
layout: 'fit',
autoShow: true,
initComponent: function() {
this.items = [
{
xtype: 'form',
items: [
{
xtype: 'textfield',
name : "stu_name",
fieldLabel: "stu_name"
}
]
}
];
this.buttons = [
{
text: 'Save',
action: 'save'
},
{
text: 'Cancel',
scope: this,
handler: this.close
}
];
this.callParent(arguments);
}
});
Users.js(store)
Ext.define('AM.store.Users', {
extend: 'Ext.data.Store',
model: 'AM.model.User',
autoLoad: true,
proxy: {
type: 'ajax',
api: {
read: 'http://127.0.0.1:8000/task/'
},
reader: {
type: 'json',
root: 'users',
successProperty: 'success'
}
}
});
User.js(model)
Ext.define('AM.model.User', {
extend: 'Ext.data.Model',
fields: ["stu_name"]
});
viewport.js
Ext.define('SI.view.Viewport', {
extend: 'Ext.container.Viewport'
});
and in my python I wrote:
def homePage(request):
StuInfo.objects.all().values_list()
return render_to_response('hmak.html', context_instance=RequestContext(request))
which in turn goes to hmak.html and from localhost/task (which I've define in the proxy) the data which it gets is in the json form as I've show you above json data
Now what is my problem that why my grid is not showing?
it just shows the header...
Can anyone please help me with this problem?
I think You have to change the
Ext.define('SI.view.Viewport', {
extend: 'Ext.container.Viewport'
});
to
Ext.define('AM.view.Viewport', {
extend: 'Ext.container.Viewport'
});
and also deleting the store calling inside of the initComponent function.
This might be the source of your problem:
this.store = {
fields: ["stu_name"]
};
In the initComponent function, you are overwriting the store that you defined in the gridpanel class definition. Have you tried deleting that?

Categories