HighChart pie does not display any data - javascript

Pie Chart looks like this:
Data is there in JSON:
EDIT
From console:
When i tried it with type of "bar" or "column" chart it works fine.
Still new to this and really appreciate your help, folks!
Django version: 1.10
Python version: 3.6
chartViewHigh.html
{% block main %}
<h1 align="center">Analysis</h1>
{% block content %}
<div id="container" style="width:50%; height:400px;"></div>
{% endblock %}
{% block extrajs %}
<script>
var endpoint = '/api/chart/data/';
var labels = [];
var defaultData = [];
var labels2 = [];
var defaultData2 = [];
$.ajax({
method: "GET",
url: endpoint,
/**
* #param data
* #param data.labels
* #param data.default
* #param data.default2
*/
success: function (data) {
labels = data.labels;
defaultData = data.default;
labels2 = data.labels2;
defaultData2 = data.default2;
setChart()
},
error: function (error_data) {
console.log("error");
console.log(error_data)
}
});
function setChart() {
$(document).ready(function() {
var chart = {
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false
};
var title = {
text: 'Total'
};
var tooltip = {
pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>'
};
var plotOptions = {
pie: {
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: true,
format: '<b>{point.name}%</b>: {point.percentage:.1f} %',
style: {
color: (Highcharts.theme && Highcharts.theme.contrastTextColor) || 'black'
}
}
}
};
var series= [{
type: 'pie',
name: 'Group share',
data: [
{ name: 'Board', y: defaultData },
{
name: 'Member',
y: defaultData2,
sliced: true,
selected: true
}
]
}];
var json = {};
json.chart = chart;
json.title = title;
json.tooltip = tooltip;
json.series = series;
json.plotOptions = plotOptions;
$('#container').highcharts(json);
});
views.py
class ChartData(APIView):
def get(self, request, format=None):
qs_count = Administrator.objects.filter(association=self.request.user.association).count()
qs_count2 = Member.objects.filter(association=self.request.user.association).count()
labels = ["Members"]
default_items = [qs_count2]
labels2 = ["Board"]
default_items2 = [qs_count]
data = {
"labels": labels,
"default": default_items,
"labels2": labels2,
"default2": default_items2
}
return Response(data)

The data array has incorrect format. y values must be numbers, you set them as an array.
Change series variable to:
var series= [{
type: 'pie',
name: 'Group share',
data: [{
name: 'Board',
y: defaultData[0] },
{
name: 'Member',
y: defaultData2[0],
sliced: true,
selected: true
}
]
}];
Or send those values as a single number instead of an array.

You look to be missing in your chart section a declaration of a pie chart.
var chart = {
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false,
type: 'pie' // this is missing.
};
Have not been able to run your code to test but fingers crossed this sorts it for you.

Related

Building own SIEM system on django

