AMCharts - Dynamically add children to tree map - amcharts

I am thoroughly enjoying AMChart's many features but I couldn't find any way to dynamically add some children to a treemap.
I am trying to load additional children on "hit" for each element
for (var i = 0; i < this.maxDepthLevel; i++) {
const series = this.chart.seriesTemplates.create(i);
series.columns.template.events.on("hit", async function(ev) {
const data = ev.target.dataItem.dataContext;
children = await api.getChildrenOf(data.id);
ev.target.dataItem.treeMapDataItem.children.values.push(...children);
});
}
^ this doesn't work and when doing this and then zooming out, I get
I even tried changing the underlying data and then calling
this.chart.invalidateRawData();
but to no avail.
Does anyone have any experience with adding such dynamic children to a tree map?
I cannot simply load everything upfront, there are far too many possible layers of depth unfortunately and the request will be too large!

Rather than directly pushing child items to children values you need to do it like this :
for(var index=0; index < children.length; index++){
var newChildDataItem = new am4charts.TreeMapDataItem();
newChildDataItem.value = children[index].value;
newChildDataItem.name = children[index].name;
newChildDataItem.color = ev.target.dataItem.dataContext.color;
ev.target.dataItem.dataContext.children.insert(newChildDataItem);
}

Related

explain by what criteria threejs assigns id to Obejct3d

there is an array of objects in the json file, the objects have current information about *.obj files and their paths. when referring to json as [...jsondata] array and calling each object in the scene through for(i=0; i<jsondata.lenght; i++) all are right, all objects are called up and the stage is lined up. But! The object.id assignment order is not the same as in the jsondata array, and for some reason always starts with id: 96. And most importantly id is not editable, and for me it is very important that the order in the scene was the same as in json. Can someone explain by what criteria threejs assigns this id?
Don't rely on the Object.id property to maintain any desired order. These are automatically generated, and they can add up quickly if any of your *.obj files have children, grandchildren, lights, cameras, etc.
For example, if you want 2 cars with id = 1 & 2, each part of the car could have a new id, depending on how it was built:
window: 2,
wheels: 3,
headlamps: 4,
light: 5
By the time you start car # 2, you're already on id = 6.
If you want to store a specific attribute in certain objects, you could use the .userData property to store it.
for(let i = 0; i < jsondata.length; i++) {
object[i].userData.order = i;
}
Or just create your own array to access them in order later:
const orderedItems = [];
for(let i = 0; i < jsondata.length; i++) {
orderedItems.push(someObject);
}

Iterate over child nodes on a Telerik MVC TreeView

I have a Telerik MVC Treeview that i am trying to get the child nodes for using JQuery. I'm using the "hasChildren" property to tell me if the node has any children and that's working fine. But I can't seem to figure out the node property that will let me iterate over the child nodes. "nodes[i].children.view()" gives me an empty array but it should be an array of the child nodes according to this Kendo doc.
var productTreeView = $("#treeviewProducts").data("kendoTreeView");
var nodes = productTreeView.dataSource.view();
for (var i = 0; i < nodes.length; i++) {
if (nodes[i].hasChildren) {
var childrenNodes = nodes[i].children.view();
for (var x = 0; x < childrenNodes.length; x++) {
...
}
}
}
UPDATE: The code above works fine if the node with children is expanded but does not work when the node with children is collapsed because LazyLoading for child nodes was enabled (thanks DontVoteMeDown). Either turn that off or expand all nodes before running the code (productTreeView.expand(".k-item");).

Polymer core-animation-group imperative example?

