我正在尝试仅将平移(暂时不想缩放)添加到我的 D3 力导向图形可视化中。无论我尝试什么,我都会收到错误消息 - “无法读取 null 的属性‘翻译’”。我觉得好像我在设置我找到的所有示例中的内容,但有些地方不太对劲。
这是我最近的尝试。据我所知,相关代码应该在我定义 svg 的顶部,但我包括了其余部分,以防有什么我不知道的影响它。
var isiOS = false;
var agent = navigator.userAgent.toLowerCase();
if(agent.indexOf('iphone') >= 0 || agent.indexOf('ipad') >= 0){
isiOS = true;
};
var h = 1000;
var w = 1000;
var width = 1500,
var height = 1500;
var default_node_color = '#FF9900';
var shining_node_color = '#fc5f05';
var text_color = 'white';
var link_color = '#666699';
var svg = d3.select("#chart").append("svg")
.attr("width", width)
.attr("height", height)
.call(d3.behavior.zoom().on("zoom", function() {
svg.attr("transform", "translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")");
}))
.append('g');
var g = svg.append('g');
var force = d3.layout.force()
.gravity(0.05)
.distance(100)
.charge(-100)
.size([w, h]);
d3.xhr("{{ url_for('visualization_data', interactions_filter = interactions_filter)}}")
.header("Content-Type", "application/json")
.post(
JSON.stringify({
"fileindicator": "{{fileindicator}}"
}), function(error, rawData) {
if (error) throw error;
var json = JSON.parse(rawData.response);
force
.nodes(json.nodes)
.links(json.links)
.start();
var link_scale = d3.scale.linear()
.domain([0, d3.max(json.links, function(d) {
return (d.value);
})])
.range([1, 13]);
var link = g.selectAll(".link")
.data(json.links)
.enter().append("line")
.attr("class", "link")
.style("stroke-width", function(d) {
return link_scale(d.value);
})
.style('stroke', link_color)
.attr("fill-opacity", .75);
var node = g.selectAll(".node")
.data(json.nodes)
.enter().append("g")
.attr("class", "node")
.call(force.drag)
.style("fill", default_node_color);
var radius_scale = d3.scale.sqrt()
.domain([0, d3.max(json.nodes, function(d) {
return (d.n_interactions);
})])
.range([2, 17]);
if (isiOS) {
// single click centers node
var centerEvent = "click";
} else {
// double click centers node
var centerEvent = "dblclick";
}
var all_links = d3.selectAll('.link');
var all_nodes = d3.selectAll('.node');
//populate select box
var select_box = $('.chzn-select');
select_box.empty();
select_box.trigger('chosen:updated');
var character_to_node_id = []
for (var i = 0; i < all_nodes[0].length; i++) {
var option = '<option value="' + all_nodes[0][i].__data__.index + '">' + all_nodes[0][i].__data__.name + '</option>';
character_to_node_id.push(option);
select_box.append("<option value='' selected='selected'></option>");
select_box.append(character_to_node_id);
var onClick = window.onClick = function(d, i) {
// console.log(this)
// console.log('d, i, this:', d, i, this);
var index_of_clicked_node = d.index;
// Moves clicked node to center
var dcx = (w / 2 - d.x * zoom.scale());
var dcy = (h / 2 - d.y * zoom.scale());
zoom.translate([dcx, dcy]);
g.transition()
.duration(2000)
.attr("transform", "translate(" + dcx + "," + dcy + ")scale(" + zoom.scale() + ")");
//select all links NOT related to the clicked node and fade
var fade_links = d3.selectAll('.link').filter(function(d) {
return index_of_clicked_node !== d.source.index && index_of_clicked_node !== d.target.index;
});
// console.log(fade_links);
fade_links.style('opacity', .2);
var active_links = d3.selectAll('.link').filter(function(d) {
return index_of_clicked_node === d.source.index || index_of_clicked_node === d.target.index;
});
// active_links.style('stroke', 'red')
active_links.style('opacity', .85);
var active_link_id_list = [];
active_links[0].forEach(function(link) {
active_link_id_list.push(link.__data__.target.index)
active_link_id_list.push(link.__data__.source.index)
});
console.log('number of active links: ', active_link_id_list.length);
//select all nodes not connected to the clicked node and fade
var fade_nodes = d3.selectAll('.node').filter(function(d) {
return !active_link_id_list.includes(d.index);
});
fade_nodes.style('opacity', .2);
var active_nodes = d3.selectAll('.node').filter(function(d) {
return active_link_id_list.includes(d.index);
});
console.log('number of active nodes: ', active_nodes);
d3.selectAll('circle').filter(function(d, i) {
if (d.name === name) {
// call click event on the circle
window.onClick(d, i);
}
});
active_nodes.style('opacity', .85)
.transition()
.duration(1000)
.style('fill', shining_node_color)
.transition()
.duration(1000)
.style('fill', default_node_color);
};
node.append('circle')
.attr("class", "circle")
.attr("r", function(d, i) {
return radius_scale(d.n_interactions);
})
.style('opacity', .85)
.style('stroke', 'black')
.style('stroke-width', 10)
.style('stroke-opacity', 0.0)
.call(force.drag)
.on(centerEvent, onClick);
var text_scale = d3.scale.linear()
.domain([0, d3.max(json.nodes, function(d) {
return (d.n_interactions);
})])
.range([6, 16]);
node.append("text")
.attr("dx", 12)
.attr("dy", ".35em")
.attr('fill', 'black')
.text(function(d) {
return d.name
})
.style("font-size", function(d) {
return text_scale(d.n_interactions) + "px";
})
.style('font-family', "futura-pt")
.style('fill', text_color);
force.on("tick", function() {
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;
});
node.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
});
});
$('#loading-text').hide();