Javascript error receiving data from JSON echo - javascript

I'm trying to create a candlestick chart with volume.
The candlestick chart works perfectly, the problem is with the volume.
What I have:
What I need:
datachart.php -> It sends the JSON data.
I feel that the error is in $data[], because the script index.htm doesn't recognize the volume data.
<?php
include '../dbh.php';//It connects to the database
$sql = "SELECT * FROM table ORDER BY date ASC";
$result = $conn->query($sql);
$data = array();
$count = 0;
while ($row = mysqli_fetch_array($result))
{
$newdate = strtotime($row['date']) * 1000;
$data[] = array($newdate, (float)$row['open'], (float)$row['high'], (float)$row['low'], (float)$row['close'], (float)$row['volume']);
$count++;
}
echo json_encode($data);
?>
index.htm
$.getJSON('datachart.php', function (data) {
// split the data set into ohlc and volume
var ohlc = [],
volume = [],
dataLength = data.length,
// set the allowed units for data grouping
groupingUnits = [[
'week', // unit name
[1] // allowed multiples
], [
'month',
[1, 2, 3, 4, 6]
]],
i = 0;
for (i; i < dataLength; i += 1) {
ohlc.push([
data[i][0], // the date
data[i][1], // open
data[i][2], // high
data[i][3], // low
data[i][4] // close
]);
volume.push([
data[i][0], // the date
data[i][5] // the volume
]);
}
// create the chart
Highcharts.stockChart('container', {
rangeSelector: {
selected: 1
},
title: {
text: 'Exchange Market'
},
yAxis: [{
labels: {
align: 'right',
x: -3
},
title: {
text: 'OHLC'
},
height: '60%',
lineWidth: 2,
resize: {
enabled: true
}
}, {
labels: {
align: 'right',
x: -3
},
title: {
text: 'Volume'
},
top: '65%',
height: '35%',
offset: 0,
lineWidth: 2
}],
tooltip: {
split: true
},
series: [{
type: 'candlestick',
name: 'AAPL',
data: ohlc,
dataGrouping: {
units: groupingUnits
}
}, {
type: 'column',
name: 'Volume',
data: volume,
yAxis: 1,
dataGrouping: {
units: groupingUnits
}
}]
});
});
If we take only this part of the index.htm code:
volume.push([
data[i][0], // the date
data[i][5] // the volume
]);
If I change the "5" to 1,2,3 or 4, it draws the volume graph. Then, why doesn't it draw the graph with "5" if the volume is in position 5?

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()

Highcharts Using CSV instead of JSON

I tried the code like this with many small restructuration and modification but without success.
Here is the code:
$(function () {
$.get('data.csv', function(data) {
// split the data set into ohlc and volume
var ohlc = [],
volume = [],
dataLength = data.length,
// set the allowed units for data grouping
groupingUnits = [[
'week', // unit name
[1] // allowed multiples
], [
'month',
[1, 2, 3, 4, 6]
]],
i = 0;
for (i; i < dataLength; i += 1) {
ohlc.push([
data[i][0], // the date
data[i][1], // open
data[i][2], // high
data[i][3], // low
data[i][4] // close
]);
volume.push([
data[i][0], // the date
data[i][5] // the volume
]);
}
$('#chart').highcharts({
rangeSelector: {
selected: 1
},
title: {
text: 'AAPL Historical'
},
yAxis: [{
labels: {
align: 'right',
x: -3
},
title: {
text: 'OHLC'
},
height: '60%',
lineWidth: 2
}, {
labels: {
align: 'right',
x: -3
},
title: {
text: 'Volume'
},
top: '65%',
height: '35%',
offset: 0,
lineWidth: 2
}],
data: {
csv: data
},
series: [{
type: 'candlestick',
name: 'AAPL',
data: ohlc,
dataGrouping: {
units: groupingUnits
}
}, {
type: 'column',
name: 'Volume',
data: volume,
yAxis: 1,
dataGrouping: {
units: groupingUnits
}
}]
});
});
});
Here is data.csv:
Date,Open,High,Low,Close,Volume
2013-12-20,9371.08,9413.09,9352.98,9400.18,161686900
2013-12-19,9279.68,9351.9,9257.24,9335.74,98276500
2013-12-18,9145.35,9190.73,9122.05,9181.75,82342700
2013-12-17,9142.75,9161.8,9085.12,9085.12,72207500
2013-12-16,9004.62,9187.78,8997.75,9163.56,99105600
2013-12-13,9016.78,9046.63,8990.58,9006.46,67761700
2013-12-12,9032.67,9060.54,8984.28,9017,75120200
2013-12-11,9093.26,9153.14,9065.51,9077.11,64845800
2013-12-10,9180.29,9223.73,9091.97,9114.44,74363400
Can you help me to figure out the problem or purpose new approch please ?
What is my goal ?
Is to be able to load a CSV file inside the chart instead of using JSON file.
Why ?
Because modifing CSV file is more easier for me using PHP than JSON, and it's for performance too.
Thank's
When you do data.length, you are getting length of the csv file string. What you need to do is split the data with the newline delimiter.
// sample from data
var data = `Date,Open,High,Low,Close,Volume
2013-12-20,9371.08,9413.09,9352.98,9400.18,161686900
2013-12-19,9279.68,9351.9,9257.24,9335.74,98276500`;
// split by \n (new line)
data = data.split('\n'); // now data is an array of rows
var finalObj = [];
// iterate over the rows
data.map(function(row){
var obj = {};
// row is a string separated by ','
row = row.split(','); // now row is an array
obj['date'] = row[0];
obj['open'] = row[1];
obj['high'] = row[2];
obj['low'] = row[3];
obj['close'] = row[4];
obj['volume'] = row[5];
finalObj.push(obj);
})
console.log(finalObj);
Output:
[
{
date:'Date',
open:'Open',
high:'High',
low:'Low',
close:'Close',
volume:'Volume'
},
{
date:'2013-12-20',
open:'9371.08',
high:'9413.09',
low:'9352.98',
close:'9400.18',
volume:'161686900'
},
{
date:'2013-12-19',
open:'9279.68',
high:'9351.9',
low:'9257.24',
close:'9335.74',
volume:'98276500'
}
]

