上午試圖與從API接收到的數據的圖形,並把這個圖形上(https://bl.ocks.org/mbostock/4062045) - 力指向圖如何使上VueJS一個圖形
但是我在這是怎麼完成的不確定VueJs還是有更簡單的工具來做到這一點?
D3力定向圖似乎有點複雜,也許有一個圖書館已經開箱即用?
上午試圖與從API接收到的數據的圖形,並把這個圖形上(https://bl.ocks.org/mbostock/4062045) - 力指向圖如何使上VueJS一個圖形
但是我在這是怎麼完成的不確定VueJs還是有更簡單的工具來做到這一點?
D3力定向圖似乎有點複雜,也許有一個圖書館已經開箱即用?
從評論中提到的vue-d3
包只是將D3添加到Vue原型,因此可以通過this.$d3
訪問。
我已經測試過這個軟件包,但它不能與我的D3版本一起工作。看起來像一個套管問題(D3而不是D3)。所以我手動添加了原型。
我不知道是否有更容易創建力圖的庫,但請看下面的演示或此fiddle。
我修改了鏈接中的示例以創建一個強制有向圖。演示正在工作,但正如你所提到的,它非常複雜。 也可以從SVG綁定到Vue.js模型。但我找不到一個更好的方法來做到這一點。
例如,點擊添加一個新節點並不適用於只向數組中添加新節點,但這應該是Vue.js組件的目標。一旦數據改變,SVG圖應該自動更新。
目前,組件中沒有使用Vue.js中的節點和鏈接,因爲我不知道如何添加圖形的更新。
如果您想出瞭如何使用模型數據添加更新,請讓我知道。通過刪除SVG並重新創建它,刷新整個圖表非常容易。 (見重新加載按鈕)
// https://unpkg.com/[email protected] --> only adds d3 to Vue.prototype but it wasn't working as expected (d3 is lower case)
Vue.prototype.$d3 = d3;
const URL = 'https://demo5147591.mockable.io/miserables'; // data copied from below link because of jsonp support
//'https://bl.ocks.org/mbostock/raw/4062045/5916d145c8c048a6e3086915a6be464467391c62/miserables.json';
//console.log(window.d3);
const d3ForceGraph = {
template: `
<div>
{{mousePosition}}
<button @click="reload">reload</button>
<svg width="600" height="600"
\t @mousemove="onMouseMove($event)"></svg>
</div>
`,
data() {
return {
nodes: [],
links: [],
simulation: undefined,
mousePosition: {
x: 0,
y: 0
}
}
},
mounted() {
this.loadData(); // initially load json
},
methods: {
// load data
loadData() {
\t \t this.$svg = $(this.$el).find('svg');
let svg = this.$d3.select(this.$svg.get(0)), //this.$d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height");
//console.log($(this.$el).find('svg').get(0));
this.simulation = this.$d3.forceSimulation()
.force("link", this.$d3.forceLink().id(function(d) {
return d.id;
}))
.force("charge", this.$d3.forceManyBody())
.force("center", this.$d3.forceCenter(width/2, height/2));
let color = this.$d3.scaleOrdinal(this.$d3.schemeCategory20);
$.getJSON(URL, (graph) => {
//d3.json("miserables.json", function(error, graph) { // already loaded
//if (error) throw error; // needs to be implemented differently
let nodes = graph.nodes;
let links = graph.links;
let link = svg.append("g")
.attr("class", "links")
.selectAll("line")
.data(links) //graph.links)
.enter().append("line")
.attr("stroke-width", function(d) {
return Math.sqrt(d.value);
});
let node = svg.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(nodes) //graph.nodes)
.enter().append("circle")
.attr("r", 5)
.attr("fill", function(d) {
return color(d.group);
})
.call(this.$d3.drag()
.on("start", this.dragstarted)
.on("drag", this.dragged)
.on("end", this.dragended));
node.append("title")
.text(function(d) {
return d.id;
});
this.simulation
.nodes(graph.nodes)
.on("tick", ticked);
this.simulation.force("link")
.links(links); //graph.links);
function ticked() {
link
.attr("x1", function(d) {
return d.source.x;
})
.attr("y1", function(d) {
return d.source.y;
})
.attr("x2", function(d) {
return d.target.x;
})
.attr("y2", function(d) {
return d.target.y;
});
node
.attr("cx", function(d) {
return d.x;
})
.attr("cy", function(d) {
return d.y;
});
}
})
},
reload() {
//console.log('reloading...');
this.$svg.empty(); // clear svg --> easiest way to re-create the force graph.
this.loadData();
},
// mouse events
onMouseMove(evt) {
//console.log(evt, this)
this.mousePosition = {
x: evt.clientX,
y: evt.clientY
}
},
// drag event handlers
dragstarted(d) {
if (!this.$d3.event.active) this.simulation.alphaTarget(0.3).restart();
d.fx = d.x;
d.fy = d.y;
},
dragged(d) {
d.fx = this.$d3.event.x;
d.fy = this.$d3.event.y;
},
dragended(d) {
if (!this.$d3.event.active) this.simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}
}
};
new Vue({
el: '#app',
data() {
return {}
},
components: {
d3ForceGraph
}
});
.links line {
stroke: #999;
stroke-opacity: 0.6;
}
.nodes circle {
stroke: #fff;
stroke-width: 1.5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.8.0/d3.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.2.6/vue.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="app">
<d3-force-graph></d3-force-graph>
</div>
我通過提供d3 force graph with vue.js的一例回答上VUE + D3另一個問題。
d3.js現在拆分成小模塊,具體計算被隔離在小組件中,如d3-force。 SVG可以像任何其他HTML結構一樣在組件模板中繪製。
先生你去https://www.npmjs.com/package/vue-d3 –
看看https://github.com/johnnynotsolucky/samples/tree/master/vuejs-d3你可以看更多的演示在https://github.com/vuejs/awesome-vue – Ethaan