I'm posting this in case anyone else ran into the same issue. As of Feb 2022 amCharts v5 is still very new and the demo code seems to need a little curation on amCharts' part i.e. Show us that the object needs to be declared with a type - AND TELL US WHICH TYPE TO USE!
I copied the code from this demo example verbatim
// Add bullet
// https://www.amcharts.com/docs/v5/charts/xy-chart/series/#Bullets
let circleTemplate = am5.Template.new({});
series0.bullets.push(function() {
let graphics = am5.Circle.new(root, {
fill: series0.get("fill"),
}, circleTemplate);
return am5.Bullet.new(root, {
sprite: graphics
});
});
and got the following error
Even the documentation page does not suggest specifying the type
I reached out to amCharts via their support system and got the following response:
Hi Adam,
How about specifying Circle as a generics for themplate?
let circleTemplate: am5Template<am5.Circle> Yours sincerely,
Martynas Majeris amCharts
First off am5Template is not valid, but I assumed he meant am5.Template
Second, his code is not complete and did not compile as-is.
I tried a few variations and the following worked:
// Add bullet
// https://www.amcharts.com/docs/v5/charts/xy-chart/series/#Bullets
let circleTemplate = am5.Template.new({}); // <-- demo code
// let circleTemplate3: am5Template<am5.Circle>; // <-- code provided by the support person
let circleTemplate2: am5.Template<am5.Circle> = am5.Template.new({}); // <-- WORKING modification of the suggested code
// let circleTemplate1: am5Template<am5.Circle> = am5.Template.new({}); // attempted variation of the suggested code
series0.bullets.push(function() {
let graphics = am5.Circle.new(root, {
fill: series0.get("fill"),
}, circleTemplate2); // <-- compiler now sees the object as the appropriate object type
return am5.Bullet.new(root, {
sprite: graphics
});
});
Another example (from the same demo) which requires the same modification, but with a different template type:
// Add bullet
// https://www.amcharts.com/docs/v5/charts/xy-chart/series/#Bullets
let starTemplate: am5.Template<am5.Star> =am5.Template.new({});
series1.bullets.push(function() {
let graphics = am5.Star.new(root, {
fill: series1.get("fill"),
spikes: 8,
innerRadius: am5.percent(70),
}, starTemplate);
return am5.Bullet.new(root, {
sprite: graphics
});
});
So yeah, maybe this will help someone who ran into the same issue as me. What would be REALLY nice is if they had Cope Pen examples that use TS and not just JS
Related
I'm using Keen.io ("version": "3.4.1") JavaScript SDK, along with their integration with C3.js, to produce a donut graph by using the code below. However, I don't want percentages, but rather absolute numbers. i.e. Not 25%, but 7.
From reading the docs and looking at examples (see "var c3gauge") and example, I thought you could modify the output by applying the chartOptions. That doesn't seem to be working. At this point, I feel like I'm doing something stupid I'm just not catching.
How do I display absolute values in my donut, not percentages?
var c3donut = new Keen.Dataviz()
.library('c3')
.chartType('donut')
.el(document.getElementById(elem))
.title("Awesome Sauce")
.parseRawData(data)
.chartOptions({
donut: {
label: {
format: function (value) {
console.log("I never fire, why?");
return value;
}
}
}
})
.render();
This is possible with keen-dataviz.js library. I've created a working example here: https://jsfiddle.net/bx9efr4h/1/
Here's part of the code that made it work:
var chart = new Keen.Dataviz()
.el('#chart')
.type("donut")
.chartOptions({
donut: {
label: {
format: function(value) {
return value;
}
}
}
})
.prepare();
keen-js works a little differently because c3.js is not the default dataviz library for it. This is likely why it isn't working like expected for you.
I'm trying to detect when a marker if found/lost in ar.js, while using a-frame.
From what I see in the source code, when the marker is found, a 'getMarker' event should be fired, moreover artoolkit seems to dispatch a markerFound event.
I tried to listen to those events on the <a-scene>, or on the <a-marker>, but it seems I'm either mistaken, or i need to get deeper to the arController, or arToolkit objects.
When i log the scene, or the marker, i only get references to the attributes, which don't seem to have the above objects attached.(like marker.arController, or marker.getAttribute('artoolkitmarker').arController)
Did anybody tried this and have any tips how to do this ?
PR303 introduces events when a marker is found and lost
markerFound
markerLost
You can use them by simply adding an event listener:
anchorRef.addEventListener("markerFound", (e)=>{ // your code here}
with a simple setup like this:
<a-marker id="anchor">
<a-entity>
</a-marker>
example here.
Please note, that as of sep 18', you need to use the dev branch to use the above.
ORIGINAL ANWSER - in case you want to do it manually
Detecting if the marker is found is possible by checking if the marker is visible when needed (other event, or on tick): if(document.querySelector("a-marker").object3D.visible == true)
For example:
init: function() {
this.marker = document.querySelector("a-marker")
this.markerVisible = false
},
tick: function() {
if (!this.marker) return
if (this.marker.object3D.visible) {
if (!this.markerVisible) {
// marker detected
this.markerVisible = true
}
} else {
if (this.markerVisbile) {
// lost sight of the marker
this.markerVisible = false
}
}
}
As adrian li noted, it doesn't work with a-marker-camera, only with a-markers
I went with a dirty hack diving into the internals, bear in mind that what I've provided might not suffice because the event get's called every time the marker is found, sadly I couldn't find an event to hook into for markers being lost.
const arController = document.querySelector("a-scene").systems.arjs._arSession.arContext.arController;
arController.addEventListener("getMarker", (evt) => {
const markerType = evt.data.type;
const patternType = 0;
//console.log("onMarkerFound!!");
if (markerType == patternType) {
//console.log("onMarkerFound out pattern!!");
//Do stuff...
}
});
using JxMaps (Java Swing) I draw a polyline.
This works fine.
Now I'd like to add arrwos to the lines. Anyone having an idea whats wrong with my code?
...
Symbol icon = new Symbol();
icon.setPath("google.maps.SymbolPath.FORWARD_CLOSED_ARROW");
IconSequence iconSequence = new IconSequence();
iconSequence.setIcon(icon);
iconSequence.setOffset("100%");
options.setIcons(new IconSequence[]{iconSequence});
// Applying ALL options to the polyline
polyline.setOptions(options);
No Arrows appear
If I look at the Google Maps API, it looks very similiar:
// var lineSymbol = {
// path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW
//
// new google.maps.Polyline({
//icons: [{
// icon: lineSymbol,
// offset: '100%'
//}],
Thanks
Possibility to use built-in symbol paths was introduced in JxMaps version 1.2.2. You can download it from official product page: www.teamdev.com/jxmaps
You can add this kind of image using following code:
Symbol icon = new Symbol();
icon.setPath(StandardSymbol.BACKWARD_CLOSED_ARROW);
Thanks.
Well, I've been reading the documentation and I believe that I'm calling functions and passing parameters correctly, but for the life of me I can't get this simple UI code to work.
I'm generating a UI for a Spreadsheet using the following code:
function checkOut() {
var app = buildUI();
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
spreadsheet.show(app);
}
function buildUI() {
var gui = UiApp.createApplication();
gui.setTitle("Check-Out/Check-In");
gui.setStyleAttribute("background", "lavender");
// Absolute panel for setting specific locations for elements
var panel = gui.createAbsolutePanel();
// Equipment ID#s Label
var equipmentIDLabel = gui.createLabel("Equipment ID#s");
equipmentIDLabel.setHorizontalAlignment(UiApp.HorizontalAlignment.CENTER);
equipmentIDLabel.setSize("20px", "125px");
equipmentIDLabel.setStyleAttributes({background: "SteelBlue", color: "white"});
// Add all components to panel
panel.add(equipmentIDLabel, 10, 0);
gui.add(panel);
return gui;
}
function getUIdata(eventInfo) {
// I know how to get the data from each element based on ID
}
It generates the Absolute Panel correctly when checkOut() is called, but the EquipmentIDLabel is never added to the panel. I am basing the code on the simplistic design I created in the GUI builder (that will be deprecated in a few days, which is why I am writing the code so that I can change it later):
So what exactly is going wrong here? If I can figure out how to add one element, I can infer the rest by looking at the docs. I've never been any good at GUI development!
You could maybe use grid as an interesting alternative... here is an example :
// define styles
var labelStyle = {background: "SteelBlue", color: "white",'textAlign':'center','line-height':'20px','vertical-align':'middle','font-family':"Arial, sans-serif",'fontSize':'10pt'};// define a common label style
var fieldStyle = {background: "white", color: "SteelBlue",'font-family':"Courrier, serif",'fontSize':'11pt'};// define a common label style
function checkOut() {
var app = buildUI();
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
spreadsheet.show(app);
}
function buildUI() {
var gui = UiApp.createApplication();
gui.setTitle("Check-Out/Check-In");
gui.setStyleAttribute("background", "lavender");
var panel = gui.createAbsolutePanel().setStyleAttribute('padding','10px');
var grid = gui.createGrid(4,2).setWidth('300').setCellPadding(10);//define grid size in number of row & cols
var equipmentID = ['equipmentIDLabel','equipmentIDLabel1','equipmentIDLabel2','equipmentIDLabel3'];// define labels in an array of strings
for(var n=0 ;n<equipmentID.length ; n++){;// iterate
var equipmentIDLabel = gui.createLabel(equipmentID[n]).setWidth('125').setStyleAttributes(labelStyle);
var equipmentIDField = gui.createTextBox().setText('Enter value here').setName(equipmentID[n]).setSize("125", "20").setStyleAttributes(fieldStyle);
grid.setWidget(n,0,equipmentIDLabel).setWidget(n,1,equipmentIDField);
}
gui.add(panel.add(grid));
return gui;
}
It looks like the absolute panel offset method is a little capricious and take control of your positioning, in my tests I have been able to position panels that are visible in the following way:
panel.add(equipmentIDLabel);
panel.add(equipmentIDField,150,0);
panel.add(otherLabel);
panel.add(otherField, 150, 20);
Try it out with trial and error, you may get the UI you need, if not I would move to an alternate layout, verticalPanel is a little better behaved and of course you can use forms as well.
Another small bug is that you inverted the length and hight in equipmentIDLabel.setSize("20px", "125px");
Let me know if I can be of more assitance
The specific problem in your code is the following line :
// Add all components to panel
panel.add(equipmentIDLabel, 10, 0);
Simply change it to : panel.add(equipmentIDLabel);
..and you will see the field (at position 0,0).
As patt0 observes, you can then add OTHER components and use positioning. It seems to be a limitation of adding the first field to an absolutePanel.
Of course, the Google Script gui is now deprecated (since December 2014) but I was interested to try your code and see that it still basically executes (as at Feb 2016).
I've successfully implemented a bit of code that strips all HTML from a pasted string using stripTags(). My next goal is to mark a few tags with white flags so they get ignored on 'paste' event using .wrap() to augment the function.
I'm using prototype.js as a framework and have slowly been working through the growing pains of learning both the framework and javascript, but this issue has presented a bit of a roadblock.
I've googled around a bit and found what looks like two great solutions, but I don't seem to be implementing them correctly.
Found solutions:
http://perfectionkills.com/wrap-it-up/ (function to indicate tags to remove)
and
http://pastebin.com/xbymCFi9 (function to allow tags to keep)
I pretty much copied and pasted from the latter.
If I pull the 'br' from the code, then the regex is ignored and all html is stripped. If I leave it, nothing gets pasted.
Here is what I've pieced together (and I feel silly for not being able to figure this out!).
String.prototype.stripTags = String.prototype.stripTags.wrap(
function(proceed, allowTags) {
if (allowTags) {
if (Object.isString(allowTags)) allowTags = $w(allowTags)
this.gsub(/(<\/?\s*)([^\s>]+)(\s[^>]*)?>/, function(match) {
if (allowTags.include(match[2].toLowerCase()))
return match[1] + match[2] + match[3] + '>'
})
} else {
// proceed using the original function
return proceed();
}
});
WysiHat.Commands.promptLinkSelection = function() {
if (this.linkSelected()) {
if (confirm("Remove link?"))
this.unlinkSelection();
} else {
var value = prompt("Enter a URL", "http://www.alltrips.com/");
if (value)
this.linkSelection(value);
}
}
document.on("dom:loaded", function() {
var editor = WysiHat.Editor.attach('event_desc');
var toolbar = new WysiHat.Toolbar(editor);
editor.observe("paste", function(event) {
var el = $(this);
setTimeout(function() {
var pText = el.innerHTML.stripTags('br');
//alert(pText);
$('event_desc_editor').update(pText);
$('event_desc').setValue(pText);
}, 0);
});
(You may recognize the WysiHat code from 37Signals text editor)
note: you can see the alert commented out. If I do alert the ptext, I get 'undefined' returned.
So I've given up on and moved to a regex solution:
el.innerHTML.replace(/<(?!\s*\/?\s*p\b)[^>]*>/gi,'')