I am currently working on own siem system, where windows logs(in csv format) automatically collecting every hour and displaying in a Highcharts. The backend is Django.
But ran into problems:
There's too many data that GPU of browser is load.
I set auto parsing to per 1 hour but site not displaying. Other parts of code are working
Is it ok if I write logs in database?
Can anyone give me advices how to do it right?
Here is my Javascript code in template/dashboard
_categories = {{categories|safe}};
_values = {{values|safe}};
_data = {{data|safe}};
Highcharts.chart('pie', {
colors: ['#558dfa', '#a1c1fe', '#4c72bc', '#3a61ad'],
title: {
text: ''
},
chart: {
type: 'pie'
},
tooltip: {
valueSuffix: '%'
},
plotOptions: {
pie: {
allowPointSelect: false,
cursor: 'pointer',
dataLabels: {
enabled: false
},
showInLegend: false
}
},
series: [{
name: 'Percentage',
colorByPoint: true,
data: [
{
name: 'Critical',
y: {{range.0}}
},
{
name: 'Error',
y: {{range.1}}
},
{
name: 'Information',
y: {{range.2}}
},
{
name: 'Warning',
y: {{range.3}}
},
]
}]
});
Highcharts.stockChart('container', {
chart: {
alignTicks: false
},
rangeSelector: {
selected: 0
},
series: [{
type: 'column',
data: _data,
}],
dataGrouping: {
units: [[
'week', // unit name
[1] // allowed multiples
], [
'month',
[1, 2, 3, 4, 6]
]]
}
});
Here is my views.py
def dashboard_req(path, request):
df = pd.read_csv(path)
rs = df.groupby('Level')['Event ID'].count()
r = df.groupby('Time Generated')['Event ID'].count()
categories = list(rs.index)
values = list(rs.values)
count = len(df.index)
date = list(r.index)
values2 = list(r.values)
data = []
for i in range(len(date)):
date_format = datetime.datetime.strptime(date[i], "%Y-%m-%d %H:%M:%S")
unix_time = datetime.datetime.timestamp(date_format)
data.append([int(unix_time)*1000, values2[i]])
ranges = []
for i in values:
percent = i / count * 100
ranges.append(round(percent,1))
table_content = df.to_html(index=None)
table_content = table_content.replace("<thead>","<thead class='thead-dark'>")
table_content = table_content.replace('class="dataframe"',"class='table table-striped'")
table_content = table_content.replace('border="1"',"")
context = {"categories": categories, 'values': values, 'table_data':table_content, 'count':count, 'range':ranges, 'data':data}
# print('Done')
return render(request, './dashboard.html', context=context)
def do_something(scheduler, request):
scheduler.enter(3600, 1, do_something, (scheduler, request)) # sec
path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'data\log.csv')
server = 'localhost'
logtype = 'Application'
hand = win32evtlog.OpenEventLog(server,logtype)
flags = win32evtlog.EVENTLOG_BACKWARDS_READ|win32evtlog.EVENTLOG_SEQUENTIAL_READ
total = win32evtlog.GetNumberOfEventLogRecords(hand)
head = ['ID','Time Generated', 'Source Name', 'Event ID', 'Event Category', 'Level', 'Event Data']
id_count = 1
event_types = ['Critical', 'Error', 'Warning', 'Information']
with open(path, 'w', encoding="utf-8") as file:
writer = csv.writer(file)
writer.writerow(head)
while True:
events = win32evtlog.ReadEventLog(hand, flags,0)
if events:
for event in events:
data = event.StringInserts
if data:
for msg in data:
log_row = [id_count, event.TimeGenerated, event.SourceName, event.EventID, event.EventCategory, event_types[event.EventType-1], msg]
else:
log_row = [id_count, event.TimeGenerated, event.SourceName, event.EventID, event.EventCategory, event_types[event.EventType-1]]
writer.writerow(log_row)
id_count+=1
else:
break
dashboard_req(path, request)
def dashboard(request):
my_scheduler = sched.scheduler(time.time, time.sleep)
my_scheduler.enter(3600, 1, do_something, (my_scheduler, request))
my_scheduler.run()

Create Pie chart for each Json object

I have one Json with multiple array and foreach array I want to create Pie chart, but I don't know how to do it.
This is the array thet I have. And this is what I tried :
function Pie() {
$.getJSON("/Admin/Attivita/OreOggi", function (data) {
console.log(data);
var oreTecico = [];
var oreTecico = [];
var oreMalatia = [];
var oreStraordinario = [];
var oreInfortunio = [];
var oreFerie = [];
for (var i = 0; i < data.length; i++) {
nomeTecnico.push(data[i].nome);
oreTecico.push(data[i].odinario);
oreMalatia.push(data[i].malatia);
oreStraordinario.push(data[i].straordinario);
oreInfortunio.push(data[i].infortunio);
oreFerie.push(data[i].ferie);
};
// Build the chart
Highcharts.chart('zdravko', {
chart: {
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false,
type: 'pie'
},
title: {
text: 'Ore segnate oggi'
},
tooltip: {
pointFormat: '<b>{point.name}</b>: {point.y:.1f} h.'
},
accessibility: {
point: {
valueSuffix: '%'
}
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: false
},
showInLegend: true
}
},
series: [{
name: nomeTecnico[0],
colorByPoint: true,
data: [{
name: '',
y:0,
sliced: true,
selected: true
}, {
name: 'Odinario',
y: oreTecico[0]
}, {
name: 'Malatia',
y: oreMalatia[0]
}, {
name: 'Straordinario',
y: oreStraordinario[0]
}, {
name: 'Infortunio',
y: oreInfortunio[0]
}, {
name: 'Ferie',
y: oreFerie[0]
}]
}]
});
});
}
It shows only the last "data". I want to make fo each array one pie. If i have 100 arrays I want 100 pies.
UPDATE:
I added this :
data.forEach(function (el) {
var chartData = [el.data1, el.data2];
var chartContainer = document.createElement('div');
document.getElementById('zdravko').append(chartContainer);
Highcharts.chart(chartContainer, {
series: [{
type: 'pie',
data: chartData
}]
});
});
The chartData is array of undefined objects.
Is it possible to make for or foreach inside Highcharts?
You need to use the Highcharts.chart method in a loop, for example:
var data = [{
data1: 12,
data2: 25
}, {
data1: 67,
data2: 11
}];
data.forEach(function(el) {
var chartData = [el.data1, el.data2];
var chartContainer = document.createElement('div');
document.getElementById('container').append(chartContainer);
Highcharts.chart(chartContainer, {
series: [{
type: 'pie',
data: chartData
}]
});
});
Live demo: http://jsfiddle.net/BlackLabel/x95pbw7j/
API Reference: https://api.highcharts.com/class-reference/Highcharts#.chart

