byłem krach głowę nad tym problemem od pewnego czasu ...Niezwykłe d3 zoom w klasie wielokrotnego użytku - to i wiążą
Mam zwykły konstruktor/prototyp obiektu (jak klasa) w JS, który przechowuje wszystkie mój wykres d3 logika:
figureGen = function(html_element) {
this.svg = d3.select(html_element)
.append('svg')
.style('width', '100%')
.style('height', '100%')
.append('g')
.attr("class", "sadrzalac")
.attr("transform", "translate(" + 0 + "," + 0 + ")");
this.element = element;
this.data = [];
this.yRange = d3.scale.linear();
this.xRange = d3.scale.linear();
this.xAxis = undefined;
this.yAxis = undefined;
this.width = undefined;
this.height = undefined;
this.zoom = undefined;
this.margin = {top: 20, right: 20, bottom: 20, left: 35};
this.svg.append("rect")
.attr("class", "clipPath")
.attr("transform", "translate(" + this.margin.left + "," + -this.margin.top + ")");
this.svg.append('g')
.attr("class","xaxis axis");
this.svg.append('g')
.attr("class", "yaxis axis");
}
dla konstruktora, a dla metody coś takiego
figureGen.prototype = {
constructor: figureGen,
init: function(sampledata, width, height){
var y_min = Number(d3.min(this.podaci, function (d) { return d.y;}));
var y_max = Number(d3.max(this.podaci, function (d) { return d.y;}));
var x_min = Number(d3.min(this.podaci, function (d) { return d.x;}));
var x_max = Number(d3.max(this.podaci, function (d) { return d.x;}));
var ukupan_opseg = y_max - y_min;
var spacer = (ukupan_opseg*25)/100;
this.xRange = d3.scale.linear().range([this.margin.left + 10, this.width - this.margin.right]).domain([x_min, x_max]);
this.yRange = d3.scale.linear().range([this.height - this.margin.top, this.margin.bottom]).domain([y_min-spacer, y_max+spacer]);
this.zoom = d3.behavior.zoom()
.x(this.xRange)
.y(this.yRange)
.scaleExtent([1, 5])
.center([this.width/2, this.height/2])
.size([this.width, this.height])
.on("zoom", this.zoomProcess());
this.svg
.attr("width", this.sirina)
.attr("height", this.visina)
.call(this.zoom);
this.xAxis = d3.svg.axis()
.scale(this.xRange)
.innerTickSize(-this.height+40)
.outerTickSize(5)
.tickPadding(10)
.tickFormat(d3.format("d"));
this.yAxis = d3.svg.axis()
.scale(this.yRange)
.orient("left")
.innerTickSize(-this.width)
.outerTickSize(5)
.tickPadding(10)
.tickSubdivide(false);
this.svg.select('.xosa')
.attr("transform", "translate(0," + (this.height - this.margin.bottom) + ")")
.call(this.xAxis);
this.svg.select(".yosa")
.attr("transform", "translate(" + (this.margin.left) + ",0)")
.call(this.yAxis);
},
zoomProcess: function{
this.svg.select(".xaxis").call(this.xAxis);
this.svg.select(".yaxis").call(this.yAxis);
console.log(this.svg);
}
}
i problem jest w zoomProcess metoda, która zawsze zwraca (loguje) element HTML na obiekcie this.svg zamiast this.svg, który może .select. Funkcja powiększania jest poprawnie dołączona do mojego elementu, a na myszy, gdy zacznie się powiększanie, ale pojawi się komunikat o błędzie, że nie można wykonać tej operacji na tym.xAxis.
Co jeszcze dziwniejsze, kiedy wywołać zoomProcess z innego źródła, jak przycisk kliknij jego dziennika konsola wysyła przedmiotu właściwego this.svg a nie elementu HTML, więc wydaje się, że błąd pochodzi z obsługi zdarzeń zoom. Co jest nie tak?
Są to dwa przykłady Szukałem na stronie:
http://bl.ocks.org/stepheneb/1182434
http://bl.ocks.org/mbostock/7ec977c95910dd026812
EDIT: Teraz myślę, że chyba powinni stosować .bind() na tym obiekcie, tak aby jego odniesienie pozostaje takie samo podczas przechodzenia do metody zoomProcedura. Wciąż nie jestem pewien, jak to zrobić.
Co to oznacza: "_ i problem jest w metodzie zoomProcess, która zawsze zwraca (loguje) element HTML na obiekcie this.svg zamiast this.svg, który może .select. Zachowanie zoomu jest poprawnie dołączone do mojego elementu, a na myszy, gdy zacznie się powiększanie, ale wyskakuje błąd mówiąc, że to .call na this.xAxis_ "możesz chcieć go edytować, żeby miało to sens." –