amsik / liquor-tree Goto Github PK
View Code? Open in Web Editor NEWTree component based on Vue.js
License: MIT License
Tree component based on Vue.js
License: MIT License
I'm currently make a file browser with lazy load. The file tree data is stored in Vuex modules. I found using your demo in #39 will store file tree data and node text in Vuex. What I want is store expanded state in Vuex also, so that when I load new data into Vuex the nodes won't collapsed automatically.
Just copy the demo into jsfiddle. Line 152 in HTML editor, set t.state = { expanded: true }
, but the nodes will collapse (expected all nodes to be expanded).
So the question is can I store node state in Vuex?
Thanks!
The tree is not being rendered on IE11, knowing that it's working perfectly on other browsers.
Hi~
I want to remove a node's all childrens but not itself, i use node.removeChild()
, but it's not working. What is the correct way?
ok so i have an async of the root working, but when i choose the children modules, the fetch data method doesn't get called again? is this by design or am i missing something? looking at your async example with data-root, data-1,data-2, it seems like it would call the fetch on selection?
thanks,
matt
Using the current API, is it possible to get the path to a given node ?
Let's say I have this kind of structure.
How can I get the path to the "Child Node 1.1.1.1.1 [node in question]" ?
Is any way to prevent indeterminate node to recurse down check?
Actually i don't want that to be indeterminate but in fact a checked node.
So i don't want the parent node to uncheck if all his children are unchecked is there any options for checkbox to prevent this?
Thanks
The events demo references a feature of "editing a node" which internally calls method startEditing()
off of node
object that is passed to the event handler.
I neither can find such method in Node API nor I see this feature functioning correctly. In fact, an error gets reported into console once "Edit" link is clicked.
any plans to support drag and drop in the tree? it's a great control, thanks for the hard work.
I would like to only collapse a node when clicking the expand/collapse icon -- not when selecting the item directly. Typically, I can do something like event.stopPropagation() or event.preventDefault() to accomplish this, but would need access to the actual click event being fired not the node itself.
Any thoughts if this is possible now in some way I am not seeing or could support be added? Thank you.
Hello,
is there a possibility to save the changed state in a json from the tree?
For example I have a predefined tree with no checked node. How can I get the data json with the checked nodes?
Best Regards
how to reload the node after events ?
Hello,
I have a dropdown called project on the parent component and a child component to display the tree.
The treeData is depending on the selected project. The data is fetched from a backend and the data is passed as props from parent to child. Actually a watcher is implemented to verify the data.
How is it possible to update and redraw the tree?
Best regards,
amehlen
A weird bug I found is when a Node text value has brackets Tree.find returns false.
let tree = item.find({ text: 'London (SE5)' id: 5, state: { checked: true } }); if (tree) { tree.uncheck(); }
This returns null, however if I changed text to 'London - SE5' it works.
Also, does the Tree.find API search in data object?
Thanks
Now there is only basic functionality of DND includes events (dragging:start, dragging:finish)
Plans:
states
like draggable
, dropable
Hi, I'm trying to load the children of a selected node async via axios. Problem is that I need to pass some params and headers that are generated/ selected during the runtime.
Using this.property only returns undefined, despite defining it in the data(). Using this.$store or this.$data doesn't work either. Only thing that works is defining a property above the export default in the script, but then that's not reactive either.
treeOptions: {
parentSelect: true,
checkbox: true,
fetchData(node) {
console.log("fetchSession: ", this.session)
return axios.get(`/treedata/${node.id}`, {
params: {
session: this.session
},
headers: {
"body": this.body,
}
}).then(response => {
// JSON responses are automatically parsed.
console.log("TreeDataResponse: ", response)
let obj = response.data.Objects
return Promise.resolve(obj)
})
.catch(e => {
console.log("error: ", e)
})
Update: Solution
data() {
return {
...
body: 'some body',
treeFilter: '',
treeOptions: {
parentSelect: true,
checkbox: true,
fetchData: this.getFetchData
},
}
},
methods: {
getFetchData (node) {
console.log("getFetchData: ", node.id, this.$store.getters.session)
return axios.get(`/treedata/${node.id}`, {
params: {
session: this.$store.getters.session
},
headers: {
"body": this.body,
}
}).then(response => {
// JSON responses are automatically parsed.
console.log("TreeDataResponse: ", response)
let obj = response.data.Objects
return Promise.resolve(obj)
})
.catch(e => {
console.log("error: ", e)
})
},
Can you add a prop to define if a node should expand only when you click on the tree-arrow area and not on the tree-content area.
But I also need to trigger the node:selected event when I click on the tree-content area...
I implemented the Liqour tree and it works great. However I have one question, which I do not succeed with. Right now I have a tree structure with checkboxes. I use this line to get the results:
<pre style="display: none;" id="selectedFeaturesDiv" v-if="treeModel"> {{ treeModel.checked.map(el => el.parent.text + ";" +el.text) }} </pre>
This gives me the checked nodes and the parent node. However I want to know all parents of the specific node not only the first, but also the parent of the parent until the root node. Is this possible?
Hey, just tried liquor-tree and as it seems from initial tests it's not reactive. My data is primary asynchronous and all my components have no data when mounted and rely on the reactive nature of vuejs. I looked at liquor source and it looks like the render uses a model property that is generated only once on mounted()
(once per component instance) and not part of data()
function.
I have deployed the liquor-tree component and found that any changes to the data prop do not affect the model object in component data.
Specifically, I have my code to compose two sets of tree data in terms of different languages. While I changed the tree data from a language to another by passing a different object as the data prop, the liquor tree is totally not affected.
After reading the source code, I assume that the tree data passed into the data prop is just an intermediate object. However, the model object in the component data, which is calculated based on the data prop, is the actual source of the tree.
Based on the assumption, a mechanism that watches the data prop changes is required.
Thanks for this amazing Library!
I do not have control over the JSON data from the server. Is it possible to have an option set a different property name for children objects like below?
const treeData = [ { text: 'Item 1', state: { visible: false } }, { text: 'Item 2', state: { selected: { text: 'Item 3', children: [ { label: 'Item 3.1', state: { disabled: true } }, { label: 'Item 3.2', state: { selectable: false } } ]} // and so on ... ]
Thanks
Hi!
Thanks for your wonderfull library.
I see in src/lib/Node.js that events are emitted when a node is selected.
How would I listen to that event to dynamically display the nodes data object into a Div?
If selectedNodeInfo() is run every time a node gets selected then this would work :
<template>
<div>
<LiquorTree :data="dirTree" :options="treeOptions" ref="tree"/>
<div >{{selected}}</div>
</div>
</template>
<script>
import LiquorTree from 'liquor-tree'
import axios from 'axios'
export default {
name: "resourceTree",
components: {
LiquorTree
},
data() {
return {
dirTree: this.getDirPaths(),
// This property should contain the selected node's Object.
selected : {},
treeOptions: {
propertyNames: {
text: 'name',
children: 'children'
}
}
}
},
created() {
this.getDirPaths()
},
methods : {
getDirPaths() {
return axios.get("http://localhost:9090/fragpaths")
.then(response => response.data)
}
},
selectedNodeInfo() {
this.selected = this.$refs.tree.findAll({state: { selected: true } })
}
}
</script>
<style scoped>
</style>
Hi, thanks for this tool, it's amazing.
Unfortunately, i have a little problem ,
It doesn't work with dynamic data, maybe something i made wrong ? Here is my code
<template>
<tree
ref="tree"
:data="treeData"
/>
</template>
<script>
...
data: () => ({
treeData: []
}),
mounted: function () {
this.getTreeData()
},
methods: {
getTreeData() {
var self = this
axios.get('http://localhost:8082/files')
.then((response) => {
self.treeData = response.data
})
.catch((err) => {
console.log('Error : ' + err)
})
}
...
</script>
Thank you !
How to get all data of tree after change add,edit,delete,checked node?
Hello Thank you for your awesome vue package
do you have there an sample using fetchdata ?
Thank you!
Hi.
I am trying to get the node after appending it, but I'm not getting.
My code:
`
let node = this.$refs.tree.append({ text: 'My Text', state: { selected: true }});
let selection = this.$refs.tree.selected();
alert(selection.length); // <-------- this always stays zero
`
Can you help me solve this?
Thank you in advance.
Hellow
I've noticed that once u use the store option to keep the liquor-tree updated some options stop working.
I added state:{checked:true} on some of my data's nodes but it has no effect :o
Do you have any solution ?
Thank you
We have a requirement where we only need the leaf nodes to have checkboxes, parent nodes should not have them. How can we accomplish this?
i see you can pass in a variable to the options called store where you can access the store to get values(using in fetch data), but i'm getting some weird errors.
Uncaught (in promise) TypeError: Cannot read property 'state' of undefined
at a (liquor-tree.esm.js?6487:6)
at VueComponent.connectStore (liquor-tree.esm.js?6487:6)
at eval (liquor-tree.esm.js?6487:6)
how i'm calling it/configuration:
<tree v-if="websiteId != 0" :options="treeOptions" @node:selected="onNodeSelected" />
treeOptions: {
store: this.$store,
fetchData (node) {
return HTTP.get(/api/websitenavigation?nodeid=${node.id}&websiteId=${this.store.getters.websiteId}
).then(function (response) { return response.data })
}
}
if i take out the store: this.$store and hard code the id (${this.store.getters.websiteId}, i get exactly as i would expect it to work. any ideas or help?
thanks,
matt
Hi, Comrade!
We're watching you and already noticed that our young Padawan getting basics of Open Source stack.
And of course we would like to see the high reliability of your work!
Unfortunately, at the moment we can not treat the source code - as a standard.
So we would like to see the implementation of testing and some of CI procedures ;-)
I found the liqour Tree lib and looks like something I would like to user. I dynamically built a json structure but the tree does not want to load the structure. The following structure is printed in the console:
{
"text": "http://data.resc.info/shape#PropertyObject",
"state": {
"expanded": true
},
"children": [
{
"text": "http://vocab.netage.nl/kro#hasMonument",
"children": [
{
"text": "http://vocab.netage.nl/kro#monument",
"children": []
},
{
"text": "http://vocab.netage.nl/kro#resource",
"children": []
},
{
"text": "http://purl.org/dc/terms/modified",
"children": []
}
]
},
{
"text": "http://vocab.netage.nl/kro#hasAHN",
"children": [
{
"text": "http://vocab.netage.nl/kro#bouwlagen",
"children": []
},
{
"text": "http://vocab.netage.nl/kro#resource",
"children": []
},
{
"text": "http://vocab.netage.nl/kro#pandHoogte",
"children": []
},
{
"text": "http://vocab.netage.nl/kro#gemiddelde_hoogte",
"children": []
},
{
"text": "http://vocab.netage.nl/kro#maximale_hoogte",
"children": []
},
{
"text": "http://purl.org/dc/terms/modified",
"children": []
}
]
},
{
"text": "http://vocab.netage.nl/kro#hasBuilding",
"children": [
{
"text": "http://vocab.netage.nl/kro#bouwjaar",
"children": []
},
{
"text": "http://vocab.netage.nl/kro#bag_oppvlk",
"children": []
},
{
"text": "http://vocab.netage.nl/kro#status",
"children": []
},
{
"text": "http://vocab.netage.nl/kro#functie",
"children": []
},
{
"text": "http://vocab.netage.nl/kro#resource",
"children": []
},
{
"text": "http://purl.org/dc/terms/modified",
"children": []
}
]
},
{
"text": "http://vocab.netage.nl/kro#hasLRKP",
"children": [
{
"text": "http://vocab.netage.nl/kro#naamHouder",
"children": []
},
{
"text": "http://vocab.netage.nl/kro#lrkpid",
"children": []
},
{
"text": "http://vocab.netage.nl/kro#lrkpType",
"children": []
},
{
"text": "http://vocab.netage.nl/kro#kindplaatsen",
"children": []
},
{
"text": "http://purl.org/dc/terms/identifier",
"children": []
},
{
"text": "http://vocab.netage.nl/kro#resource",
"children": []
},
{
"text": "http://purl.org/dc/terms/modified",
"children": []
}
]
},
{
"text": "http://vocab.netage.nl/kro#hasAddress",
"children": [
{
"text": "http://vocab.netage.nl/kro#straat",
"children": []
},
{
"text": "http://vocab.netage.nl/kro#resource",
"children": []
},
{
"text": "http://vocab.netage.nl/kro#huisnummer",
"children": []
},
{
"text": "http://vocab.netage.nl/kro#plaatsnaam",
"children": []
},
{
"text": "http://vocab.netage.nl/kro#gemeentenaam",
"children": []
},
{
"text": "http://purl.org/dc/terms/modified",
"children": []
}
]
},
{
"text": "http://vocab.netage.nl/kro#hasBRK",
"children": [
{
"text": "http://vocab.netage.nl/kro#sectie",
"children": []
},
{
"text": "http://vocab.netage.nl/kro#perceelnummer",
"children": []
},
{
"text": "http://vocab.netage.nl/kro#resource",
"children": []
},
{
"text": "http://purl.org/dc/terms/modified",
"children": []
}
]
},
{
"text": "http://vocab.netage.nl/kro#hasRRGS",
"children": [
{
"text": "http://vocab.netage.nl/rrgs#gasdruk_meet_en_regelstations",
"children": []
},
{
"text": "http://vocab.netage.nl/rrgs#gasvulstations",
"children": []
},
{
"text": "http://vocab.netage.nl/rrgs#vervoerseenheden_met_gevaarlijke_stoffen",
"children": []
},
{
"text": "http://vocab.netage.nl/rrgs#overige_onbrandbare_vaste_gevaarlijke_stoffen",
"children": []
},
{
"text": "http://vocab.netage.nl/rrgs#brandbare_vaste_stoffen",
"children": []
},
{
"text": "http://vocab.netage.nl/rrgs#gasflessendepots_groterdan_10000",
"children": []
},
{
"text": "http://purl.org/dc/terms/identifier",
"children": []
},
{
"text": "http://vocab.netage.nl/rrgs#vloeistoffen_die_zeer_giftige_gassen_kunnen_vormen",
"children": []
},
{
"text": "http://vocab.netage.nl/rrgs#stofexplosie_gevaarlijke_stoffen",
"children": []
},
{
"text": "http://vocab.netage.nl/rrgs#overige_gevaarlijke_vloeistoffen",
"children": []
},
{
"text": "http://vocab.netage.nl/rrgs#overige_gevaarlijke_gassen",
"children": []
},
{
"text": "http://vocab.netage.nl/rrgs#kew",
"children": []
},
{
"text": "http://vocab.netage.nl/rrgs#zeer_licht_ontvlambare_vloeistoffen",
"children": []
},
{
"text": "http://vocab.netage.nl/rrgs#brandbare_vloeistoffen",
"children": []
},
{
"text": "http://vocab.netage.nl/rrgs#vaste_stoffen_die_zeer_giftige_gassen_kunnen_vormen",
"children": []
},
{
"text": "http://vocab.netage.nl/kro#resource",
"children": []
},
{
"text": "http://vocab.netage.nl/rrgs#defensie",
"children": []
},
{
"text": "http://vocab.netage.nl/rrgs#zeer_gifitige_vloeistoffen",
"children": []
},
{
"text": "http://vocab.netage.nl/rrgs#ammoniak",
"children": []
},
{
"text": "http://vocab.netage.nl/kro#naam",
"children": []
},
{
"text": "http://vocab.netage.nl/rrgs#vervoer_en_opslag",
"children": []
},
{
"text": "http://vocab.netage.nl/rrgs#vuurwerk",
"children": []
},
{
"text": "http://purl.org/dc/terms/modified",
"children": []
},
{
"text": "http://vocab.netage.nl/rrgs#zeer_giftige_gassen",
"children": []
},
{
"text": "http://vocab.netage.nl/rrgs#giftige_vloeistoffen",
"children": []
},
{
"text": "http://vocab.netage.nl/rrgs#mijnbouw",
"children": []
},
{
"text": "http://vocab.netage.nl/rrgs#indicatie_BEVI",
"children": []
},
{
"text": "http://vocab.netage.nl/rrgs#zeer_giftige_vaste_stof",
"children": []
},
{
"text": "http://vocab.netage.nl/rrgs#pgs15",
"children": []
},
{
"text": "http://vocab.netage.nl/rrgs#oxiderende_gassen",
"children": []
},
{
"text": "http://vocab.netage.nl/rrgs#vaste_stoffen_die_giftige_stoffen_kunnen_vormen",
"children": []
},
{
"text": "http://vocab.netage.nl/kro#rrgsid",
"children": []
},
{
"text": "http://vocab.netage.nl/rrgs#propaan",
"children": []
},
{
"text": "http://vocab.netage.nl/rrgs#lpg",
"children": []
}
]
},
{
"text": "http://vocab.netage.nl/kro#hasNHR",
"children": [
{
"text": "http://vocab.netage.nl/kro#sbicode",
"children": []
},
{
"text": "http://vocab.netage.nl/kro#organization",
"children": []
},
{
"text": "http://vocab.netage.nl/kro#kvknummer",
"children": []
},
{
"text": "http://vocab.netage.nl/kro#vestigingsnummer",
"children": []
},
{
"text": "http://vocab.netage.nl/kro#resource",
"children": []
},
{
"text": "http://purl.org/dc/terms/modified",
"children": []
}
]
},
{
"text": "http://vocab.netage.nl/kro#hasWOZ",
"children": [
{
"text": "http://vocab.netage.nl/kro#waardeonder",
"children": []
},
{
"text": "http://vocab.netage.nl/kro#waardeboven",
"children": []
},
{
"text": "http://vocab.netage.nl/kro#gebrklasse",
"children": []
},
{
"text": "http://vocab.netage.nl/kro#waardeklasse",
"children": []
},
{
"text": "http://vocab.netage.nl/kro#bouwbest",
"children": []
},
{
"text": "http://vocab.netage.nl/kro#resource",
"children": []
},
{
"text": "http://purl.org/dc/terms/modified",
"children": []
}
]
}
]
}
The only thing shown in on the page is a checkbox with no text and no child features. I have totally no clue why it does not work. The only thing which I found is if I let the generate method return "{text: "test"}", it does work. But when the complete structure is generated like:
var treeData = []; var test = {}; test.text = "test"; treeData.push(test);
it does not work. Compared with the standard working json tree, it is totally the same structure.
Hello
I have problem to show some reactive data with node.data source.
Tried this workaround https://github.com/amsik/liquor-tree/issues/9 but it does not work.
I want to pass data object through the computed getters but without results.
Please could you give me some clue how solve this problem.
Thank you in advance.
Hellow !
I'm trying to use your nice component on a project, unfortunatly I just encountered several problems :(
So, the component beeing unable to update using computed props on :data, I noticed u added the new store option which I'm trying to use.
My tree options
treeOptions: { store: { store: this.$store, getter: "treeStore", mutations: ["updateTree"] }, checkbox: true, propertyNames: { text: "myname", children: "mychildren" }, filter: { plainList: true } }
My Store:
import forest from "./forest" const store = new Vuex.Store({ modules: { forest }, });
My Store module "forest"
export default { namespaced: true, treeStore: [], getters, mutations: { updateTree(state, newData) { state.treeStore = newData; } }, actions };
Could you give me a hand in order to solve those problems please?
Thank you kindly :p.
Is there an available solution to this?
Btw @amsik , your plugin is good and has a potential to grow. :)
Thank you.
Cheers,
Reymark
{
propertyNames: {
text: 'name',
},
filter: {
emptyText: 'Ничего не найдено!',
showChildren: true,
},
checkbox: true,
multiple: false,
autoCheckChildren: false
}
Is it possible to asynchronously load node children when selecting/expending the target node.
I only want to show the children after expanding the parent and append them to the parent.
Do you mind adding an example ?
Here's the component code if it helps
<template>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-10">
<div class="card">
<div class="card-header">
<div class="d-flex justify-content-between align-items-center">
<span>
<i class="far fa-folder"></i>
Digital Assets
</span>
<div class="d-flex">
<input type="text" class="form-control form-control-sm mr-3" v-model="query">
<div class="dropdown">
<a class="btn btn-secondary btn-sm dropdown-toggle" href="#" role="button"
id="dropdownMenuLink" data-toggle="dropdown" aria-haspopup="true"
aria-expanded="false">
</a>
<div class="dropdown-menu" aria-labelledby="dropdownMenuLink">
<a class="dropdown-item" href="#">
Open All
</a>
<a class="dropdown-item" href="#">
Collapse All
</a>
<a class="dropdown-item" href="#">
Refresh
</a>
</div>
</div>
</div>
</div>
</div>
<div class="card-body">
<!-- load the tree here -->
<liquor-tree
ref="tree"
:options="treeOptions"
:filter="query"
>
<div class="tree-scope" slot-scope="{ node }">
<template v-if="!node.hasChildren()">
<i :class="node.data.icon"></i>
{{ node.text }}
</template>
<template v-else>
<i :class="[node.expanded() ? 'far fa-folder-open' : 'far fa-folder']"></i>
{{ node.text }}
</template>
</div>
</liquor-tree>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import LiquorTree from 'liquor-tree'
export default {
name: 'assets-library',
data: function () {
return {
treeOptions: {
selectedArrowOnly: true,
fetchData(node) {
return fetch(`/tree?id=${node.id}`)
.then(r => r.json())
.then(items => {
items.forEach(setData)
function setData(item) {
item.data = item
if (item.children) {
item.children.forEach(setData)
}
}
return items
})
},
},
query: ''
}
},
methods: {},
components: {
LiquorTree
}
}
</script>
<style>
.tree-node.matched > .tree-content {
background: #f7f2e7;
}
</style>
When tree initialized with some state(for example "expanded": true) this state doen't get applied and tree goes with default behavior.
Example https://codesandbox.io/s/41y00nvw0
See root node state expanded=true
but tree is not expanded. Try clicking Test Reactivity
button.
Add an opportunity to filter tree.
I found a small mismatch in example in documentation
you have
this.$refs.tree.find('Node Text') // It will find Node that has text 'Node Text' this.$refs.tree.find(/Node Text/) // Using RegExp. It will find: Node Text ATAT, ATATA Node Text and so on... this.$refs.tree.find({ text: /^Item 2/, state: { checked: true, selected: true } })
when you find, it should be stateS instead of state
i'm passing a state object to the tree via vuex(with a specific node selected), but it doesn't respect that i'm passing it in as selected?
Hey,
I copied your code and tried to play with this a little bit as some study material.
This is the problem I'm facing
I've tracked down the problem at some level in the TreeMixin file when initEvents is called, but I think I'm wrong.
I've pushed the code on github, if you wouldn't mind checking it.
Something else I'd like to know, in the repo, you'll find a data.json file that contains a tree structure that is coming from an api I'm working on, the node's icon is also in that tree structure.
Is it possible to show the icon since it's part of the data structure and the actual node's data that can be accessed is "text" ?
Here's the rep link:
sym-library
Hi, I have issue as following.
I loaded the tree datas from server, and change the state by vuex, but the tree can not refresh.
Can u help me about that? Thank you!
Here is my source image.
<VueTree
:data="tree_items"
@node:selected="onSelected"
ref="tree"
/>
const state = {
tree_items:[],
},
const mutations = {
updateTree(state, treeData) {
state.tree_items = [];
state.tree_items.push(...treeData);
},
}
const actions = {
initTree({commit}, cb) {
tool.request('url',params).then((data)=>{
commit('updateTree', data)
cb & cb(data);
}
})
},
}
Hi!
I need to attach events listeners to the nodes when they are created (on open/expand) and when they are closed (on close/colapse) i need to map wich event was dismissed to re-attach it when open the node again.
Or some init node function that i can pre-define some code every time a node is opened.
There are any way to do it already that i am missing?
Thanks, i loved the plugin!
Hi,
I'm integrating this tool with Vuex, and have the following problem.
According to the documents, integrated with Vuex should pass Vuex store object into treeOptions
The file tree looks like this (see also github repo)
.
├── components
| ├── common
| | └── Filetree.vue
| | └── ...
| └── ...
├── store
| ├── modules
| | ├── Filetree.js
| | └── ...
| └── index.js
└── ...
When I create several modules, the states of each modules are separated but the mutations are mixed. It seems unable to get a Vuex store object.
In my understanding, this plugin will copy the reference of its data into Vuex state in initTree
mutation. Can I pass only listened state property and some actions(or mutations) into tree options
? So that I can visit the required objects from Vue file via mapState
, mapActions
and mapMutations
.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.