Highcharts line not plotting - mysql

I have used an example and can successfully read data using php and mysql and plot it (timebase vs a variable), all works fine. I have taken that and used it as a template and used a different db that doesn't use a timebase but the graph isn't rendering. The graph is meant to display data from an SQL query that collates the frequency of occurrence of a variable with the variable on the x axis and the frequency of occurrence on the Y axis.
The chart pops up with the x and y axis values as expected. It looks right; except the plot is missing. To assist my troubleshooting I have listed the data on the screen albeit not pretty- this proves the db is being called correctly and there are no obvious SQL errors and that data is being returned.
db_code`
<?php
$con = mysql_connect("localhost","root","hal9000");
if (!$con) {
die('Could not connect: ' . mysql_error());
}
mysql_select_db("sqm", $con);
$result = mysql_query("SELECT magnitude, COUNT(*) AS xxx FROM data WHERE magnitude > 1 GROUP by magnitude");
while($row = mysql_fetch_array($result)) {
echo $row['magnitude'] . "\t" . $row['xxx']. "\n";
}
mysql_close($con);
?> `
main_page code
<script type="text/javascript">
var chart;
$(document).ready(function() {
var options = {
chart: {
renderTo: 'common_LHS',
defaultSeriesType: 'line',
marginRight: 130,
marginBottom: 25
},
title: {
text: 'Magnitude',
x: -20 //center
},
subtitle: {
text: '',
x: -20
},
plotOptions: {
series: {
marker: {
enabled: true,
symbol: 'circle',
radius: 0
}
}
},
xAxis: {
type: 'linear',
tickWidth: 0,
gridLineWidth: 1,
labels: {
align: 'center',
x: -3,
y: 20
}
},
yAxis: {
title: {
text: 'Frequency of occurrence'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'top',
x: -10,
y: 100,
borderWidth: 0
},
tooltip: {
crosshairs: [{
width: 2,
color: 'red'
}, {
width: 2,
color: 'red'
}],
},
series: [{
name: 'Occurrence',
}]
}
jQuery.get('data.php', null, function(tsv) {
var lines = [];
traffic = [];
try {
// split the data return into lines and parse them
tsv = tsv.split(/\n/g);
jQuery.each(tsv, function(i, line) {
line = line.split(/\t/);
traffic.push ([
parseFloat(line[0]), //need to parseFloat to convert data to float from string
parseFloat(line[1])
]);
});
} catch (e) { }
options.series[0].data = traffic;
chart = new Highcharts.Chart(options);
});
});
The data looks as I expected when graphed in LibreCalc, apart from the line not rendering it is almost done in Highcharts.
Appreciate any advice. Unfortunately since I am new to this forum I can't submit images but happy to send them to someone if it helps.
Expect it is something simple, usually is :)

I think the problem comes from the way you build your traffic array. It might not be well sorted. Try to sort it by the first element, using something like:
function Comparator(a,b){
if (a[0] < b[0]) return -1;
if (a[0] > b[0]) return 1;
return 0;
}
traffic.sort(Comparator);
options.series[0].data = traffic;
Does it give you a different result ? Also, does your browser console log something when rendering the chart ?

Well I said it would be simple and it was.
I added ,10 to make sure it was decimal and it didn't make any difference. I changed it to 16 and was expecting the values to change and it did so it was definitely reading the data although it still didn't plot the data.
I then added .replace(',', '') to the y axis and it worked.
parseFloat (line[1],10),
parseFloat (line[1].replace(',', ''), 10)
Seems it doesn't like comma's in the data value!

Related

Is there a way to plot Multiple Lines with Plotly.JS?