I'm fairly new to Polymer and struggling to get some animations to work imperatively. My page displays a grid of cards. When one is clicked, I want the rest to move off screen.
I can get the cards to move one at a time in code, but since they all need to move in parallel, I think I need a core-animation-group to run them. But...
I can't figure out the syntax for creating a core-animation-group in code, and there doesn't seem to be a "play()" method...?
I'd be very, very grateful for a quick example.
TIA
The documentation on core-animation-group is a bit lackluster, but it is possible to create and play a core-animation-group using only JavaScript. Create your core-animation-group with new CoreAnimationGroup(). Then add child animations with animGroup.appendChild(coreAnim). Finally, play the group with animGroup.play().
You say you want to animate an indeterminate number of cards in parallel. Try something like this:
var cards = document.querySelector("#cards-wrapper").children;
var anim = new CoreAnimationGroup();
anim.type = "par"; // Display child animations in parallel.
anim.duration = 200; // Milliseconds
var cardAnimKeyframes = [
// CSS properties {propName: "value"}
{opacity: 1},
{opacity: 0},
];
for (var i = 0; i < cards.length; i++) {
var childAnim = new CoreAnimation();
childAnim.target = cards[i];
childAnim.keyframes = cardAnimKeyframes;
anim.appendChild(childAnim); // This is critical.
}
// Then, when you are ready...
anim.play();
Hope this helps :D

Unable to create accurate copy of a Kinetic.js stage / layer

I'm trying to build in a change history, rather than a diff style history, I've opted to save the entire object.
This becomes problematic because each copy of the object updates along side the original object.
The Kinetic.Node.clone method seemed like the right thing for me, but it doesn't seem to do what I expect it to do.
Pseudocode:
var History = function(){
var h = this;
h.history = [];
h.pointer = -1;
h.save = function() {
h.history = h.history.slice(0,h.pointer);
h.history.push(im.Stage.createCopy());
h.movePointer(1);
};
h.movePointer = function(diff) {
h.pointer += diff;
(h.pointer < 0 && (h.pointer = 0));
(h.pointer >= h.history.length && (h.pointer = h.history.length-1));
return h.pointer;
};
h.render = function() {
im.Stage = h.history[h.pointer].createCopy();
im.Stage.draw();
};
h.undo = function() {
h.movePointer(-1);
h.render();
};
h.redo = function() {
h.movePointer(1);
h.render();
};
};
How can I create an accurate copy of the stage?
The best method to build up a history system is to store your layers/elements after each operation into an array as serialized values, using layer.toJSON() .
If you use images on layers and eventhandlers that you want to display/work after you restore anything from the history then you will have to reattache images and eventhandlers to the objects/layers/etc because toJSON() does not store images and eventhandlers as it would have been too large data stored. Build up your history like this:
first, try to use projeqht's answer on this question .
second you will have to reattach the images and eventhandlers. With a trick given by markE on this question you can easily handle it.
The best thing for an accurate representation is to do:
var layers = stage.getChildren();
to get the layers. Then do:
var layerChildren = new Array();
for(var i=0; i<layers.length; i++)
layerChildren[i] = layers.getChildren();
each time you want to save a state.
This will store all your layers and their children in an array. Fairly efficient and accurate.
Now you just have to save the list of layers and list of children somewhere and then you can move back and forth between states.

Google Script Image Resizing

I'm trying to make a script that will resize the images in a google doc. What I have is:
var imgs = currentDoc.getImages();
for (var i = 1; i < imgs.length; i++)
{
cell = row.insertTableCell(1);
imgNew = imgs[i].setWidth(365);
cell.insertImage(1, imgNew.getBlob());
}
The image gets inserted correctly but the size does not change regardless of what I set the width to. Since the image is going into a cell (width=370), is it possible to just make the image take up 100% of the width and scale the height proportionally? If not I can deal with manually setting the number of pixels but that is not working either. Any ideas?
The problem is that the image size should be changed after it is inserted to a table. The following code works correctly
function test() {
var doc = DocumentApp.openById('here_is_doc_id');
var imgs = doc.getImages();
var table = doc.getTables()[0];
for (var i = 0; i < imgs.length; i++) {
var row = table.appendTableRow();
var cell = row.insertTableCell(0);
var imgNew = imgs[i].copy();
cell.insertImage(0, imgNew);
imgNew.setWidth(365);
}
}
Please mention, that array indexes, cells numbers, etc. start from 0 and not 1.
Just as an FYI, you don't need to call getBlob()... anything that has a getBlob() can be passed in directly wherever a Blob is needed.
Have you tried:
imgs[i].attr('width', '370');
Or try assigning a class that has width: 100%

Resources