当我突然发生时,我正在整理文件夹结构(将JS移动到.js
文件而不是内联,并将其放入自己的文件夹中)。我的力导向图突然出现了这个奇怪的问题。所有节点和链接都移动到屏幕的左上角。它看起来像这样:
Javascript控制台显示Cannot create property 'vx' on string 'dki'
。
当我尝试将整个代码粘贴到jsfiddle中时,奇怪的是,它正常工作。你可以在这里找到小提琴:https://jsfiddle.net/k6pf1hfw/1/
这是JS代码:
var nodes = [
{ id: "pusat", group: 0, label: "Pusat", level: 0 },
{ id: "dki", group: 1, label: "Prov. DKI", level: 1 },
{ id: "jaksel", group: 1, label: "Kota Jakarta Selatan", level: 2 },
{ id: "jakpus", group: 1, label: "Kota Jakarta Pusat", level: 2},
{ id: "jabar", group: 2, label: "Prov. Jawa Barat", level: 1 },
{ id: "sumedang", group: 2, label: "Kab. Sumedang", level: 2 },
{ id: "bekasi", group: 2, label: "Kota Bekasi", level: 2 },
{ id: "bandung", group: 2, label: "Kota Bandung", level: 2 },
{ id: "jatim", group: 3, label: "Prov. Jawa Timur", level: 1 },
{ id: "malang", group: 3, label: "Kota Malang", level: 2 },
{ id: "lamongan", group: 3, label: "Kota Lamongan", level: 2 },
{ id: "diy", group: 4, label: "Prov. DIY", level: 1 },
{ id: "sleman", group: 4, label: "Kab. Sleman", level: 2 },
{ id: "jogja", group: 4, label: "Kota Yogyakarta", level: 2 },
{ id: "bali", group: 5, label: "Prov. Bali", level: 1 },
{ id: "bali1", group: 5, label: "Kota Denpasar", level: 2 },
{ id: "bali2", group: 5, label: "Kab. Buleleng", level: 2 },
{ id: "ntt", group: 6, label: "Prov. NTT", level: 1 },
{ id: "ntt1", group: 6, label: "Kab. Alor", level: 2 },
{ id: "ntt2", group: 6, label: "Kab. Manggarai Timur", level: 2},
{ id: "ntb", group: 7, label: "Prov. NTB", level: 1 },
{ id: "kabima", group: 7, label: "Kab. Bima", level: 2 },
{ id: "kobima", group: 7, label: "Kota Bima", level: 2 },
{ id: "kaltara", group: 8, label: "Prov. Kaltara", level: 1 },
{ id: "kubar", group: 8, label: "Kab. Kutai Barat", level: 2 },
{ id: "kutim", group: 8, label: "Kab. Kutai Timur", level: 2 },
{ id: "kaltim", group: 9, label: "Prov. Kaltim", level: 1 },
{ id: "bpp", group: 9, label: "Kota Balikpapan", level: 2 },
{ id: "samarinda", group: 9, label: "Kota Samarinda", level: 2 },
{ id: "kalsel", group: 10, label: "Prov. Kalsel", level: 1 },
{ id: "banjar", group: 10, label: "Kota Banjarmasin", level: 2 },
{ id: "tapin", group: 10, label: "Kab. Tapin", level: 2 },
{ id: "kalbar", group: 11, label: "Prov. Kalbar", level: 1 },
{ id: "melawi", group: 11, label: "Kab. Melawi", level: 2 },
{ id: "sambas", group: 11, label: "Kab. Sambas", level: 2}
]
var links = [
// Pusat-Provinsi
{ source:"pusat", target:"dki", strength:.5, value:100000000000 },
{ source:"pusat", target:"jabar", strength:.5, value:30000000000},
{ source:"pusat", target:"jatim", strength:.5, value:100000000000},
{ source:"pusat", target:"diy", strength:.5, value:1000000000000},
{ source:"pusat", target:"bali", strength:.5, value:10000000000},
{ source:"pusat", target:"ntt", strength:.5, value:1000000000},
{ source:"pusat", target:"ntb", strength:.5, value:1000000000},
{ source:"pusat", target:"kaltim", strength:.5, value:5000000000000},
{ source:"pusat", target:"kaltara", strength:.5, value:5000000000000},
{ source:"pusat", target:"kalsel", strength:.5, value:10000000000000},
{ source:"pusat", target:"kalbar", strength:.5, value:1000000000},
// Provinsi-Kab/Kota
{ source:"dki", target:"jaksel", strength:.7, value:2000000000},
{ source:"dki", target:"jakpus", strength:.7, value:4000000000000},
{ source:"jabar", target:"sumedang", strength:.7, value:400000000000},
{ source:"jabar", target:"bekasi", strength:.7, value:40000000000},
{ source:"jabar", target:"bandung", strength:.7, value:40000000000},
{ source:"jatim", target:"malang", strength:.7, value:300000000000},
{ source:"jatim", target:"lamongan", strength:.7, value:100000000000},
{ source:"diy", target:"sleman", strength:.7, value:4500000000000},
{ source:"diy", target:"jogja", strength:.7, value:6700000000000},
{ source:"bali", target:"bali1", strength:.7, value:100000000000000},
{ source:"bali", target:"bali2", strength:.7, value:2400000000000},
{ source:"ntt", target:"ntt1", strength:.7, value:60000000000000},
{ source:"ntt", target:"ntt2", strength:.7, value:100000000000},
{ source:"ntb", target:"kabima", strength:.7, value:126000000000},
{ source:"ntb", target:"kobima", strength:.7, value:1000000000000},
{ source:"kaltara", target:"kubar", strength:.7, value:12420000000000},
{ source:"kaltara", target:"kutim", strength:.7, value:14400000000000},
{ source:"kaltim", target:"bpp", strength:.7, value:1470000000000},
{ source:"kaltim", target:"samarinda", strength:.7, value:1000000000000000},
{ source:"kalsel", target:"banjar", strength:.7, value:137000000000},
{ source:"kalsel", target:"tapin", strength:.7, value:5050000000000},
{ source:"kalbar", target:"melawi", strength:.7, value:2400000000000},
{ source:"kalbar", target:"sambas", strength:.7, value:5500000000000}
];
function getNeighbors(node) {
return links.reduce(function(neighbors, link) {
if (link.target.id === node.id) {
neighbors.push(link.source.id)
} else if (link.source.id === node.id) {
neighbors.push(link.target.id)
}
return neighbors
}, [node.id])
}
function isNeighborLink(node, link) {
return link.target.id === node.id || link.source.id === node.id
}
function getNodeColor(node, neighbors) {
// If is neighbor
if (Array.isArray(neighbors) && neighbors.indexOf(node.id) > -1) {
return 'rgba(251, 130, 30, 1)'
// return node.level === 1 ? '#9C4A9C' : 'rgba(251, 130, 30, 1)'
} else {
// Check the node level
if (node.level === 0) {
return '#E72148'
} else if (node.level === 1) {
return '#9C4A9C'
} else {
return '#D8ABD8'
}
}
//return node.level === 0 ? '#91007B' : '#D8ABD8'
}
function getLinkColor(node, link) {
return isNeighborLink(node, link) ? 'rgba(251, 130, 30, 1)' : 'rgba(251, 130, 30, 0.25)'
}
function getTextColor(node, neighbors) {
return Array.isArray(neighbors) && neighbors.indexOf(node.id) > -1 ? '#333' : '#bbb'
}
var width = window.innerWidth
var height = window.innerHeight
var svg = d3.select('svg')
// svg.attr('width', width).attr('height', height)
svg.attr("width", '100%')
.attr("height", '500px')
.attr('viewBox', '250 0 800 600')
//.attr('viewBox','0 0 '+Math.min(width,height)+' '+Math.min(width,height))
.attr('preserveAspectRatio','xMidYMid')
.append("g")
.attr("transform", "translate(" + Math.min(width,height) / 2 + "," + Math.min(width,height) / 2 + ")");
//add zoom capabilities
var zoom_handler = d3.zoom()
.scaleExtent([1 / 2, 8])
.on("zoom", zoom_actions);
zoom_handler(svg);
function zoom_actions(){
g.attr("transform", d3.event.transform)
}
function button_zoom_in(){
zoom_handler.scaleBy(svg, 2);
}
function button_zoom_out(){
zoom_handler.scaleBy(svg, 0.5);
}
// simulation setup with all forces
var linkForce = d3
.forceLink()
.id(function (link) { return link.id })
// Alternative: using the distance from the data "strength"
//.distance(50).strength(function (link) { return link.strength })
// If don't want to use this, use default here:
.distance(50).strength(.7)
var simulation = d3
.forceSimulation()
.force('link', linkForce)
.force('charge', d3.forceManyBody().strength(-1500))
.force('radial', d3.forceRadial(function(d) {
return d.level * 50
}, width / 2, height / 2))
.force('center', d3.forceCenter(width / 2, height / 2))
var dragDrop = d3.drag().on('start', function(node) {
node.fx = node.x
node.fy = node.y
}).on('drag', function(node) {
simulation.alphaTarget(0.7).restart()
node.fx = d3.event.x
node.fy = d3.event.y
}).on('end', function(node) {
if (!d3.event.active) {
simulation.alphaTarget(0)
}
node.fx = null
node.fy = null
})
function selectNode(selectedNode) {
var neighbors = getNeighbors(selectedNode)
// we modify the styles to highlight selected nodes
nodeElements.attr('fill', function(node) {
return getNodeColor(node, neighbors)
})
textElements.attr('fill', function(node) {
return getTextColor(node, neighbors)
})
linkElements.attr('stroke', function(link) {
return getLinkColor(selectedNode, link)
})
}
// Enables zooming
var g = svg.append("g")
.attr("class", "everything");
// Enables zooming end
// Create circling orbit
var circles = g.selectAll(null) // use g.selectAll instead of svg.selectAll to enable zoom
.data([200,350]) // sets the circle radius
.enter()
.append("circle")
.attr("cx", width/2)
.attr("cy", height/2)
.attr("r", d=>d)
.style("fill", "none")
.style("stroke", "#ddd");
var linkElements = g.append("g") // use g.append instead of svg.append to enable zoom
.attr("class", "links")
.selectAll("line")
.data(links)
.enter().append("line")
.attr("id",function(d,i) { return "linkId_" + i; })
.attr("stroke-width", function(link) {
var linkWidthNormalize = link.value / 1000000000; // in milyar
// under assumption that smallest 10 milyar, largest > 40 triliun
if (linkWidthNormalize >= 40001) {
return 12;
} else if (linkWidthNormalize >= 20001 && linkWidthNormalize <= 40000) {
return 10;
} else if (linkWidthNormalize >= 9001 && linkWidthNormalize <= 20000) {
return 8;
} else if (linkWidthNormalize >= 4001 && linkWidthNormalize <= 9000) {
return 6;
} else if (linkWidthNormalize >= 10 && linkWidthNormalize <= 4000) {
return 4;
} else {
return 2;
}
// return linkWidthNormalize;
})
.attr("stroke", "rgba(251, 130, 30, 0.5)")
var nodeElements = g.append("g") // use g.append instead of svg.append to enable zoom
.attr("class", "nodes")
.selectAll("circle")
.data(nodes)
.enter().append("circle")
.attr("r", 12)
.attr("fill", getNodeColor)
.attr("stroke", "#fff")
.attr('stroke-width', 2)
.call(dragDrop)
//.on('click', selectNode) // alternative
.on('mouseover', selectNode)
var textElements = g.append("g") // use g.append instead of svg.append to enable zoom
.attr("class", "texts")
.selectAll("text")
.data(nodes)
.enter().append("text")
.text(function(node) {
return node.label
})
.attr("font-size", 10)
.attr("font-family", "sans-serif")
.attr("text-anchor", "middle")
.attr("fill", "#333")
.attr("style", "font-weight:bold; -webkit-text-stroke: 1px #fff; text-shadow: 3px 3px 0 #fff, -1px -1px 0 #fff, 1px -1px 0 #fff, -1px 1px 0 #fff, 1px 1px 0 #fff")
.attr("dx", 0)
.attr("dy", 20)
simulation.nodes(nodes).on('tick', () => {
nodeElements
.attr('cx', function(node) {
return node.x
})
.attr('cy', function(node) {
return node.y
})
textElements
.attr('x', function(node) {
return node.x
})
.attr('y', function(node) {
return node.y
})
linkElements
.attr('x1', function(link) {
return link.source.x
})
.attr('y1', function(link) {
return link.source.y
})
.attr('x2', function(link) {
return link.target.x
})
.attr('y2', function(link) {
return link.target.y
})
})
simulation.force("link").links(links)
&#13;
我无法找到代码的任何问题。我已经尝试恢复我的动作(将文件移回其初始位置)但没有任何变化。它还是那样的。
这有什么问题?这让我发疯了。
答案 0 :(得分:0)
我终于找到了罪魁祸首。
希望这会像对我一样粗心对任何人发出警告: d3.js cannot read iso-8859-1
编码。我的HTML文件使用iso-8859-1
编码,同时JSFiddle正在使用utf-8
。这就是为什么它在JSFiddle中起作用但不在我的最后。
所以改变这个:
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
到此:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
修复了问题。