I am trying to use PLOTLY.JS to plot 2 line graphs. But nothing is showing up on the screen except an empty graph. Any help? It works fine with one lines, bar charts, etc.
var plot_data = {}
var trace1 = {
x: [4, 3, 1],
y: [1, 3, 6],mode: 'lines',
type: 'scatter'
};
var trace2 = {
x: [6, 8, 9],
y: [1, 2, 4],mode: 'lines',
type: 'scatter'
};
var data = [trace1, trace2];
plot_data.push(data);
var layout =
{
title: { text: 'Task Plot', font: { family: 'Courier New, monospace', size: 24 }, xref: 'paper', x: 0.05,}
};
//var config = {responsive : true};
Tester = document.getElementById('myDash');
Plotly.newPlot(Tester, plot_data, layout);
If you look at the documentation here, you'll want to pass an array of traces to Plotly.newPlot, so you can replace plot_data with data:
Plotly.newPlot(Tester, data, layout);

Razor chart.js labels/data not in sync

I have a Razor application that generates three columns of data to use in a chart graph. The page and javascript to do that looks like this:
<div><canvas id="myChart"></canvas></div>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
var Maanden = [];
var Totalen = [];
#foreach (var m in Model.Grafieks)
{
#:Maanden.push("#m.maand" + "-" + "#m.jaar");
#:Totalen.push(#m.Total);
}
const ctx = document.getElementById('myChart').getContext('2d');
const myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: Maanden,
datasets: [
{ label: 'Facturen €',
data: Totalen,
backgroundColor: 'rgb(255, 255, 132)',
borderColor: 'rgb(255, 99, 132)',
borderWidth: 1,
}
]
},
});
</script>
Problem is that the labels are displayed OK but the data is off. Every second column is empty and its data pushed to the next column:
Chrome says:
Is there something wrong pushing the data into the arrays?
I had to convert the comma in decimal Totalen to a period!
#foreach (var m in Model.Grafieks)
{
#:Maanden.push("#m.maand" + "-" + "#m.jaar");
<text>bedrag = parsePotentiallyGroupedFloat("#m.Total");</text>
#:Totalen.push(bedrag);
}
function parsePotentiallyGroupedFloat(stringValue) {
stringValue = stringValue.trim();
var result = stringValue.replace(/[^0-9]/g, '');
if (/[,\.]\d{2}$/.test(stringValue)) {
result = result.replace(/(\d{2})$/, '.$1');
}
return parseFloat(result);
}
The function "parsePotentiallyGroupedFloat" is from here: Convert String with Dot or Comma as decimal separator to number in JavaScript

how does one create a trailing path in cesium?

I would like to have a trailing orange path behind movement of my billboard entity. I am pro grammatically controlling its movement (it is coming from a live remote sensor). The the actual SVG/Canvas for the symbol comes from: https://github.com/spatialillusions/milsymbol
But the point is that I am clearly making an error in how to setup the PATH attribute of the entity. I don't see a trailing or leading path. What am I doing wrong?
makeGlyph(sprite) {
let milSym = milSymbols[sprite.type]
if (milSym === undefined) milSym = milSymbols["UFO"]
sprite.mps = 0
sprite.symbol = milSym
let sym2 = new ms.Symbol(milSym, { size: 26, type: sprite.marking, speed: sprite.mps + ' mps', direction: sprite.heading, infoColor: "red" })
let glyph = new Cesium.Entity({
name: sprite.marking,
id: sprite.id,
position: Cesium.Cartesian3.fromDegrees(sprite.lon, sprite.lat, sprite.altitude),
billboard: {
image: sym2.asCanvas(), //Get the canvas for the billboard
// heightReference : Cesium.HeightReference.CLAMP_TO_GROUND,
pixelOffset: new Cesium.Cartesian2(-sym2.markerAnchor.x, -sym2.markerAnchor.y), // Symbol offset
eyeOffset: new Cesium.Cartesian3(0.0, 0.0, 0.0), // default
horizontalOrigin: Cesium.HorizontalOrigin.LEFT, // default
verticalOrigin: Cesium.VerticalOrigin.TOP
},
path: {
leadTime: 100,
trailTime: 100,
width: 1,
material: new Cesium.ColorMaterialProperty({
color : Cesium.Color.ORANGE,
})
},
label: {
text: sprite.marking,
font: '14pt monospace',
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
outlineWidth: 1,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
pixelOffset: new Cesium.Cartesian2(0, -20)
}
})
sprite.glyph = glyph
this.infoBox(sprite)
this.viewer.entities.add(glyph)
}
updateGlyph(sprite) {
this.viewer.entities.suspendEvents()
let loc = Cesium.Cartesian3.fromDegrees(sprite.lon, sprite.lat, sprite.altitude)
sprite.mps = sprite.speed[0] + sprite.speed[1] + sprite.speed[2]
sprite.glyph.position = loc;
this.infoBox(sprite)
this.viewer.entities.resumeEvents()
}

