Синтаксис для осевого перехода в svg/d3
У меня невероятно простой синтаксический вопрос. Я изучаю d3, SVG и Javascript, главным образом, редактируя код другого пользователя, что бросает вызов.
Целью является обновление оси y после обновления данных и шкалы, основанной на данных. Я хочу, чтобы ось - тики, метки и все - переход с доменом данных. Ось не обновляется. Проблема может быть связана с областью действия, или я ссылаюсь на неправильный элемент SVG. (Фактически, несколько графиков обновляются одновременно, но я просто фокусируюсь на оси одного из них здесь.)
function makeYaxis (chart, scale, nticks, label, width, height, xmf, visName)
{
var yAxis = d3.svg.axis()
.scale(scale)
.orient("left")
.ticks(nticks);
chart.append("svg:g")
.attr("class","y axis")
.append("g")
.attr("transform","translate(60,1)") // fix magic #
.call(yAxis);
var xMove = xmf.yylMarginFactor * width - 1;
var yMove = (((1 - xmf.xxbMarginFactor) * height +
xmf.xxtMarginFactor * height) / 2);
chart.append("svg:text")
.attr("class", visName + "xLabel")
.attr("x", 0)
.attr("y", 0)
.attr("dy", "-2.8em")
.text(label)
.attr("transform", "rotate(-90) translate(-" + yMove + "," + xMove + ")");
}
function makeYscale (plotMargin, thedata, xmf)
{
var dataMin = d3.min(thedata[0]);
var dataMax = d3.max(thedata[0]);
var yyMargin = d3.max([plotMargin * (dataMax - dataMin),0.05]);
var yy = d3.scale.linear()
.domain([dataMin - yyMargin, yyMargin + dataMax])
.range([(1 - xmf.xxbMarginFactor) * height, xmf.xxtMarginFactor * height]);
return yy;
}
// Set up this visualization
var chart = d3.select("#vis1")
.append("svg:svg")
.attr("class", "vis1chart")
.attr("width", width)
.attr("height", height);
var yy = makeYscale(plotMargin, thetas, xmf);
makeYaxis(chart, yy, nYTicks, "parameter", width, height, xmf, "vis1");
var points = chart.selectAll("circle.vis1points")
.data(thetas)
.enter().append("svg:circle")
.attr("class", "vis1points")
.attr("cx", function (d, i) { return xx(i); })
.attr("cy", function (d, i) { return yy(d); })
.attr("r", 3);
points.transition()
.attr("cx", function (d, i) { return xx(i); })
.attr("cy", yy)
.duration(dur);
vis1move();
function vis1move ()
{
function movePoints ()
{
var tmp = chart.selectAll(".vis1points").data(thetas[0], function (d, i) { return i; } );
var opa1 = points.style("stroke-opacity");
var opa2 = points.style("fill-opacity");
tmp
.enter().insert("svg:circle")
.attr("class", "vis1points")
.attr("cx", function (d, i) { return xx(i); })
.attr("cy", yy)
.attr("r", 3)
.style("stroke-opacity", opa1)
.style("fill-opacity", opa2);
tmp.transition()
.duration(10)
.attr("cx", function (d, i) { return xx(i); })
tmp.exit()
.transition().duration(10).attr("r",0).remove();
};
// (Code for updating theta, the data, goes here)
// Update axes for this vis
yy = makeYscale(plotMargin, thetas, xmf);
var transition = chart.transition().duration(10);
var yAxis = d3.svg.axis()
.scale(yy)
.orient("left")
.ticks(4);
transition.select("y axis").call(yAxis);
movePoints(); // Previously had been before axis update (fixed)
}
Извините, я не могу получить это автономное.
Правильно ли transition.select.("y axis").call(yAxis)
? Есть ли что-то блестящее здесь?
Изменить: Чтобы все было просто, теперь у меня
// Update axes for this vis
yy = makeYscale(plotMargin, thetas, xmf);
var yAxis = d3.svg.axis().scale(yy);
chart.select("y axis").transition().duration(10).call(yAxis);
Мне интересно, если что-то вроде того, что я создал ось в первую очередь (в makeYaxis()
), мешает мне правильно ее выбирать. Функция yy
возвращает правильные значения под капотом, а точки данных получаются на графике и масштабируются должным образом. Это просто, что ось "застряла".
Ответы
Ответ 1
Следуя советам и примерам здесь, я наткнулся на то, что кажется решением.
Во-первых, в функции makeYaxis()
я удалил строку .append("g")
. Я также обновил имя класса до yaxis
. Теперь функция читает
function makeYaxis (chart, scale, nticks, label, width, height, xmf, visName)
{
var yAxis = d3.svg.axis()
.scale(scale)
.orient("left")
.ticks(nticks);
chart.append("svg:g")
.attr("class","yaxis") // note new class name
// .append("g")
.attr("transform","translate(60,1)")
.call(yAxis);
// everything else as before
}
Затем я добавил дополнительный период в мой вызов select(".yaxis")
:
chart.select(".yaxis").transition().duration(10).call(yAxis);
Буду очень признателен, если кто-нибудь сможет мне объяснить, почему это решение работает.