Highcharts data value from variable array string

Got a column called ChartData in database with a string value of 4,11,25,36,50. Trying to assign this value to a hidden variable so JS can read the value of this and put this value in the data option using high charts. I have console.log the variable and looks like its appearing as a string rather than an array when being parsed across the server side to the client side.
C# code
string str = reader["ChartData"].ToString();
string[] strList = str.Split(','); //seperate the hobbies by comma
// convert it in json
dataStr = JsonConvert.SerializeObject(strList, Formatting.None);
hiddenvariable.Value = dataStr;
JS code:
function CreateBoxPlot() {
var hv = $('#hiddenvariable').val();
alert(hv); //["40","61","65","74","77"]
var chart;
var titleText = 'Test Chart Title';
var subTitleText = 'Test Chart Subtitle';
var type = 'boxplot';
var data = hv;
console.log(data); //["40","61","65","74","77"]
$(function () {
$('#container').highcharts({
chart: { type: type, inverted: true },
title: { text: titleText },
subtitle: { text: subTitleText },
legend: { enabled: false },
tooltip: {
shared: true,
crosshairs: true
},
plotOptions: {
series: {
pointWidth: 50
}
},
xAxis: {
visible: false
},
yAxis: {
visible: true,
title: {
text: 'Values'
},
plotLines: [{
value: 80,
color: 'red',
width: 2
}]
}
});
chart = $('#container').highcharts();
chart.addSeries({ data: data });
});
}
However when i hardcode data to the below value this works. How do i format this correctly when its parsed over to the JS side:
var data = [[40,61,65,74,77]]
You have to convert the string '["40","61","65","74","77"]' to js array with numbers. To make it work on each browser you can follow this approach:
Parse the string to js array using JSON.parse()
Loop through the created array and convert each element to number:
var json = '["40","61","65","74","77"]',
dataString = JSON.parse(json),
data = [],
i;
for (i = 0; i < dataString.length; i++) {
data[i] = +dataString[i];
}
Code:
$(function() {
var json = '["40","61","65","74","77"]',
dataString = JSON.parse(json),
data = [],
i;
for (i = 0; i < dataString.length; i++) {
data[i] = +dataString[i];
}
$('#container').highcharts({
chart: {
inverted: true
},
legend: {
enabled: false
},
tooltip: {
shared: true,
crosshairs: true
},
plotOptions: {
series: {
pointWidth: 50
}
},
xAxis: {
visible: false
},
yAxis: {
visible: true,
title: {
text: 'Values'
},
plotLines: [{
value: 80,
color: 'red',
width: 2
}]
}
});
chart = $('#container').highcharts();
chart.addSeries({
data: data
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<div id="container"></div>
Demo:
https://jsfiddle.net/BlackLabel/ay1xmgoc/
Taking reference from the comments, add this to your code and then try.
var data = hv.map(function (element) {
return +element;
});

File loading a Csv file into highcharts

I'm plotting Csv column data in highcharts. Instead of the:
$.get('5.csv', function(data)
I want input a local desktop Csv file using:
function handleFileSelect(evt) {
var files = evt.target.files; // FileList object
My current Javascript code is below :
var options = {
chart: {
renderTo: 'container',
defaultSeriesType: 'line'
},
title: {
text: 'Test'
},
xAxis: {
categories: []
},
yAxis: {
title: {
text: 'Units',
}
},
series: []
};
// $.get('5.csv', function(data) {
var file = event.target.file;
var reader = new FileReader();
var txt=reader.readAsText(file);
var lines = txt.split('\n');
var c = [], d = [];
$.each(lines, function(lineNo, line) {
if(lineNo > 0 ){
var items = line.split(',');
var strTemp = items[0];
c = [parseFloat(items[0]), parseFloat(items[1])];
d.push(c);
console.log(c);
}
});
options.xAxis.categories = c;
options.series = [{
data: d
}];
chart = new Highcharts.Chart(options);
});
How would I go about doing this ? I want to upload a Csv file from a local desktop machine. How do I link the File Reader upload of the file to highcharts to plot, instead of using the $.get(5.csv', function(data) { ? Or am I better using jquery-csv (https://github.com/evanplaice/jquery-csv). I know there are browser security issues. My file is a 3 column Csv with a one line header, column 1 is the x-axis, 2 is the y-axis, 3 will be the error bar, which I haven't yet implemented:
Q,I,E
0.009,2.40E-01,5.67E-02
0.011,2.13E-01,3.83E-02
0.013,2.82E-01,2.28E-02
etc ....
This works now upload by File API
function processFiles(files) {
var chart;
options = {
chart: {
zoomType: 'x',
renderTo: 'container',
type: 'line',
zoomType: 'x'
},
title: {
text: ''
},
subtitle: {
text: ''
},
xAxis: {
type: 'linear',
minorTickInterval: 0.1,
title: {
text: 'Q'}
},
yAxis: {
type: 'linear',
minorTickInterval: 0.1,
title: {
text: 'I(ntensity)'
},
},
tooltip: {
shared: true
},
legend: {
enabled: true
},
plotOptions: {
area: {
fillColor: {
linearGradient: [0, 0, 0, 300],
stops: [
[0, Highcharts.getOptions().colors[0]],
[0, 'rgba(2,0,0,0)']
]
},
lineWidth: 1,
marker: {
enabled: false,
states: {
hover: {
enabled: true,
radius: 5
}
}
},
shadow: false,
states: {
hover: {
lineWidth: 1
}
}
}
},
series: [{
name: 'Series'}]
};
var file = files[0]
var reader = new FileReader();
reader.onload = function (e) {
str = e.target.result;
var lines = str.split("\n");
var c = [], d = [], er = [];
$.each(lines, function(lineNo, line) {
if(lineNo > 0 ){
var items = line.split(',');
var strTemp = items[0];
er = parseFloat(items[2])
a = parseFloat(items[0])
b = parseFloat(items[1])
min = (b - (er/2))
max = b + ((er/2))
c = [a , b];
var q = [], e = [];
q = [min, max]
e.push(q);
d.push(c);
console.log(c);
console.log(q);
}
});
options.xAxis.categories = c.name;
lineWidth: 1
options.series = [{
data: d,
type: 'scatter'
}, {
name: 'standard deviation',
type: 'errorbar',
color: 'black',
data : e }
];
$("#Linear").click(function(){
$('#container').highcharts().yAxis[0].update({ type: 'linear'});
});
$("#Log").click(function(){
$('#container').highcharts().yAxis[0].update({ type: 'logarithmic'});
});
$("#Guinier").click(function(){
$('#container').highcharts().yAxis[0].update({ data: Math.log(d)});
options.xAxis.categories = c.name;
lineWidth: 1
options.series = [{
data: d
}]
});
chart = new Highcharts.Chart(options);
}
reader.readAsText(file)
var output = document.getElementById("fileOutput")
};
Due to security reasons you can't load a file directly on the client-side
To do this you need to use the HTML5 File API which will give the user a file dialog to select the file.
If you plan to use jquery-csv here's an example that demonstrates how to do that.
File Handling Demo
I'm biased but I say use jquery-csv to parse the data, trying to write a CSV parser comes with a lot of nasty edge cases.
Source: I'm the author of jquery-csv
As an alternative, if jquery-csv doesn't meet your needs, PapaParse is very good too.

Array not passing data

getting data from php page and I am passing chartData array to pie(title,chartData) function as second parameter. Now chartData array is placing in data: [ chartData ] but it not working. But when I add manually with key then It work data: [ chartData[0],chartData[1], ]. But I don't want to mention it manually with key. I want to arry work automatically like data: [ chartData ]
What I have to do?
function createChart(chart) {
if ( chart == 'pie' ) {
var title = $("#chart-title").val();
/***************** Data Elements ****************/
var totalElements = $("#addMoreRowNo").val();
var chartData = new Array();
for(var j = 1; j <= totalElements; j++)
{
var key = $("#chart-pie-text_"+j).val();
var value = $("#chart-pie-percentage_"+j).val();
var data = [key, parseFloat(value)];
chartData[j-1] = data;
}
/***************** Data Elements ****************/
pie(title,chartData);
}
}
function pie(title,chartData) {
var chart;
chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false
},
title: {
text: title
},
tooltip: {
pointFormat: '{series.name}: <b>{point.percentage}%</b>',
percentageDecimals: 1
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: true,
color: '#000000',
connectorColor: '#000000',
formatter: function() {
return '<b>'+ this.point.name +'</b>: '+ this.percentage +' %';
}
}
}
},
series: [{
type: 'pie',
name: 'Browser share',
data: [
chartData
/*chartData[0],
chartData[1],*/
//['Active Postings (13)', 20.00],
]
}]
});
}
I'm pretty sure your problem can be solved by replacing
data: [
chartData
]
with
data : chartData
The way you're writing it, you're defining data as an array containing chartData, which itself is an array. The way you indicate you're testing it, though, is to get the items out of chartData and put each item into data, which results in a different structure.

Categories

Resources