Je ne suis toujours pas sûr de votre problème, car la hauteur réelle de la barre est calculée par l'échelle même que vous utilisez pour ajouter les rectangles. Et, si vous ajoutez effectivement les rectangles, vous définissez déjà la valeur de l'élément height
attribut !
Voyons un exemple. Il s'agit d'un diagramme à barres utilisant votre échelle logarithmique (j'utilise ici D3 v4, mais le principe est le même) et ces données fictives :
var data = [2000, 5000, 3000, 8000, 1500];
Comme vous pouvez le constater, il y a un minimum et un maximum. J'ai mis un padding de 20px dans l'échelle :
var yScale = d3.scaleLog()
.range([height - padding, padding])
.domain([d3.min(data), d3.max(data)]);
La première valeur de la plage est donc h - padding
et notre dernière valeur est juste padding
. Voici le tableau :
var width = 300,
height = 400,
padding = 20;
var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height);
var data = [2000, 5000, 3000, 8000, 1500];
var xScale = d3.scaleBand()
.range([50, width])
.domain(d3.range(data.length))
.padding(0.2);
var yScale = d3.scaleLog()
.range([height - padding, padding])
.domain([d3.min(data), d3.max(data)]);
var bars = svg.selectAll("foo")
.data(data)
.enter()
.append("rect")
.attr("x", (d, i) => xScale(i))
.attr("width", xScale.bandwidth())
.attr("height", d => height - padding - yScale(d))
.attr("y", d => yScale(d))
.attr("fill", "teal");
var gX = svg.append("g")
.attr("transform", "translate(0," + (height - padding) + ")")
.call(d3.axisBottom(xScale));
var gY = svg.append("g")
.attr("transform", "translate(50,0)")
.call(d3.axisLeft(yScale));
<script src="//d3js.org/d3.v4.min.js"></script>
Supposons que vous vouliez calculer la hauteur de la première barre. Nous pouvons voir, en inspectant le DOM, que sa hauteur est de 61.867984771728516
pixels :
var width = 300,
height = 400,
padding = 20;
var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height);
var data = [2000, 5000, 3000, 8000, 1500];
var xScale = d3.scaleBand()
.range([50, width])
.domain(d3.range(data.length))
.padding(0.2);
var yScale = d3.scaleLog()
.range([height - padding, padding])
.domain([d3.min(data), d3.max(data)]);
var bars = svg.selectAll("foo")
.data(data)
.enter()
.append("rect")
.attr("x", (d, i) => xScale(i))
.attr("width", xScale.bandwidth())
.attr("height", d => height - padding - yScale(d))
.attr("y", d => yScale(d))
.attr("fill", "teal");
var gX = svg.append("g")
.attr("transform", "translate(0," + (height - padding) + ")")
.call(d3.axisBottom(xScale));
var gY = svg.append("g")
.attr("transform", "translate(50,0)")
.call(d3.axisLeft(yScale));
console.log(d3.select("rect").node().height.animVal.value)
<script src="//d3js.org/d3.v4.min.js"></script>
Mais il s'agit simplement de la première valeur de l'intervalle ( height - padding
) moins yScale(2000)
:
var width = 300,
height = 400,
padding = 20;
var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height);
var data = [2000, 5000, 3000, 8000, 1500];
var xScale = d3.scaleBand()
.range([50, width])
.domain(d3.range(data.length))
.padding(0.2);
var yScale = d3.scaleLog()
.range([height - padding, padding])
.domain([d3.min(data), d3.max(data)]);
var bars = svg.selectAll("foo")
.data(data)
.enter()
.append("rect")
.attr("x", (d, i) => xScale(i))
.attr("width", xScale.bandwidth())
.attr("height", d => height - padding - yScale(d))
.attr("y", d => yScale(d))
.attr("fill", "teal");
var gX = svg.append("g")
.attr("transform", "translate(0," + (height - padding) + ")")
.call(d3.axisBottom(xScale));
var gY = svg.append("g")
.attr("transform", "translate(50,0)")
.call(d3.axisLeft(yScale));
console.log(height - padding - yScale(2000))
<script src="//d3js.org/d3.v4.min.js"></script>
C'est d'ailleurs cette valeur qui est utilisée pour définir la hauteur des barres :
.attr("height", d => height - padding - yScale(d))