webix no scroll bar in treegrid - scroll

As title, no scroll bar even I did the setting below, I tried scroll:"y",scroll:"xy",scroll:true, scrollX:true, scrollY:true, etc. All failed.
I am thinking is it because the view is "treetable".
the code is as below:
let dataTree = function(){
const config={
// container:"testA", //the container is the div Id going to contain the grid, we will addd it # PlTreeGrid
view:"treetable",
//autowidth:true,
width:'100%',
//autoheight:true,
minHeight:530,
scroll:"xy",
scroll:"x",
scroll:"y",
scrollX:true,
scrollY:true,
columns:[
{ id:"id", header:"", css:{"text-align":"right"}, width:50, sort:"int"}, //,header:{ height:25 }
{ id:"value", header:"Film title", width:250,
template:"{common.treetable()} #value#", sort:"string" },
//{ id:"chapter", header:"Mode", sort:"string", template:"#value# <div class='edit'>Del</div>", width:300}//width:200, height:'auto'
{ id:"chapter", header:"Mode", sort:"string", width:'auto',fillspace:true}
],
onDblClick:{
"webix_remove_upload":function(ev, id){
console.log("ev,id");console.log(ev,id)
//this.remove(id);
}
},
data: [
{ "id":"1", "value":"The Shawshank Redemption", "open":true, "data":[
{ "id":"1.1", "value":"Part 1 l A", "chapter":"alpha"},
{ "id":"1.2", "value":"Part 2", "chapter":"beta", "open":true, "data":[
{ "id":"1.2.1", "value":"Part 1", "chapter":"beta-twin"}
]},
{ "id":"1.3", "value":"Part 3", "chapter":"gamma" }
]},
{ "id":"2", "value":"The Godfather", "data":[
{ "id":"2.1", "value":"Part 1", "chapter":"alpha" }
]}
]
}
let onItemDblClick = function(id, e, node){
alert("happy" + id, e, node);
}
return <TreeGrid config={config} onItemDblClick={onItemDblClick} />

No problems with the scroll bar.
Your code in snippet : http://webix.com/snippet/78021640
I've just removed any "scroll" attributes, to use the default one.
The scrollbar is only showed when needed. If you use the resizer to reduce the treetable size. The scrollbar will appear when part of content become hidden.

Related

Apollo is not letting me edit an object field because it is readonly, but I cannot just make a copy of it

I am not sure how I should set cart.items to a new array, I have already made a copy of the original cache because I learned Apollo does not let you directly edit the cache, but I am still getting the following error
Error: Cannot assign to read only property 'items' of object '#'
Do I need to make a copy of the items array? And if so how do I go about changing the array on the current objects item field?
Here are my console.logs
You can ignore the typename fields as they are irrelevant to the problem
addItem
{
"__typename": "Cart",
"items": [
{
"__typename": "CartItem",
"name": "Item 3"
},
{
"__typename": "CartItem",
"name": "Item 4"
},
{
"__typename": "CartItem",
"name": "New Item!"
}
]
}
carts
{
"carts": [
{
"__typename": "Cart",
"id": "1",
"items": [
{
"__typename": "CartItem",
"id": "1",
"name": "Item 1"
},
{
"__typename": "CartItem",
"id": "2",
"name": "Item 2"
}
]
},
{
"__typename": "Cart",
"id": "2",
"items": [
{
"__typename": "CartItem",
"id": "3",
"name": "Item 3"
},
{
"__typename": "CartItem",
"id": "4",
"name": "Item 4"
}
]
}
]
}
So it seems you need to remake the items array as well since items is its own gql object type the easiest way to do this was to do it all at once with a map.
Please note the comment as that was an important detail I learned
// IMPORTANT NOTE when updating the cache of a query you must return the
// same fields as the original query even if you aren't using them in the code
const GET_CARTS = gql`
query {
carts{
id
items{
id
name
}}} `;
const MUTATION = gql`
mutation AddItem($input:MutationAddItemInput!) {
addItem(input: $input){
items{
id
name
}
}
}
`;
const { loading, error, data } = useQuery(GET_CARTS)
const [addItem] = useMutation(MUTATION, {
// refetchQueries: [{ query: GET_CARTS }]
update(cache, { data: { addItem } }) {
// addItem is the response of the query of add item function
console.log({ addItem });
// #ts-ignore
let { carts } = cache.readQuery({ query: GET_CARTS });
console.log({ carts })
// make a new array out of the carts array and add the new item to the array if the id of the cart is 2
let newCarts = carts.map((cart: Cart) => {
if (cart.id === "2") {
return { ...cart, items: [...addItem.items] }
} else {
return cart
}
})
console.log({ newCarts });
cache.writeQuery({
query: GET_CARTS,
data: { carts: newCarts }
// data: { carts: [{ id: "1", items: [{ id: "2", name: "an item" }] }] }
})
}
})
And lastly you will call the addItem function from the use mutation hook

vega-lite scatter plot with hyperlink on each data point is not clicking

I am following this documentation on making href channel inside the encoding of a vega-lite scatter plot.
The data I am using is from an elasticsearch index. This is my code for the plot:
{
$schema: https://vega.github.io/schema/vega-lite/v4.json
data: {
url: {
%context%: true
index: my_index
body: {
size: 10000
}
}
format: {
property: hits.hits
}
}
transform: [
{
calculate: datum._source.price
as: price
}
{
calculate: datum._source.size
as: size
}
{
calculate: "'https://www.example.com/'+datum._source.id"
as: url
}
]
layer: [
{
selection: {
grid: {
type: interval
bind: scales
}
}
mark: {
type: circle
tooltip: true
}
encoding: {
x: {
field: size
type: quantitative
}
y: {
field: price
type: quantitative
}
href: {
field: url
}
}
}
]
}
The code works and on hovering over the scatter points, the mouse changes to a recognised link however the click itself does not work. why is that? the only differences from the documented example is that the data is from elasticsearch and I have a second layer in the plot.
How can I make the hyperlinks work?
To enable the click selection, you need to provide a selection of type: single. Try click the points in the link of editor or try the sample below:
{
"$schema": "https://vega.github.io/schema/vega-lite/v4.json",
"description": "Using `labelExpr` to show only initial letters of month names.",
"data": {"url": "data/seattle-weather.csv"},
"mark": "circle",
"transform": [
{
"calculate": "'https://www.google.com'",
"as": "url"
}
],
"selection": {"select": {"type": "single"}},
"encoding": {
"href": {"field": "url"},
"x": {
"timeUnit": "month",
"field": "date",
"axis": {"labelAlign": "left", "labelExpr": "datum.label[0]"}
},
"y": {"aggregate": "mean", "field": "precipitation"}
}
}

Dynamically change title of a chart in amcharts 4

How can I change the title of a loaded chart using javascript? The following doesn't work with external data
https://codepen.io/abdfahim/pen/zYOPvPx
var chart = am4core.createFromConfig({
"titles": [
{
"text": "ABCD",
"fontSize": 25,
"marginBottom": 10
}
],
"dataSource": {
"url": "https://s3-us-west-2.amazonaws.com/s.cdpn.io/t-160/sample_data_serial.json"
},
"xAxes": [
{
"type": "CategoryAxis",
"dataFields": {
"category": "year"
}
}
],
"yAxes": [
{
"type": "ValueAxis"
}
],
"series": [
{
"type": "ColumnSeries",
"name": "Cars",
"dataFields": {
"categoryX": "year",
"valueY": "cars"
}
}
]
}, "chartdiv", am4charts.XYChart);
function changeTitle()
{
chart.titles[0].text = "New Title";
}
AmCharts v4 uses lists for the majority of its array-like objects, so using subscripts will not work. It's recommended to use the accessor methods provided by the list to get at the object you want to change, such as getIndex:
chart.titles.getIndex(0).title = "New title"
Updated codepen
Just in case some one will hit my same issue, I found this solution working for me
chart.titles.getIndex(0).text = "new title";
this is particularly handy if you are going to refresh the chart each x seconds

Error in DataSource for Telerik MVC DropDownTree

My Telerik MVC Dropdowntree reports the error "Object doesn't support property or method 'level'" for the datasource.
Can someone take a look below and tell me what's wrong?
The MVC looks like this
#(Html.Kendo().DropDownTree()
.Name("dropdowntree")
.DataTextField("Name")
.DataValueField("Id")
.HtmlAttributes(new { style = "width: 100%" })
.DataSource(dataSource => dataSource
.Read(read => read
.Action("DoLayers2", "Dev")
)
)
)
My controller returns the following JSON:
[
{
"Id":1,
"ParentCategoryId":0,
"Name":"First Layer",
"items":[
{
"Id":2,
"ParentCategoryId":1,
"Name":"First SubLayer1",
"items":[
]
},
{
"Id":3,
"ParentCategoryId":1,
"Name":"First SubLayer2",
"items":[
]
},
{
"Id":4,
"ParentCategoryId":1,
"Name":"First SubLayer3",
"items":[
]
}
]
},
{
"Id":5,
"ParentCategoryId":0,
"Name":"Second Layer",
"items":[
{
"Id":6,
"ParentCategoryId":5,
"Name":"Second SubLayer1",
"items":[
]
},
{
"Id":7,
"ParentCategoryId":5,
"Name":"Second SubLayer2",
"items":[
{
"Id":8,
"ParentCategoryId":7,
"Name":"Sub -3",
"items":[
]
}
]
}
]
}
]
Apparently my post has too much code and not enough details so I have to write something foolish at the end of the post to trick the system into allowing me to post it. This is rather annoying.
I'm not sure you can return the whole tree and bind it to the dropdowntree...
If you check telerik's demo you see that they only returns one level at a time, so In your case I think it only wants first level Id:1 and Id:5 at first and then it will automatically ask for second level for each branch...
(Id:1 will return 2, 3, 4 and Id:5 will return 6, 7 and Id:7 will return 8)
You will also have to return if there are any children for each node:
[
{ "Id":1, "Name":"First Layer", "hasChildren": true },
{ "Id":5, "Name":"Second Layer", "hasChildren": true }
]
Hope it helps!

