#javascript #d3.js #svg #append #bar-chart
#javascript #d3.js #svg #добавить #гистограмма
Вопрос:
При нажатии кнопки как красная женщина (непривитая), так и синяя женщина (привитая) должны обновляться, чтобы отразить новое значение. В настоящее время при нажатии кнопки красная женщина обновляется, но синяя женщина воссоздается в том месте, в которое она должна быть обновлена. Как я могу заставить синюю женщину переходить и обновляться, как красная женщина?
Здесь вы можете увидеть, где воссоздана синяя женщина:
Я создал две глобальные переменные:
var numOfPartner = 'zero';
var status = 0;
Здесь создаются данные при загрузке и вводится красное изображение:
d3.csv("link to data", function(error, data) {
if (error) {
console.log("error reading file");
}
data.sort(function(a, b) {
return d3.descending( a.status, b.status);
});
// you should calculate using d3.max for your data
widthScale.domain([0, d3.max(data, function(d) {
return d.start;
})]);
heightScale.domain(data.map(function(d) {
return d.average;
}).slice(1));
var rects = svg.selectAll("rect")
.data(([data[0]]))
.enter()
.append("rect");
rects
.attr("x", 0)
.attr("y", function(d) {
return heightScale(d.status);
})
.attr("width", function(d) {
return widthScale( d.average);
})
.attr("height", heightScale.rangeBand());
svg.selectAll("text")
.attr("class", "label")
.data(([data[0]]))
.enter()
.append("text")
.text(function(d) {
return d.average " %";
})
.attr("x", function(d) {
return widthScale( d.average) 5;
})
.attr('y', '-45')
.attr("fill", "#8a8c8e")
.attr("font-size", "24")
.attr("font-weight", "700")
// Style the axis
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," height ")")
.call(xAxis)
.attr("fill", "#808285");
// Label below x axis
svg.append("text")
.attr("class", "xlabel")
.attr("transform", "translate(" width / 2 " ,"
height ")")
.style("text-anchor", "middle")
.attr("dy", "0")
.text(" ")
.attr("fill", "#5582b0")
.attr("font-weight", "600");
svg.selectAll("image1")
.data(([data[0]]))
.enter()
.append("svg:image")
.attr("x", function(d) {
return widthScale( d.average) - 45;
})
.attr('y', '-40')
.attr("height", 200)
.attr("width", 115)
.attr("xlink:href", "link to red woman");
Вот функция обновления кнопки, в которой красная женщина работает, а синяя — нет:
d3.selectAll("button").on("click", function() {
if (this.id == "unvaccinated")
status = 0;
else if (this.id == "vaccinated") {
status = 1;
} else {
numOfPartner = this.id;
}
svg.selectAll("image2")
.data(([data[1]]))
.enter()
.append("svg:image")
.attr("x", function(d) {
return widthScale(data[1][numOfPartner]) - 45;
})
.attr('y', '-40')
.attr("height", 200)
.attr("width", 115)
.attr("xlink:href", "link to blue woman");
rects
.data(data)
.transition()
.duration(1000)
.ease("linear")
.attr("width", function(d) {
return widthScale(data[status][numOfPartner]);
});
svg.selectAll("text")
.data(([data[0]]))
.transition()
.duration(1000)
.ease("linear")
.attr("x", function(d) {
return widthScale(data[status][numOfPartner])
})
.text(function(d) {
return data[status][numOfPartner] " %"
});
svg.selectAll("image")
.data(([data[0]]))
.transition()
.duration(1000)
.ease("linear")
.attr("x", function(d) {
//get correct number
return widthScale(data[status][numOfPartner]) - 45;
});
svg.selectAll("image2")
.data(([data[1]]))
.transition()
.duration(1000)
.ease("linear")
.attr("x", function(d) {
//get correct number
return widthScale(data[1][numOfPartner]) - 45;
});
});
});
Я пытался поиграть с функцией нажатия кнопки on, а также с извлекаемыми данными, но мне не повезло.
Ответ №1:
Трудно на 100% сказать, что не так, не видя данных или живой демонстрации, но я вижу проблему в обратном вызове click. Переместите этот код в обратный d3.csv
вызов:
svg.selectAll("image2")
.data(([data[1]]))
.enter()
.append("svg:image")
.attr("x", function(d) {
return widthScale(data[1][numOfPartner]) - 45;
})
.attr('y', '-40')
.attr("height", 200)
.attr("width", 115)
.attr("xlink:href", "link to blue woman");
Это добавляет новый элемент в ваш SVG, а не делает обновление. Вероятно, это не то, что вы хотите при обратном вызове click. Это должно быть где-то в функции инициализации. У вас есть правильный код обновления позже в обратном вызове, но это не будет работать должным образом, потому что был добавлен новый элемент.
Еще одна вещь, я заметил, что вы используете image1
в обратном вызове данных и image1
в обратном вызове click. Убедитесь, что это правильно, а не опечатка.