`<script>
Chart.pluginService.register({
beforeDraw: function (chart) {
var width = chart.chart.width,
height = chart.chart.height,
ctx = chart.chart.ctx;
ctx.restore();
var fontSize = (height / 114).toFixed(2);
ctx.font = fontSize + "em sans-serif";
ctx.textBaseline = "middle";
var text = chart.config.options.elements.center.text,
textX = Math.round((width - ctx.measureText(text).width) / 2),
textY = height / 2;
ctx.fillText(text, textX, textY);
ctx.save();
}
});
// chart1
var data = {
labels: ["Red", "Blue"],
datasets: [{
data: [50],
backgroundColor: ["#BEFF60", "#36A2EB"],
hoverBackgroundColor: ["#BEFF60", "#36A2EB"]
}]
};
var promisedDeliveryChart = new Chart(document.getElementById('myChart1'), {
type: 'doughnut',
data: data,
options: {
title: {
display: true,
text: 'OEE Chart'
},
elements: {
center: {
text: parseInt(<?php echo json_encode($OEE); ?>) + '%', //set as you wish
}
},
cutout Percentage: 85,
legend: {
display: false
}
}
});
</script>
`
I have few questions here.
I have already created Plugins Service and doughnut chart code where I standardize everything including having a text in between the doughnut chart - how can I small changes the Plugin Service so that where I can add picture send towards backwards and bring the text infront?? - Is it possible this same Plugin Service used after modification answers given by anyone where for other charts but dont want to add the picture and text as other charts will be either bar graph or line chart etc... can anyone guide me with these kind of things. I'm not sure how to do it.. any advice??
If lets say I want to do chartsJS for stepped line chart how is that?? I tried using the same Plugin Service but failed. if if each type of chart need to use different plugins I can do it... but the issue I will create their separate files and call them in PHP index folder (as the main file running the website but when I add the JavaScript link and add call the name from the JS file into the PHP index file failed. Hopefully someone can guide me or advice me on this
when i use the same PluginService(which is used for doughnut chart) i cannot show the results for barchart , line chart etc using the same PluginService when i pass <php json() file ?> from the database file i created to pass the data into data[] in chartJS
-dscsccsss\\\\\\
Related
I'm using mapbox api to display maps and directions. It's easy and it works well. I want to know how to update a marker's location on the map without refreshing a page. I read this page and this page in their documentation. I understand their examples but I'm not fully grasping how to implement realtime data in my codes without causing the page to refresh. Right now I have a script that updates the user location in the database every 15 seconds and returns longitude, latitude. I have the data now what? This is where I get highly confused. If you can help I would really appreciate. I have stripped down the codes for the sake of this question.
map.html
<script type="text/javascript" src="js/jquery.min.js"></script>
<script src="https://api.mapbox.com/mapbox-gl-js/v1.7.0/mapbox-gl.js"></script>
<link href="https://api.mapbox.com/mapbox-gl-js/v1.7.0/mapbox-gl.css" rel="stylesheet" />
<script type="text/javascript" src="geolocation.js"></script>
<!--Display map-->
<div id="map"></div>
<!--mapbox script-->
<script>
mapboxgl.accessToken ='pk.xxxxxxxx';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v11',
center:[$longitude,$latitude],
zoom: 15
});
var geojson = {
type: 'FeatureCollection',
features: [{
type: 'Feature',
geometry: {
type: 'Point',
coordinates:[$longitude,$latitude]
},
properties: {
title: '',
description: ''
}}]
};
geojson.features.forEach(function(marker) {
var el = document.createElement('div');
el.className = 'marker';
new mapboxgl.Marker(el)
.setLngLat(marker.geometry.coordinates)
.setPopup(new mapboxgl.Popup({ offset: 25 })
.setHTML('<h3>' + marker.properties.title + '</h3><p>' + marker.properties.description + '</p>'))
.addTo(map);
});
</script>
geolocation.js
setInterval(function () {
$.get("https://ipinfo.io", function (response) {
//variables
var user_id = $('.userid').val();
var geoLocation = response.loc;
//build array
var values ='geoLocation=' + encodeURIComponent(geoLocation)
+ '&userid=' + encodeURIComponent(user_id);
$.ajax({
type: 'POST',
url: 'https://mywebsite.com/mobile/geolocation.php',
data: values,
success: function (data) {
//returns new longitude
var lon = data.longitude;
//returns new latitude
var lat = data.latitude;
}
});
}, "jsonp");
}, 15000);
geolocation.php
$geoLocation= mysqli_real_escape_string($conn,$_POST['geoLocation']);//coordinates
$userid= mysqli_real_escape_string($conn,$_POST['userid']);//userid
//split coordinates into lat and longitude
$longitude = substr($geoLocation, strpos($geoLocation, ",") + 1); //put it first
$latitude =preg_replace('/^([^,]*).*$/', '$1', $geoLocation); // put it second
//insert new coordinates
$insertgeo = $conn->prepare("INSERT INTO user_geolocation (latitude,longitude,userid) VALUES(?,?,?)");
$insertgeo->bind_param("sss",$latitude,$longitude,$userid);
$insertgeo->execute();
$insertgeo->close();
//return answer to json
$result = array('message' => 'success',
'userid'=>$userid,
'longitude'=>$longitude,
'latitude'=>$latitude);
header('Content-Type: application/json');
echo json_encode($result);
The documentation resources you've linked are helpful, but I think this add live realtime data example is even better for your use case. If you zoom out of the map to see a larger region of the world, you will see a blue rocket icon marker which moves every two seconds without refreshing the page. In essence, this is exactly what you're looking to do! I'll explain how the example is working so that you can use the same logic to update your own marker locations without refreshing the page as well.
The rocket icon in this example is added to the map with a source and layer. The source specifies all the underlying data (in this case, the updating GeoJSON served by the https://wanderdrone.appspot.com URL), and the layer specifies how that data should be styled on the map. If you visit this URL, you'll see that the coordinates update each time you refresh the page.
So, the code below:
Gets the GeoJSON from the url every 2 seconds.
Gets the map's 'drone' source using Map#getSource.
Sets the data used by the source in (2) to be the GeoJSON at the url using Map#setData.
window.setInterval(function() {
map.getSource('drone').setData(url);
}, 2000);
Your current implementation is using HTML-based markers via GL JS's Marker component. So, instead of switching to this source-and-layer based approach outlined above, you could use the Marker#setLngLat method each time the user's location updates in your database. This also will not refresh the whole page.
I have used highcharts single line series graph. It seems to work all fine but when I resize the page (just to check responsiveness or just it on mobile). The values disappear. I can see error in console logs.
That's how I generate the chart
Highcharts.stockChart('nav-chart', {
tooltip: {
pointFormat:"{point.y:.3f}\u20ac"
},
chart: {
type: 'line',
zoomType: 'x',
pinchType: 'x',
panning: false,
<?php if (is_front_page()){ ?>
height: 700,
<?php } else { ?>
height: 500,
events: {
load: updateLegendLabel
}
<?php } ?>
},
updateLegendLabel has some computation that generates the labels.
var chrt = !this.chart ? this : this.chart;
chrt.update({
legend: {
useHTML: true,
symbolPadding: 0,
symbolWidth: 0,
symbolHeight: 0,
symbolRadius: 0,
labelFormatter: function() {
var lastVal = this.yData[this.yData.length - 1],
chart = this.chart,
xAxis = this.xAxis,
points = this.points,
avg = 0,
counter = 0,
min, max;
... there is some business logic down there
points var becomes null when I resize the page. Why is that so? Do I need to reupdate dataset or what?
Nesting Server and Client side logic is not good. Better is to seperate logic using like this. Bellow one is just for idea not a exact code. But can be fixed if you provide complete code separating your server logic from client side logic.
<script>
//before graph area started
var dataA = '<?php echo $dataA;?>';
var dataB = '<?php echo $dataB;?>';
//graph logic started
// your graph code which can use above variables
// but the variable need to be available can be evaluated from your draw script.
</script>
then use these variables in your graph script.
Because on resizing of browser, graph is redrawing and its looking data is not available when graph is redrawing. But if above logic will be used then data will be available on every redraw
the question I am asking is from a code-architecture point of view. I am preparing a report in php which is built with a string $message and then send via a php mail function.
For example the report is built in the php file like that(basically concatenates strings):
$message .= <<<HTML
</td>
</tr>
</tbody>
</table>
HTML;
Further, I would like to include a chart. However, trying the following example and sending it per mail I get no chart and an empty <div style="width:900px;min-height:500px"></div> ==$0 value.
$message.=<<<HTML
<tr valign="top" align="center">
<script type="text/javascript">
google.charts.load("current", {packages:['corechart']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Element', 'Density', { role: 'style' }],
['Copper', 8.94, '#b87333', ],
['Silver', 10.49, 'silver'],
['Gold', 19.30, 'gold'],
['Platinum', 21.45, 'color: #e5e4e2' ]
]);
var options = {
title: "Density of Precious Metals, in g/cm^3",
bar: {groupWidth: '95%'},
legend: 'none',
};
var chart_div = document.getElementById('chart_div');
var chart = new google.visualization.ColumnChart(chart_div);
// Wait for the chart to finish drawing before calling the getImageURI() method.
google.visualization.events.addListener(chart, 'ready', function () {
chart_div.innerHTML = '<img src="' + chart.getImageURI() + '">';
console.log(chart_div.innerHTML);
});
chart.draw(data, options);
}
</script>
<div id='chart_div'></div>
</tr>
HTML;
My guess is that javascript is not accepted by f.ex. GMail. Hence, I am trying to create a png beforehand which is then included in the report.
My preferred way of doing this would be the google charts library, however, it has no support for php and is entirely based on JavaScript.
Hence, my questions are:
How can I use the google chart library in my code?
Any other suggestions if above does not work?
I appreciate if you could provide an example!
Thx in advance!
Email clients strip Javascript, SVG, and other formats, so you can't use a chart library directly in email.
Your options include:
Use getImageURI to generate a PNG of your chart and send it to your server to be emailed. This is probably the best solution if you know a client will load every chart before it needs to be emailed.
Use a tool like wkhtmltoimage to "headlessly" render a webpage that displays your charts and save it as an image.
Use a chart image rendering web service like QuickChart to generate the chart image (fyi: this is an open-source project that I started).
QuickChart in particular is built on Chart.js, so you'd have to create a Chart.js chart definition as a string:
$chartConfig = "{
type: 'bar',
data: {
labels: ['Copper', 'Silver', 'Gold', 'Platinum'],
datasets: [{
data: [8.94, 10.49, 19.30, 21.45],
backgroundColor: ['#b87333', 'silver', 'gold', '#e5e4e2'],
}]
},
options: {
title: {
display: true,
text: 'Density of Precious Metals, in g/cm^3',
},
legend: {
display: false
}
}
}";
I've used a static string to match your example, but you can include dynamic variables like in any other PHP string.
Then encode this string into a URL:
$chartUrl = 'https://quickchart.io/chart?c=' . urlencode($chartConfig);
This URL returns a chart that looks like this:
Finally, add the chart to your email body as an HTML image tag:
$message .= "<img src=\"$chartUrl\"/>";
How I can insert array value in php and mysql from variable Var s1, s2, s3:
$(function () {
var s1 = [100, 200, 300]; //How to Get Value from mysql database
var s2 = [30, 80, 90]; //How to Get Value from mysql database
var s3 = [120, 90, 80]; //How to Get Value from mysql database
// Can specify a custom tick Array.
// Ticks should match up one for each y value (category) in the series.
var ticks = ['2010', '2011', '2012'];
var plot1 = $.jqplot('chart3', [s1, s2, s3], {
// The "seriesDefaults" option is an options object that will
// be applied to all series in the chart.
seriesDefaults: {
shadow: true, // show shadow or not.
renderer: $.jqplot.BarRenderer,
rendererOptions: {
fillToZero: true
}
},
// Custom labels for the series are specified with the "label"
// option on the series option. Here a series option object
// is specified for each series.
series: [
{label: 'Hotel'},
{label: 'Event Regristration'},
{label: 'Airfare'}
],
// Show the legend and put it outside the grid, but inside the
// plot container, shrinking the grid to accomodate the legend.
// A value of "outside" would not shrink the grid and allow
// the legend to overflow the container.
legend: {
show: true,
placement: 'outsideGrid'
},
axes: {
// Use a category axis on the x axis and use our custom ticks.
xaxis: {
renderer: $.jqplot.CategoryAxisRenderer,
ticks: ticks
},
// Pad the y axis just a little so bars can get close to, but
// not touch, the grid boundaries. 1.2 is the default padding.
yaxis: {
pad: 1.05,
tickOptions: {
formatString: '$%d'
}
}
},
grid: {
borderColor: '#000', // CSS color spec for border around grid.
borderWidth: 2.0, // pixel width of border around grid.
shadow: true // draw a shadow for grid.
}
});
// Bind a listener to the "jqplotDataClick" event. Here, simply change
// the text of the info3 element to show what series and ponit were
// clicked along with the data for that point.
$('#chart3').bind('jqplotDataClick',
function (ev, seriesIndex, pointIndex, data) {
$('#info3').html('series: ' + seriesIndex + ', point: ' + pointIndex + ', data: ' + data);
});
});
2 ways:
Ajax
Use: $.getJSON ( http://api.jquery.com/jQuery.getJSON/ )
var ses = {};
$.getJSON('page_adress.php', {variable_you_want_to_pass1: 'its value', variable_you_want_to_pass2: 'var 2 value'}, function(data) {
ses = data;
});
In your PHP:
<?php
$passed_var_1 = $_REQUEST['variable_you_want_to_pass1'];
//.... etc
//Here you get your data from mysql, cast it into array
header('Content-type: application/json');
echo json_encode($dbdata);
?>
So basically after request finishes you will have exact array you had in PHP transferred in JavaScript. Have in mind that this technique uses AJAX. If you want to avoid that, you will have to use second technique.
Dynamically Creating JS
Make PHP generate your javascript. In this case you would have in your main page
<script src="js_data.js.php" type="text/javascript"></script>
In your js_data.js.php file:
<?php
header("content-type: application/x-javascript");
$s1 = array(100,200,300);
//....
var s1 = [<?=implode(', ', $s1)?>],
s2 = [<?=implode(', ', $s2)?>],
s3 = [<?=implode(', ', $s3)?>];
?>
First method (w/o ajax & json)(untidy-way)
First fetch the value from database and have it in PHP variable.
Then put html element in page and assign the value to it.
Then use it in javascript using document.getElement method.
// assume that you have got value from database in $valueFrmDB.
$valueFrmDB;
Now, take html element(you might have to take more than one)
<input type="hidden" id="something" name="something" value="echo value of $valueFrmDB here" />;
Then, in javascript
var vfd = document.getElementById('something').value;
convert string to array
Second method(with ajax and json)(simple & correct but must know ajax and json)
Use ajax to fetch the values from database
Then use json to pass that values to javascript
simply you can do this by:
<?php
$query = mysql_query("SELECT * FROM attendence");
$results = array(array());
while($line = mysql_fetch_array($query)){
$results[] = $line;
}
?>
Javascript
<script type="text/javascript">
$(document).ready(function(){
var data = <?php echo json_encode($results); ?>; //array uses here
var plot1 = jQuery.jqplot ('chart1', [data],
{
seriesDefaults: {
renderer: jQuery.jqplot.PieRenderer,
rendererOptions: {
showDataLabels: true}
},
legend: { show:true, location: 'e' }
});
});
</script>
I am trying to plot a chart (Spline) using data that is dynamically generated from PHP. The JavaScript library I am using for this purpose is HighCharts.
The PHP generates an array of values in the format like
array(
array("1304294461000",69,"1304899261000",28),
array("1304294431000",3,"1304899161000",32)
)
which I am then passing onto a javascript array using json_encode. However, when I push these values as data, it doesn't seem to be working.
For example, here's an example with relevant code snippets like -
var namesArr = <?php echo json_encode($namesArr); ?>;
var progressTrendsData = <?php echo json_encode($progressTrendsData); ?>;
var chart;
var options = {
chart: {
renderTo: 'trendsDiv',
type: 'spline'
},
series: [{
name: '',
data: []
}]
};
for(var i=0;i<namesArr.length;i++) {
options.series.push({
name: namesArr[i],
data: progressTrendsData[i]
});
}
chart = new Highcharts.Chart(options);
The options contain other relevant data needed for the chart of course.
However, the only thing the above code is doing is plotting a single value at the date January 1 irrespective of the actual data that is being pushed.
I would tend to agree w/Mark on this. It is hard to tell exactly your data is supposed to end up looking like though. Try looking at the data loading portion of the ajax data example on the highcharts demo page.
UPDATE:
Try the following pseudocode:
var chart;
var options = {
chart: {
renderTo: 'trendsDiv',
type: 'spline'
},
series: [{
name: '',
data: []
}]
};
var seriesInfo=[];
seriesInfo[0]={"name":"Series A","data":[]};
seriesInfo[1]={"name":"Series B","data":[]};
//Loop over the series and populate the data
seriesInfo[0].data.push({x:<insert Series A timestamp>,y:<insert Series A y value>});
seriesInfo[1].data.push({x:<insert Series B timestamp>,y:<insert Series B y value>});
options.series.push(seriesInfo[0]);
options.series.push(seriesInfo[1]);
chart = new Highcharts.Chart(options);