Multiple series data Highcharts line

The result of query I use display 3 column (country, date, items).
My php code side
$res = db_query($sql);
$dat = array();
while($r = db_fetch_array($res)){
$dat[]= array($r['date'], $r['items'], $r['country']);
}
// Armar
$start_date = '';
if(count($dat)>0){
$s = split(' ',$dat[0][0]);
$ss = split('-',$s[0]);
}
// Cada objeto en $dats es una grafica
$dats[] = array('type'=>'line',
'name'=>$q['title'],
'pointInterval'=>24 * 3600 * 1000,
'pointStart'=>mktime(0,0,0,$ss[1],$ss[2],$ss[0])*1000,
'data'=>$dat) ;
//echo "$sql";
echo json_encode($dats,JSON_NUMERIC_CHECK);
My Javascript Code :
function loadLine(_data){
$('#line_container').highcharts({
chart: {zoomType: 'x',spacingRight: 20},
title: { text: 'Monthly Created items'},
subtitle: {text:'Updated every day'},
xAxis: {
type: 'datetime',
maxZoom: 7 * 24 * 3600000, // fourteen days
title: {text: null}
},
yAxis: {title: {text: 'Created items'}},
tooltip: {shared: true},
legend: {enabled: true},
plotOptions: {
area: {
fillColor: {
linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1},
stops: [
[0, Highcharts.getOptions().colors[0]],
[1, Highcharts.Color(Highcharts.getOptions().colors[0]).setOpacity(0).get('rgba')]
]
},
lineWidth: 1,
marker: {
enabled: false
},
shadow: false,
states: {
hover: {
lineWidth: 1
}
},
threshold: null
}
},
series: _data
});
}
and The result displayed is like this
How Could change "series 1" in the graph by the country name I receive in my query?
The data I have in the Query has date until "April" (YTD) but the Graph shows Months in the future, How could I correct this?
If I have more than 1 country in my Query How could I display this in multiple chart lines at the same time.
Thanks in advance.
You have only supplied a single series, which will only translate to a single line. Try something like:
$res = db_query($sql);
$dat = array();
while($r = db_fetch_array($res)){
if (!isset($dat[$r['country']]))
$dat[$r['country']] = [];
$dat[$r['country']][] = array($r['date'], $r['items'], $r['country']);
}
// Armar
$start_date = '';
if(count($dat)>0){
$s = split(' ',$dat[0][0]);
$ss = split('-',$s[0]);
}
// Cada objeto en $dats es una grafica
$dats = [];
foreach ($dat as $country => $values) {
$dats[] = array('type'=>'line',
'name'=>$q['title'],
'pointInterval'=>24 * 3600 * 1000,
'pointStart'=>mktime(0,0,0,$ss[1],$ss[2],$ss[0])*1000,
'data'=>$values) ;
}
//echo "$sql";
echo json_encode($dats,JSON_NUMERIC_CHECK);
Your _data should be something like the following:
[{
name: 'USA',
data: [[Date.UTC(2013,5,1), 7.0], [Date.UTC(2013,6,1), 5.0]]
}, {
name: 'Germany',
data: [[Date.UTC(2013,5,1), 6.0], [Date.UTC(2013,6,1), 8.0]]
}, {
name: 'Japan',
data: [[Date.UTC(2013,5,1), 7.0], [Date.UTC(2013,6,1), 3.0]]
}]
So you will need to do some mapping from your _data

Want to fetch mysql Field record in highchart tooltip