jsTree - loading subnodes via ajax on demand

I'm trying to get a jsTree working with on demand loading of subnodes. My code is this:
jQuery('#introspection_tree').jstree({
"json_data" : {
"ajax" : {
url : "http://localhost/introspection/introspection/product"
}
},
"plugins" : [ "themes", "json_data", "ui" ]
});
The json returned from the call is
[
{
"data": "Kit 1",
"attr": {
"id": "1"
},
"children": [
[
{
"data": "Hardware",
"attr": {
"id": "2"
},
"children": [
]
}
],
[
{
"data": "Software",
"attr": {
"id": "3"
},
"children": [
]
}
]
]
}
.....
]
Each element could have a lot of children, the tree is going to be big. Currently this is loading the whole tree at once, which could take some time. What do I have to do to implement on-demand-loading of child-nodes when they are opened by the user?
Thanks in advance.
Irishka pointed me in the right direction, but does not fully resolve my problem. I fiddled around with her answer and came up with this. Using two different server functions is done only for clarity. The first one lists all products at top level, the second one lists all children of a given productid:
jQuery("#introspection_tree").jstree({
"plugins" : ["themes", "json_data", "ui"],
"json_data" : {
"ajax" : {
"type": 'GET',
"url": function (node) {
var nodeId = "";
var url = ""
if (node == -1)
{
url = "http://localhost/introspection/introspection/product/";
}
else
{
nodeId = node.attr('id');
url = "http://localhost/introspection/introspection/children/" + nodeId;
}
return url;
},
"success": function (new_data) {
return new_data;
}
}
}
});
The json data returned from the functions is like this (notice the state=closed in each node):
[
{
"data": "Kit 1",
"attr": {
"id": "1"
},
"state": "closed"
},
{
"data": "KPCM 049",
"attr": {
"id": "4"
},
"state": "closed"
},
{
"data": "Linux BSP",
"attr": {
"id": "8"
},
"state": "closed"
}
]
No static data is needed, the tree is now fully dynamic on each level.
I guess it would be nice to display by default first level nodes and then the children will be loaded on demand. In that case the only thing you have to modify is to add "state" : "closed" to the nodes whose child nodes are going to be loaded on demand.
You might wish to send node's id in ajax call so you modify your code
"json_data": {
//root elements to be displayed by default on the first load
"data": [
{
"data": 'Kit 1',
"attr": {
"id": 'kit1'
},
"state": "closed"
},
{
"data": 'Another node of level 1',
"attr": {
"id": 'kit1'
},
"state": "closed"
}
],
"ajax": {
url: "http://localhost/introspection/introspection/product",
data: function (n) {
return {
"nodeid": $.trim(n.attr('id'))
}
}
}
}
From jsTree documentation
NOTE:
If both data and ajax are set the initial tree is rendered from the data string. When opening a closed node (that has no loaded children) an AJAX request is made.
you need to set root elements as tree data on page load and then you will be able to retrieve their children with an ajax request
$("#introspection_tree").jstree({
"plugins": ["themes", "json_data", "ui"],
"json_data": {
//root elements
"data": [{"data": 'Kit 1', "attr": {"id": 'kit1'}} /*, ... */], //the 'id' can not start with a number
"ajax": {
"type": 'POST',
"data": {"action": 'getChildren'},
"url": function (node) {
var nodeId = node.attr('id'); //id="kit1"
return 'yuorPathTo/GetChildrenScript/' + nodeId;
},
"success": function (new_data) {
//where new_data = node children
//e.g.: [{'data':'Hardware','attr':{'id':'child2'}}, {'data':'Software','attr':{'id':'child3'}}]
return new_data;
}
}
}
});
See my answer to a similar question here (the old part) for more details
I spended hours on this problem. Finally i got it that way:
$("#resourceTree").jstree({
"types": {
"default": {
"icon": "fa fa-folder-open treeFolderIcon",
}
},
"plugins": ["json_data", "types", "wholerow", "search"],
"core": {
"multiple": false,
"data": {
"url" : function(node){
var url = "rootTree.json";
if(node.id === "specialChildSubTree")
url = "specialChildSubTree.json";
return url;
},
"data" : function(node){
return {"id" : node.id};
}
}
},
});
rootTree.json:
[
{
"text": "Opened root folder",
"state": {
"opened": true
},
"children": [
{
"id" : "specialChildSubTree",
"state": "closed",
"children":true
}
]
}
]
specialChildSubTree.json:
[
"Child 1",
{
"text": "Child 2",
"children": [
"One more"
]
}
]
So i mark the node that become the parent of the ajax loaded subtree with an id, i watch for in the core configuration.
NOTE:
That node must have the "state" : "closed" parameter and it must have
the parameter "children" : true.
I am using jsTree.js in version 3.3.3
Above solution is all fine. Here I am also providing similar working solution and very simple for lazy loading of nodes using ajax call vakata. When your API works like
https://www.jstree.com/fiddle/?lazy
and for getting any child nodes
https://www.jstree.com/fiddle/?lazy&id=2
for explanation and for complete solution you can have a look at https://everyething.com/Example-of-jsTree-with-lazy-loading-and-AJAX-call
<script type="text/javascript">
$(function () {
$('#SimpleJSTree').jstree({
'core' : {
'data' : {
'url' : "https://www.jstree.com/fiddle/?lazy",
'data' : function (node) {
return { 'id' : node.id };
}
}
}
});
});
</script>

Resources