Google column chart showing incorrect date

I am working on google column chart. I have created 3 columns while generating charts. Here are those columns.
var dtblData = new google.visualization.DataTable();
dtblData.addColumn('string', 'Names');
dtblData.addColumn('datetime', 'Intime');
dtblData.addColumn('datetime', 'Outtime');
I am using following data to show on graph.
[{"display_name":"Aditi Badurkar
","in_time":{"year":2017,"month":6,"day":22,"hours":11,"minutes":7,"seconds":8,"miliseconds":470},"out_time":{"year":2017,"month":6,"day":22,"hours":12,"minutes":45,"seconds":44,"miliseconds":237}}]
Here is my code :-
google.charts.load('current', { 'packages': ['corechart', 'bar'] });
google.charts.setOnLoadCallback(drawStuff);
function drawStuff() {
var chartDiv = document.getElementById('chart_div');
var dtblData = new google.visualization.DataTable();
dtblData.addColumn('string', 'Names');
dtblData.addColumn('datetime', 'Intime');
dtblData.addColumn('datetime', 'Outtime');
for (var i = 0; i < data.length; i++) {
if (data[i].out_time.year == 0) {
dtblData.addRow([data[i].display_name, new Date(data[i].in_time.year, data[i].in_time.month, data[i].in_time.day, data[i].in_time.hours, data[i].in_time.minutes, data[i].in_time.seconds, data[i].in_time.miliseconds), null]);
}
else {
dtblData.addRow([data[i].display_name, new Date(data[i].in_time.year, data[i].in_time.month, data[i].in_time.day, data[i].in_time.hours, data[i].in_time.minutes, data[i].in_time.seconds, data[i].in_time.miliseconds), new Date(data[i].out_time.year, data[i].out_time.month, data[i].out_time.day, data[i].out_time.hours, data[i].out_time.minutes, data[i].out_time.seconds, data[i].out_time.miliseconds)]);
}
}
var dateinFormat = new google.visualization.DateFormat({ formatType: 'long', pattern: "dd/MM/yyyy HH:mm:ss ZZZZ" });
dateinFormat.format(dtblData, 1);
var dateOutFormat = new google.visualization.DateFormat({ formatType: 'long', pattern: "dd/MM/yyyy HH:mm:ss ZZZZ" });
dateOutFormat.format(dtblData, 2);
var materialOptions = {
//width: 900,
chart: {
title: '',
subtitle: 'Intime, Outime of your kids or staff'
},
series: {
0: { axis: 'In Time' }, // Bind series 0 to an axis named 'In Time'.
1: { axis: 'Out time' } // Bind series 1 to an axis named 'Out Time'.
},
axes: {
y: {
distance: { label: 'In Time' }, // Left y-axis.
brightness: { side: 'right', label: 'Out Time' }, // Right y-axis.
}
},
};
function drawMaterialChart() {
var materialChart = new google.charts.Bar(chartDiv);
materialChart.draw(dtblData, google.charts.Bar.convertOptions(materialOptions));
}
drawMaterialChart();
}
My problem is, on graph it is showing month as July but in data it is June. I am not getting why it is showing wrong month when I scroll mouse pointer on bar? Can someone help me to solve this? I think it might be time zone issue.
Please see screenshot.
The Month in JavaScript is Zero Based, so ranges from 0 to 11 (0 meaning January and 11 meaning December).
For your code, you may decrement the month value by 1 to solve this.
Something that may be useful:
Why does the month argument range from 0 to 11 in JavaScript's Date constructor?

Google Visualization Column Chart set a data column from query as role: "Style"

I have a Google Visualization Column Chart from a query that works fine. I can set the a columns with a style role after the query by using the code snippet below. It adds a new column to the query data and sets the role as "Style". This colors each of the column chart bars accordingly. But I want to be able to use one of my query columns "C" for example as the color code and not have to add it afterward. I can't seem to get this to work. Any ideas? I posted more of my code below the snippet so you can see where I'm coming from. Thanks so much guys for any help you can give. Brandon
var data = response.getDataTable();
data.addColumn({type: "string", role: "style" });
data.setCell(0,2,'red');
data.setCell(1,2,'orange');
data.setCell(2,2,'green');
data.setCell(3,2,'yellow');
// More code above this, but I ommited it.
function drawDashboard() {
var query = new google.visualization.Query(
'URL');
query.setQuery('SELECT A, B, C');
query.send(handleQueryResponse);
}
function handleQueryResponse(response) {
if (response.isError()) {
alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
var data = response.getDataTable();
data.addColumn({type: "string", role: "style" });
data.setCell(0,2,'red');
data.setCell(1,2,'orange');
data.setCell(2,2,'green');
data.setCell(3,2,'yellow');
// Create a dashboard.
var dashboard = new google.visualization.Dashboard(
document.getElementById('dashboard_div'));
// Create a range slider, passing some options
var scoreSlider = new google.visualization.ControlWrapper({
controlType: 'NumberRangeFilter',
containerId: 'filter_div',
options: {
filterColumnLabel: 'Class AVG'
}
});
var ClassFilter = new google.visualization.ControlWrapper({
controlType: 'CategoryFilter',
containerId: 'Classfilter_div',
options: {
'filterColumnLabel': 'Teacher Name','ui': { 'labelStacking': 'veClasscal','allowTyping': true,'allowMultiple': true
}
}});
// Create a Column Bar chart, passing some options
var columnChart = new google.visualization.ChartWrapper({
chartType: 'ColumnChart',
containerId: 'chart_div',
options: {
title: 'Math Proficiency by Class',
height: 320,
width: 500,
chartArea:{left:"10%",top:"10%",width:"80%",height:"60%"},
hAxis: {textStyle: {fontSize:14}, title: 'Teacher Name', titleTextStyle: {fontSize:14}, textStyle: {fontSize:14}},
vAxis: {minValue: 0, maxValue: 100, title: 'Math Proficiency AVG', titleTextStyle: {fontSize:14}, textStyle: {fontSize:14}},
legend: {position: 'none'},
animation: {duration:1500, easing:'out'},
colors: ['#a4c2f4','#3c78d8']
},
view: {columns: [0, 1, 2]}
});
// Define a table
var table = new google.visualization.ChartWrapper({
chartType: 'Table',
dataTable: data,
containerId: 'table_div',
options: {
width: '400px'
},
view: {columns: [0, 1,]}
});
// Establish dependencies, declaring that 'filter' drives 'ColumnChart',
// so that the column chart will only display entries that are let through
// given the chosen slider range.
dashboard.bind([scoreSlider], [table, columnChart]);
dashboard.bind([ClassFilter], [table, columnChart]);
// Draw the dashboard.
dashboard.draw(data);
}// More code below this, but I ommited it.
I'm not sure how you would add this to a column in the query but...
using a DataView with a calculated column should work...
Assumes the value you want to test is in the second column -- index 1
var data = response.getDataTable();
var view = new google.visualization.DataView(data);
view.setColumns([0, 1, {
type: "string",
role: "style",
calc: function (dataTable, rowIndex) {
if (dataTable.getValue(rowIndex, 1) < 0.69) {
return 'color: red;';
} else if ((dataTable.getValue(rowIndex, 1) >= 0.69) && (dataTable.getValue(rowIndex, 1) <= 0.79)) {
return 'color: yellow;';
} else {
return 'color: green;';
}
}
}]);