I have a graphML file. I want to display the graph from my graphML file on the browser. I'm working with cytoscape.js. As far as I understood, we can import graph from the graphML file using cytoscape extention cytoscape-graphml.js. But I don't know how to do that. Here is the example of what I want to achieve.
var cy;
fetch('http://localhost/Development/example.graphml')
.then(response => response.text())
.then((data) => {
cy = cytoscape({
container: document.getElementById('cy'),
elements: data
});
});
Well, as you can read in the docs of cytoscape.js-graphml, you only need to initialize cytoscape with the graphml data and a layout like this:
var cy;
fetch('http://localhost/Development/example.graphml')
.then(response => response.text())
.then((data) => {
cy = cytoscape({
container: document.getElementById('cy'),
style: [
{
selector: 'node',
style: {
'content': 'data(id)'
}
},
{
selector: 'edge',
style: {
'target-arrow-shape': 'triangle'
}
}
],
ready: function () {
this.graphml({layoutBy: 'cose'});
this.graphml(data);
}
});
});
Related
this is my first question asked on stackoverflow!
I'm quite new on Vue.js and I am currently trying to display and interact with a node network graph using the v-network-graph component. I am struggling with using the EventHandler, because I didn't really got how to create it and interact with it. Should I initiate it within another instance and import it directly inside this one? Could you please help me understand how to manage the event handler ?
I tried the following code, expecting it to print in the console the node's id I clicked on:
<script lang="ts">
import { reactive, ref } from 'vue';
import * as vNG from 'v-network-graph';
import {
ForceLayout,
ForceNodeDatum,
ForceEdgeDatum,
} from 'v-network-graph/lib/force-layout';
const graph = ref<vNG.Instance>();
export default {
data() {
return {
nodes: { '': { name: '' } },
edges: { '': { source: '', target: '' } },
layouts: {
nodes: {
node0: {
x: 0,
y: 0,
fixed: true,
},
},
},
configs: reactive(
vNG.defineConfigs({
node: {
selectable: true,
label: {
direction: 'center',
color: '#eeeeee',
},
normal: {
radius: 48,
},
},
view: {
autoPanAndZoomOnLoad: 'fit-content',
minZoomLevel: 1,
maxZoomLevel: 2,
layoutHandler: new ForceLayout({
positionFixedByDrag: false,
positionFixedByClickWithAltKey: true,
}),
},
}),
),
};
},
methods: {
async getNodes() {
await fetch('http://127.0.0.1:5000/getNodes')
.then((response) => response.json())
.then((data) => { this.nodes = (data); });
},
async getEdges() {
await fetch('http://127.0.0.1:5000/getEdges')
.then((response) => response.json())
.then((data) => { this.edges = (data); });
},
},
beforeMount() {
this.getNodes();
this.getEdges();
const eventHandlers: vNG.EventHandlers = {
'node:click': ({ node }) => {
window.console.log(this.nodes[node]);
},
};
},
mounted() {
this.$refs.graph.fitToContents();
},
};
</script>
<template>
<v-network-graph
:nodes="nodes"
:edges="edges"
:configs="configs"
:layouts="layouts"
:event-handlers="eventHandlers"
ref="graph"
class="visualization"
/>
</template>
<style>
.visualization {
width: 100%;
height: 100vh;
border: 1px solid #000;
}
</style>
I've understood how to make it thanks to this post. Basically the documentation I was learning with is using Script Setup while I'm using the OptionAPI!
The actual answer:
The trick here is to not use the vNG.EventHandlers and to set the event handling Object directly in the data component, and the v-bind directive in the graph element.
The code (please note that I intentionally removed the useless code that was in the previous post to make a clearer answer):
<script lang="ts">
import { reactive, ref } from 'vue';
import * as vNG from 'v-network-graph';
const graph = ref<vNG.Instance>();
export default {
data() {
return {
nodes: reactive({ '': { name: '' } }),
edges: { '': { source: '', target: '' } },
click_event: {
'node:click': ({ node }) => {
window.console.log(this.nodes[node]);
},
},
},
},
};
</script>
<template>
<v-network-graph
:nodes="nodes"
:edges="edges"
:event-handlers="click_event"
ref="graph"
class="visualization"
/>
</template>
I am working on a Quasar project and I am having a problem. I need to access from external javascript to the properties and methods of the Vue component.
const vue = Vue.extend({
name: 'PageIndex',
data() {
return {
accessToken:
'myToken',
mapStyle: 'mapbox://styles/mapbox/streets-v11',
coordinates: { lng: -82.42642875898966, lat: 23.11975881338755 },
barbershopsSource: {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
properties: {
title: 'Foo'
},
geometry: {
type: 'Point',
coordinates: [-82.42644475189455, 23.119620627441506]
}
},
{
type: 'Feature',
properties: {
title: 'Bar'
},
geometry: {
type: 'Point',
coordinates: [-82.42193696725194, 23.124402891576594]
}
},
{
type: 'Feature',
properties: {
title: 'Baz'
},
geometry: {
type: 'Point',
coordinates: [-82.43414198682088, 23.115900071933567]
}
}
]
}
};
},
components: {},
methods: {
createMap() {
mapboxgl.accessToken = this.accessToken;
const map = new mapboxgl.Map({
container: 'map',
style: this.mapStyle, // stylesheet location
center: this.coordinates, // starting position [lng, lat]
zoom: 15 // starting zoom
});
const source = this.barbershopsSource;
map.on('load', function() {
console.log('Map loaded');
//I want to have access to the component properties here
});
map.on('click', 'barbershops', function(e) {
console.log('Barbershop clicked:', e.lngLat);
});
}
},
mounted() {
this.createMap();
}
});
export default vue;
I know that access to properties is pretty simple, but the thing is that by default and I don't know why, Quasar uses Vue.extend to create the components. If I substitute
const vue = Vue.extend
by
const vue = new Vue
I can access to properties, but the component view isn't loaded.
Any help would be greatly appreciated
The way it works is, quasar takes App.vue as the entry point and loads the generated compiled javascript. The app is created there.
There is only one app running.
You add functionality to your vue app by extend the app.
You create app once in App.vue and add functionality to it by extending.
I would like to create a line chart using the vue-chartjs library.
What I have created so far produces no error but it also renders nothing but a blank canvas. When I switch to the developer view, I notice that all my data prints out. I'm just not sure why it's not rendering.
Here's my HTML and a snippet of the Vue code:
<div class="app">
<h1>Line Chart</h1>
<line-chart></line-chart>
</div>
<script>
Vue.component('line-chart', {
extends: VueChartJs.Line,
mounted () {
this.renderChart({
labels: this.chartDate,
datasets: [
{
label: 'Data One',
backgroundColor: '#f87979',
data: this.expectedFund
}
]
}, {responsive: true, maintainAspectRatio: false})
}
})
new Vue({
el: '.app',
data: {
message: 'Hello World',
dataSetData: [],
expectedFund: '',
chartDate: '',
crossOver: '',
billing: ''
},
methods: {
getDataSet: function(dataField) {
console.log("get data sets");
console.log(this.dataSetData);
this.expectedFund = this.dataSetData.map(function(chartData) {
//alert("expected");
console.log(chartData);
return chartData.ExpectedFund;
});
this.billing = this.dataSetData.map(function(chartData) {
return chartData.Billing;
});
this.billing = this.dataSetData.map(function(chartData) {
return chartData.Billing;
});
this.chartDate = this.dataSetData.map(function(chartData) {
return chartData.date;
});
this.crossOver = this.dataSetData.map(function(chartData) {
return chartData.crossOver;
});
},
getListData: async function() {
const { data } = await axios.get(
"https://my-json-server.typicode.com/isogunro/jsondb/chartData"
);
return data;
}
},
mounted: async function() {
this.dataSetData = await this.getListData();
console.log("ok", this.dataSetData);
this.getDataSet();
}
})
</script>
If the pasted code is not enough, here's the Pen
After much struggle and bouncing around a bunch of Vue discords, I was able to figure out how to create a multi-line and bar-chart using Vue-Chartjs. It was a struggle worth it because I finally understand the use of props and how they work, which is what I was missing with the vuejs charts. Here's a pen showing the solution.
I am posting the json below because my charts use that data found in "my fake json server/typicode". It might change in the future, so I'm pasting it here.
{"chartData":
[
{
"date":"4/4/2019",
"totalCount":381,
"ExpectedFund":191,
"Funded":290,
"Billing":125,
"crossOver":241,
"AcceptedTotal":515
},
{
"date":"4/11/2019",
"totalCount":233,
"ExpectedFund":12,
"Funded":220,
"Billing":125,
"crossOver":211,
"AcceptedTotal":315
},
{
"date":"4/18/2019",
"totalCount":542,
"ExpectedFund":34,
"Funded":240,
"Billing":125,
"crossOver":125,
"AcceptedTotal":415
},
{
"date":"4/25/2019",
"totalCount":154,
"ExpectedFund":49,
"Funded":210,
"Billing":243,
"crossOver":35,
"AcceptedTotal":115
},
{
"date":"5/2/2019",
"totalCount":300,
"ExpectedFund":55,
"Funded":200,
"Billing":125,
"crossOver":145,
"AcceptedTotal":105
},
{
"date":"5/9/2019",
"totalCount":231,
"ExpectedFund":55,
"Funded":250,
"Billing":125,
"crossOver":355,
"AcceptedTotal":215
},
{
"date":"5/16/2019",
"totalCount":331,
"ExpectedFund":77,
"Funded":270,
"Billing":312,
"crossOver":15,
"AcceptedTotal":615
},
{
"date":"5/23/2019",
"totalCount":498,
"ExpectedFund":232,
"Funded":270,
"Billing":312,
"crossOver":15,
"AcceptedTotal":615
},
{
"date":"5/30/2019",
"totalCount":102,
"ExpectedFund":33,
"Funded":150,
"Billing":25,
"crossOver":155,
"AcceptedTotal":315
},
{
"date":"6/6/2019",
"totalCount":293,
"ExpectedFund":235,
"Funded":170,
"Billing":112,
"crossOver":125,
"AcceptedTotal":315
},
{
"date":"6/13/2019",
"totalCount":198,
"ExpectedFund":432,
"Funded":470,
"Billing":112,
"crossOver":315,
"AcceptedTotal":215
}
]
}
I want to embed a mapbox-gl map in my Vue page. How do I get it to create the new object and attach it to the DOM? I need to create the new mapboxgl.Map() object and associate it with the DOM element.
Thanks!
My code:
<template>
<div id="map">
</div>
</template>
<script>
export default {
head () {
return {
script: [
{ src: 'https://cdn.klokantech.com/mapbox-gl-js/v0.43.0/mapbox-gl.js' }
],
link: [
{ rel: 'stylesheet',
href: "https://cdn.klokantech.com/mapbox-gl-js/v0.43.0/mapbox-gl.css" }
]
}
},
map () {
return new mapboxgl.Map({
container: 'map',
center: [10.18440, -0],
zoom: 0.89,
interactive: false,
attributionControl:false
});
}
}
</script>
<style>
#map {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 0;
}
</style>
Have you try on mounted event ?
export default {
head () {
...
},
methods: {
map: function () {
mapboxgl.accessToken = '<your access token here>'; // optional
return new mapboxgl.Map({
container: 'map',
center: [10.18440, -0],
zoom: 0.89,
interactive: false,
attributionControl:false,
// set your own style:
style: 'http://osm-liberty.lukasmartinelli.ch/style.json' // free
//style: 'mapbox://styles/mapbox/streets-v9'// access token required
});
}
},
mounted () {
let map = this.map()
map.addControl(new mapboxgl.NavigationControl());
}
}
it works fine ^^
I am using cytoscape.js for one of my usecases. Here, I prefer to display the graph with only nodes in the beginning as shown below.
var cy1 = cytoscape({
container: document.getElementById('cy'),
elements: {
nodes: countriesJSON
},
style: [
{
selector: 'node',
style: {
'background-color': '#666',
'label': 'data(id)'
}
},
{
selector: 'edge',
style: {
'width': 1,
'line-color': '#aaa',
}
}
]
});
cy1.layout({
name: 'circle'
});
Now, inside a function, I will form the edges as like this
function myfunc(){
...
...
allRoutes.map(function(d){
var inner={};
var obj = {}
inner["id"]="edge"+index
inner["source"]=data[0]
inner["target"]=data[1]
obj["data"]=inner
allLegsJSON[i]=obj;
i++;
})
...
...
cy1.elements({ edges: allLegsJSON });
}
Once edges are created, I want to assign edges to the graph as above. However, this code is not working. Can someone tell me how to do this? I wish to assign the edges and then update the cy1 graph.
This did this
cy1.add({ edges: allLegsJSON });