Here I am using highchart with codeigniter. I got highchart record with graph but I want record comes from mysql database field of "zreadactivity" in tooltip. I could not get proper name in tooltip for "zreadactivity" as it contains record. So, I just want to know that where I am stuck?
Here is my code:
Controller:
public function branchwiseactivityavg()
{
$data = $this->Data->branch_wise_activities();
$category = array();
$category['name'] = 'EndDate';
$series1 = array();
$series1['name'] = 'TotalValue';
$series2 = array();
$series2['name'] = 'zreadactivity';
foreach ($data as $row)
{
$category['data'][] = $row->EndDate;
$series1['data'][] = $row->TotalValue;
$series2['data'][] = $row->zreadactivity;
}
$result = array();
array_push($result,$category);
array_push($result,$series1);
array_push($result,$series2);
print json_encode($result, JSON_NUMERIC_CHECK);
}
Javascript:
<script type="text/javascript">
$(document).ready(function() {
var options = {
chart: {
renderTo: 'container5',
type: 'column',
marginRight: 130,
marginBottom: 25,
zoomType: 'x'
},
title: {
text: 'Branch wise activities Last 30 Days',
x: -20 //center
},
subtitle: {
text: '',
x: -20
},
xAxis: {
categories : []
},
yAxis: {
title: {
text: 'TotalValue'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip:
{
formatter: function() { return ' ' +
'EndDate: ' + this.x + '<br />' +
'TotalValue: ' + this.y + '<br />' +
'zreadactivity: ' + this.series.name;
}
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'top',
x: -10,
y: 100,
borderWidth: 0
},
series: []
};
$.getJSON("branchwiseactivityavg", function(json) {
options.xAxis.categories = json[0]['data'];
options.series[0] = json[1];
chart = new Highcharts.Chart(options);
});
});
</script>
zreadactivity table:
zreadacivity
---------------
Refund
Exchange
Voids
Cancel
Discount
Price Overwrite
One way is to create JSON where for series' data each point is defined as an array like:
[value_from_TotalValue, value_from_zreadactivity]
and set keys for series like:
series: [{keys: ['y','zreadactivity']}]
and in tooltip's formatter use this.point.zreadactivity to access zreadactivity.
Other option is to build this structure for series in JavaScript after getting JSON data.
Example with keys: http://jsfiddle.net/yhx2dp2g/
Example without keys: http://jsfiddle.net/yhx2dp2g/1/

Is it possible create a Highstock chart using TWO PANES and MULTIPLE SERIES in a pane

Does anybody know if it's possible to create a chart using TWO PANES and, inside of a pane, MULTIPLE SERIES?
I did a screenshot of what I need:
Does anybody have a example in JFiddler?
I already tried to create one but I didn't have success...
Regards,
Marcelo
Yes, I did it!
Bellow follow the source code that I've created:
HTML
<script src="http://code.highcharts.com/stock/highstock.js"></script>
<script src="http://code.highcharts.com/stock/modules/exporting.js"></script>
<div id="container" style="height: 500px; min-width: 310px"></div>
Javascript Code
$(function() {
$.getJSON('http://www.highcharts.com/samples/data/jsonp.php?filename=aapl-ohlcv.json&callback=?', function(data) {
var ohlc = [],
ohlc2 = [],
volume = [],
dataLength = data.length,
groupingUnits = [
['week', [1]],
['month', [1, 2, 3, 4, 6]]
],
i = 0;
for (i; i < dataLength; i += 1) {
ohlc.push([
data[i][0], // the date
data[i][1], // open
data[i][2], // high
data[i][3], // low
data[i][4] // close
]);
ohlc2.push([
data[i][0], // the date
data[i][1] - (Math.ceil(Math.random()*100)+100), // open
data[i][2] - (Math.ceil(Math.random()*100)+100), // high
data[i][3] - (Math.ceil(Math.random()*100)+100), // low
data[i][4] - (Math.ceil(Math.random()*100)+100) // close
]);
volume.push([
data[i][0], // the date
data[i][5] // the volume
]);
}
// create the chart
$('#container').highcharts('StockChart', {
rangeSelector: {
inputEnabled: $('#container').width() > 480,
selected: 1
},
title: {
text: 'Two Panes & Multiple Series'
},
yAxis: [{
labels: {
align: 'right',
x: -3
},
title: {
text: 'OHLC'
},
height: '60%',
lineWidth: 2
}, {
labels: {
align: 'right',
x: -3
},
title: {
text: 'Volume'
},
top: '65%',
height: '35%',
offset: 0,
lineWidth: 2
}],
series: [{
name: 'AAPL',
data: ohlc,
dataGrouping: {
units: groupingUnits
}
}, {
name: 'AAPL2',
data: ohlc2,
dataGrouping: {
units: groupingUnits
}
}, {
name: 'Volume',
data: volume,
yAxis: 1,
dataGrouping: {
units: groupingUnits
}
}]
});
});
});
And the link in JSFiddler:
http://jsfiddle.net/marcelojuventino/tc1a78ma/1/
Thanks to everybody!

Categories

Resources