I would like to display "Loading" when my chart's data are fetching and if there's no data - I'd like to display "No Data". I tried with loading and noData properties from Highcharts API, but the effect is always the same - "Loading" overlaps with "No Data", and after some time "Loading" vanishes. Could anyone give me example where these two properties works fine when they are used simultaneously?
I prepared two demos shows how to achieve it.
In the first, the chart is initialized with the series config (the data is an empty array) and I used the setTimeout as a simulation of fetching data. When data comes the series is updated depending if a new data is an empty array or not.
Demo: https://jsfiddle.net/BlackLabel/1dg2zyus/
setTimeout(function() {
let data = [];
//let data = [1,2,3,4,5];
if (data.length) {
chart.series[0].update({
data: data
})
}
chart.hideLoading();
}, 1000)
In the second demo - the chart is initialized without the series config. Again, setTimeout is used as a simulation. When data comes - we can use the addSeries feature this time to add the data to the chart.
Demo: https://jsfiddle.net/BlackLabel/97jd2v5e/
setTimeout(function() {
let data = [];
//let data = [1,2,3,4,5];
if (data.length) {
chart.addSeries({
data: data
})
}
chart.hideLoading();
}, 1000)
API: https://api.highcharts.com/class-reference/Highcharts.Chart#addSeries
API: https://api.highcharts.com/class-reference/Highcharts.Series#update
Related
I am using PDFJS and the viewer. I do however have the problem that annotation are not shown correctly like the are in the pdfs demo viewer https://mozilla.github.io/pdf.js/web/viewer.html.
Annotation correctly displayed in pdfs demo viewer:
Here is now it is displayed in my app using Chrome:
Here is how it is displayed I Safari using my app:
This is now I initialise the pdfs viewer:
function initPdfjs() {
// Enable hyperlinks within PDF files.
pdfLinkService = new (pdfjsViewer as any).PDFLinkService({
eventBus,
});
// Enable find controller.
pdfFindController = new (pdfjsViewer as any).PDFFindController({
eventBus,
linkService: pdfLinkService,
});
const container = document.getElementById('viewerContainer');
if (container) {
// Initialize PDFViewer
pdfViewer = new (pdfjsViewer as any).PDFViewer({
eventBus,
container,
removePageBorders: true,
linkService: pdfLinkService,
findController: pdfFindController,
});
// pdfViewer.textLayerMode = Utils.enableTextSelection() ? TextLayerMode.ENABLE : TextLayerMode.DISABLE;
pdfViewer.textLayerMode = TextLayerMode.ENABLE_ENHANCE;
// See https://github.com/mozilla/pdf.js/issues/11245
if (Utils.isIos()) {
pdfViewer.maxCanvasPixels = 4000 * 4000;
}
pdfLinkService.setViewer(pdfViewer);
return;
} else {
console.error(`getElementById('viewerContainer') failed`);
}
}
What do I need to do in order to get the annotations to display correctly in my app?
I got it working. I don't know if it is the right way, but I post it in case somebody can use it.
First I setup webpack to copy the content from ./node_modules/pdfjs-dist/web/images to my dist folder so the images got included. That solved all the display errors except {{date}}, {{time}}.
new CopyPlugin({
patterns: [
{ from: './node_modules/pdfjs-dist/web/images', to: '' },
{ from: './l10n', to: 'l10n' },
],
}),
To solve the {{date}}, {{time}} problem I set up a localisation service. I did that by copying the file ng2-pdfjs-viewer-master/pdfjs/web/locale/en-US/viewer.properties to ./l10n/local.properties in my project. Then it is copied to the dist folder by above webpack plugin. I then setup the l10n service in my pdfjs by adding this code:
// initialize localization service, so time stamp in embedded comments are shown correctly
l10n = new (pdfjsViewer as any).GenericL10n('en-US');
const dir = await l10n.getDirection();
document.getElementsByTagName('html')[0].dir = dir;
and added l10n to PDFViewer initialisation:
// Initialize PDFViewer
pdfViewer = new (pdfjsViewer as any).PDFViewer({
eventBus,
container,
removePageBorders: true,
linkService: pdfLinkService,
findController: pdfFindController,
l10n,
});
And now annotations is shown correctly:
What I find a bit weird is the date format. I used en-US as locale, so I would expect it to be mm/dd/yyyy (American way), but it is dd/mm/yyyy (like a dane would prefer it). I have tried to fool around with the date settings on my Mac and language settings in Chrome, but it doesn't look like it has any effect, so I don't know what to do if an American customer complains.
I have an iOS app in swift that is successfully displaying a map using the Mapbox iOS library.
I also have a some GeoJSON data, as a dictionary, which I have pulled from a Redis database. I have successfully printed this data in the Xcode console after pulling it and it looks like this:
Optional(["city": chicago, "data": {
features = (
{
geometry = {
coordinates = (
"-87.86810699999999",
"41.966483"
);
type = Point;
};
properties = {
weight = 1;
};
type = Feature;
},
{
geometry = {
coordinates = (
"-87.866905",
"41.96288"
);
type = Point;
};
properties = {
weight = 3;
};
type = Feature;
},
/*and so on with many more point features...*/
The line that converts the raw array returned from the Redis query into the above dictionary in the code is the following:
let geojson_dict = (message[0] as! String).convertToDictionary()
I want to now put this GeoJson data over my MapBox map view defined in the code as:
var mapBoxView: MGLMapView?
at the point I have the GeoJson data the mapBoxView is added as a view and visible.
This example touches on how to do this:
https://docs.mapbox.com/ios/maps/examples/heatmap-example/
but the GeoJson data has a different structure and it is not dealing with a dictionary in memory but rather pulling the GeoJson from a url. This coupled with the example being poorly documented/commented makes it hard to adapt to my particular use case.
I tried the following:
let feature = try! MGLShape(data: geojson_dict as Data, encoding: String.Encoding.utf8.rawValue) as! MGLShapeCollectionFeature
but this doesn't seem to want to work with geojson_dict being a dictionary, nor would it add a heat map to the mapbox view.
Your geojson_dict["data"] is your GeoJson dictionary. I suppose you already instantiate your mapboxView and added to your viewController (very much like MapBox's Heatmap sample), so here is how you may instantiate your MGLShapeSource.
func mapView(_ mapView: MGLMapView, didFinishLoading style: MGLStyle) {
guard let dict = geojson_dict else {
return
}
var source : MGLShapeSource
do {
let json = try JSONSerialization.data(withJSONObject: dict[“data"], options: JSONSerialization.WritingOptions())
let shape = try MGLShape(data: json, encoding: String.Encoding.utf8.rawValue)
source = MGLShapeSource(identifier: dict[“city”], shape: shape, options: nil)
mapView.style.addSource(source)
} catch {
// handle any exceptions here
}
// Continue defining your heat layer as on Mapbox sample
…
}
I am working with a UITableView which contains an image and some labels.
The text is loading from one server and the image is downloaded from another server. The image URL is dependent on the text value response but I have to show them in one cell. What I have to do is combine those data after they have loaded and to then to show them.
What could be the right approach?
You can combine response of two requests using DispatchGroup:
let group = DispatchGroup()
var text: String?
var image: UIImage?
group.enter()
requestText(completion: { response in
text = // extract text from response
group.leave()
})
group.enter()
requestImage(completion: { response in
image = // extract image from response
group.leave()
})
group.notify(queue: DispatchQueue.main, execute: {
let textWithImage = (text, image)
// show data in table view
})
You can simply display the textual data first than as soon as a image is downloaded you can than map that image to the textual data by having some common id in both the responses and reload that particular cell . In this way the user will be able to see the textual data and after some milliseconds the images will also show up nicely.
I have searched the forum. I got very close answers and I am able to partly solve the problem I am facing, but need a little more clarity whether this is possible or any available option is there. The problem is like below.
I am using SAP UI5.
I have DatePicker in one screen and there the date pattern is shown using the code below:
this._enddatepicker = new mii.control.miiDatePicker({ value: { path: "/dateValue", type: new sap.ui.model.type.Date({ pattern: "MM-dd-yyyy" })} });
So now it shows 08-29-2000
But I want to show the dates As per Local PC/System Date; So if Date is shown in toolbar as 2000-08-29, in the screen it needs to show in the same format. For that I have used the below code:
this._enddatepicker = new mii.control.miiDatePicker({ value: { path: "/dateValue", type: new sap.ui.model.type.Date({ setLocal:oLocale })} });
But here is the problem: it is taking the LongDate format. So if the long date format is dd-MMMM-yyyy it shows 29,August 2000. but the Date in the toolbar is in short date format dd-MM-yyyy, which I need to display on the screen.
Are there any options or ways to show the same?
this._enddatepicker = new mii.control.miiDatePicker({
value: {
path: "/dateValue",
type: new sap.ui.model.type.Date({
setLocal: oLocale
}),
// you can specify style as long/short/medium/full
formatOptions: {
style: 'medium'
}
}
});
Titanium / for an iOS App:
How can I manage to take a photo, and then use this one later in a new function to for example show the photo, and put a slightly larger duplicate of it with a transparency on top of itself?
Note that I tried to edit the answer from Mitul Bhalia with the following, but the edit got knocked back. So here's how you do it:
After taking the image, you can store it as a variable in the global object, Alloy.Globals. You can then access this else where or later on in your app.
For example:
takePhotoButton.addEventListener('click', function(){
Titanium.Media.showCamera({
success:function(event) {
if(event.mediaType === Ti.Media.MEDIA_TYPE_PHOTO) {
// Store the file in a variable
var image = event.media;
// Store the image in the global object
Alloy.Globals.temporaryImage = image;
} else {
alert("got the wrong type back ="+event.mediaType);
}
},
...
And somewhere else in your app, after the image has been stored, for example:
var anImage = Ti.UI.createImageView({ image: Alloy.Globals.temporaryImage })
Also note that extensive use of the global object can cause memory issues, so try not to overdo it.
If you want to save photo then you can use Alloy.Globals to save data globally so you can use it later.
Alloy.Globals.photo = blob object;
Here is how I am currently solving my problem:
takePhotoButton.addEventListener('click', function(){
Titanium.Media.showCamera({
success:function(event) {
if(event.mediaType === Ti.Media.MEDIA_TYPE_PHOTO) {
// Store the file in a variable
var image = event.media;
var filename = 'myPhoto.jpg';
takenPhoto = Titanium.Filesystem.getFile(Titanium.Filesystem.applicationDataDirectory, filename);
takenPhoto.write(image);
} else {
alert("got the wrong type back ="+event.mediaType);
}
},
...
and then later I can use takenPhoto to show the picture I have taken with the camera.
But I do not really know if this is the best way and if it is even correct, as I do not use 'var' to initiate takenPhoto. But if I use 'var' I cannot use takenPhoto outside of the function.