I'm showing a chart using AmCharts4 with the URL option to load the data from a PHP file in JSON format. The problem is that sometimes I have an error. In the javascript console, I see the message: net::ERR_NETWORK_IO_SUSPENDED and in the chart the message: Unable to load file. I need to reload the page to load the chart again. I'm not able to find a similar problem on the web, therefore I would be very grateful for help.
const chartTotales = am4core.create('chart-disponibilidad-pastel', am4charts.PieChart);
chartTotales.dataSource.url = 'backend/production.php?opc=4';
chartTotales.dataSource.reloadFrequency = 6000;
const pieSeries = chartTotales.series.push(new am4charts.PieSeries());
pieSeries.dataFields.value = 'horas';
pieSeries.dataFields.category = 'tipo';
pieSeries.dataFields.test = '0 min';
pieSeries.slices.template.stroke = am4core.color('#fff');
pieSeries.slices.template.strokeOpacity = 1;
pieSeries.labels.template.text = '{category} {test} {value.formatDuration(\'hh:mm:ss\')} Hrs';
pieSeries.slices.template.tooltipText = '{category} {value.formatDuration(\'hh:mm:ss\')}';
const colorSetTotal = new am4core.ColorSet();
//D72906
colorSetTotal.list = ['#F6F623', '#498561', '#D72906'].map( function(color) {
// #ts-ignore
return new am4core.color(color);
});
You can try setting updateCurrentData to true, this shouldn't remove current data.
chartTotales.dataSource.updateCurrentData= true;
https://www.amcharts.com/docs/v4/reference/datasource/#updateCurrentData_property
Also check Network tab in browser tools to see what is in response from API.
Maybe you are hitting rate limiter.
Related
I have a form that takes in two text inputs and one image input (PictureBox). I can get the text inputs to show from local storage but I can't get the image to show. I have read the official docs but to no avail.
Form 1
NSBPage.appendChild(HeaderGlobal)
Button1.onclick=function(){
var myDetails1 = Input1.value;
var myDetails2 = Input1Copy.value;
localStorage.myDetails1 = PictureBox1.toDataURL();
console.log(localStorage);
$("#Toast1").toast("show");
Form1.reset();
ChangeForm(Form2)
}
Form 2
Form2.onshow=function(){
if(localStorage.myDetails1){
localStorage.setItem("myDetails1",localStorage.myDetails1);
const recentImageDataUrl = localStorage.getItem("myDetails1");
if(recentImageDataUrl){
PictureBox2.setAttribute("src",recentImageDataUrl);
}
}
Button1Copy.onclick=function(){
ChangeForm(Form1);
}
Local/Session Storage - JavaScript Tutorial
With help from this video and a few modification I finally got it to work.
Post 2
Form2.onshow=function(){
if(localStorage.myDetails1){
localStorage.setItem("myDetails1",localStorage.myDetails1);
const recentImageDataUrl = localStorage.getItem("myDetails1");
if(recentImageDataUrl){
Image1.src = recentImageDataUrl;
}
}
}
I am trying to dynamically load data into the body of my modal but cannot seem to get it to work.
function legend(mb) {
var url = mb;
var location = document.getElementById("choice2");
var gwc = location.options[location.selectedIndex].value;
if (gwc == 15)
{
title = ['<strong>Geomorphology</strong>'];
var url = 'http://localhost/geoserver/apib/wms?REQUEST=GetLegendGraphic&VERSION=1.1.0&FORMAT=image/png&WIDTH=20&HEIGHT=25&LAYER=apib:chamapwathi_block_gm&legend_options=fontSize:14';
}
}
Considering you have only the javascript tag there, I am adding a basic javascript solution. In my example, content changes on button click, which you would have to do when you get the data from your API call.
I have also added an id attribute to the modal body.
document.getElementById('left-modal-body').innerHTML = 'Hello';
Updated Example
I'm playing about with PDF.js, and can't seem to find a solution to my problem.
I have a PDF with a trim area and bleed, I need to get the trim area so that I can crop the PDF image data in HTML canvas.
I see that Acrobat has javascript that can return the Trim based on getPageBox("Trim"). Is there any equivalent in PDF.js?
I cant seem to find a reference when inspecting the Javascript PDF Object in the console.
I was able to get it after editing pdf.worker.js. Tested with 1.7.225. First, Add get trimBox() after get cropBox() like this:
get trimBox() {
var trimBox = this.getInheritedPageProp('TrimBox', true);
if (!isArray(trimBox) || trimBox.length !== 4) {
return shadow(this, 'trimBox', this.mediaBox);
}
return shadow(this, 'trimBox', trimBox);
},
Now, in handler.on('GetPage', function ... of WorkerMessageHandler, add a few lines like this:
handler.on('GetPage', function wphSetupGetPage(data) {
return pdfManager.getPage(data.pageIndex).then(function (page) {
var rotatePromise = pdfManager.ensure(page, 'rotate');
var refPromise = pdfManager.ensure(page, 'ref');
var userUnitPromise = pdfManager.ensure(page, 'userUnit');
var viewPromise = pdfManager.ensure(page, 'view');
var trimBoxPromise = pdfManager.ensure(page, 'trimBox'); //added
return Promise.all([
rotatePromise,
refPromise,
userUnitPromise,
viewPromise,
trimBoxPromise //added
]).then(function (results) {
return {
rotate: results[0],
ref: results[1],
userUnit: results[2],
view: results[3],
trimBox: results[4] //added
That's it. Now you can get the trim box in your app by page.pageInfo.trimBox.
In addition to the excellent answer from #Sangbok Lee,
If you use the latest PDF.js version, the this.getInheritedPageProp function has changed to
this._getInheritableProperty('TrimBox', true)
Figured it out.
For anyone else who may be interested in pdf.worker.js on line 2654 I added the following that exposed the trimBox.
tboxX = this.pageDict.map.TrimBox[0];
tboxY = this.pageDict.map.TrimBox[1];
tboxW = this.pageDict.map.TrimBox[2];
tboxH = this.pageDict.map.TrimBox[3];
I'm sure there is a neater way, but it works.
How to handle two or more linked Canvas-Charts with Chart.js? With this script the canvas-image is linked with a bigger version to present the big file in a fancybox or just two download it (right-click -> save). Easy.
<a HREF="#" id="canvas_link_1">
<canvas id="image1"></canvas>
</a>
<a HREF="#" id="canvas_link_2">
<canvas id="image2"></canvas>
</a>
To use toDataURL() with Chart.js it's a bit tricky, cause it will render the whole chart not before the animation has ended. If we do ask for the URL too early, it will present an empty (transparent) image. That's why we need onAnimationComplete in the options:
var options = {
onAnimationComplete: done
}
Later in the script, it will fire/change the new HREF, when the animation is over.
var ct1 = document.getElementById("image1").getContext("2d");
ct1.canvas.width = document.getElementById("image1").offsetWidth;
ct1.canvas.height = document.getElementById("image1").offsetHeight;
var Chart1 = new Chart(ct1).Line(lineChartData1,options);
function done() {
var url1=document.getElementById("image1").toDataURL();
document.getElementById("canvas_link_1").href=url1;
}
var ct2 = document.getElementById("image2").getContext("2d");
ct2.canvas.width = document.getElementById("image2").offsetWidth;
ct2.canvas.height = document.getElementById("image2").offsetHeight;
var Chart2 = new Chart(ct2).Line(lineChartData2,options);
function done() {
var url2=document.getElementById("image2").toDataURL();
document.getElementById("canvas_link_2").href=url2;
}
That works. But only with one canvas-image. If I delete the 2nd function done() it will work with the 1st canvas, if I delete the 1st function, only the 2nd canvas presents the url.
I think the problem is with "done", it's not a name, just like a situation, or? The "var options" is are general for all canvas-images (for sure I can change to options1 and options2 and also to "Line(lineChartData1,options1)" but without any change)... so "done" will fire all functions and - that's bad - appearently only the last function.
On the other side I cannot rename the entry of onAnimationComplete. It's null or done, nothing else. What is to do?
You can have different callbacks with different names. "done" is just an example name (a better name would probably be "completed").
For example - first create two option objects, one for each chart:
var options1 = {
onAnimationComplete: done1
};
var options2 = {
onAnimationComplete: done2
};
Then initialize the charts with those:
...
var Chart1 = new Chart(ct1).Line(lineChartData1, options1);
...
var Chart2 = new Chart(ct2).Line(lineChartData2, options2);
And finally define the callbacks:
function done1() {
var url = document.getElementById("image1").toDataURL();
document.getElementById("canvas_link_1").href = url;
}
function done2() {
var url = document.getElementById("image2").toDataURL();
document.getElementById("canvas_link_2").href = url;
}
Hope this helps (and that I understood the problem correctly) !
I have been using the Google API to get JSON data from my Blogger account and display and format blog posts on my own webiste.
It was working perfectly for weeks, and then suddenly, as of yesterday, the content stops displaying. The title, update (the date the post was updated), and the id, all come back just as they always have. Only the content stopped coming back.
I haven't changed the code in any way since first implementing it, and I looked for documentation to see if the API had changed, but didn't come across anything. So I am completely stumped as to why this one aspect of the code would suddenly stop working.
This is pretty much the entire Javascript that I use to get the JSON data. Is there something wroing with it?
function init() {
// Get your API key from http://code.google.com/apis/console
gapi.client.setApiKey('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx');
// Load the Blogger JSON API
gapi.client.load('blogger', 'v3', function() {
// Load the list of posts for code.blogger.com
var request = gapi.client.blogger.posts.list({
'blogId': 'xxxxxxxxxxxxxxxxxxx',
'fields': 'items(content,title,updated,id)'
});
request.execute(function(response) {
var blogger = document.getElementById("blogger");
var anchor = 0;
for (var i = 0; i < response.items.length; i++)
{
var bloggerDiv = document.createElement("div");
bloggerDiv.id = "blogger-" + i;
bloggerDiv.className = "bloggerItem";
$(bloggerDiv).append("<h2>" + response.items[i].title + "</h2>");
var date = response.items[i].updated;
date = date.replace("T", " ");
date = date.replace("+09:00", "");
var printDate = new moment(date);
$(bloggerDiv).append("<p><span class='byline'>" + printDate.format('dddd, MMMM Do YYYY, h:mm:ss a') + "</span></p>");
$(bloggerDiv).append(response.items[i].content)
bloggerAnchor = document.createElement("a");
bloggerAnchor.name = "blogger-" + response.items[i].id;
blogger.appendChild(bloggerAnchor);
blogger.appendChild(bloggerDiv);
anchor = anchor + 1;
}
// find out which anchor the user wanted...
var hashVal = window.location.hash.substr(1);
// ... then jump to that position:
location.hash = "#" + hashVal;
});
});
}
Now fetchBodies defaults is false instead of true. For this reason you need to add param fetchBodies=true.