Gibt es eine einfache Möglichkeit, Textbeschriftungen zwischen Zecken auszurichten?
Hier ist meine Zeitachse mit Beschriftungen über den Häkchen:
Ich möchte diese Etiketten gerne hier platzieren:
Am Ende hatte ich einen der Lars Kotthoffs Ratschläge .
Jedes Mal, wenn ich call(axis)
benutze, passe ich auch Beschriftungen an.
Hier ist vereinfachter Code:
function renderAxis() {
axisContainer
.transition().duration(300)
.call(axis) // draw the standart d3 axis
.call(adjustTextLabels); // adjusts text labels on the axis
}
function adjustTextLabels(selection) {
selection.selectAll('.major text')
.attr('transform', 'translate(' + daysToPixels(1) / 2 + ',0)');
}
// calculate the width of the days in the timeScale
function daysToPixels(days, timeScale) {
var d1 = new Date();
timeScale || (timeScale = Global.timeScale);
return timeScale(d3.time.day.offset(d1, days)) - timeScale(d1);
}
Update:
Übrigens, hier ist eine calendar Demo, die ich am Ende beendet habe: http://bl.ocks.org/oluckyman/6199145
Es gibt keine einfache (d. H. Eingebaute) Möglichkeit, dies zu tun, aber Sie können es trotzdem erreichen. Es gibt einige Möglichkeiten. Am einfachsten ist es wahrscheinlich, die Funktion tickFormat
zu verwenden, um ein Format mit einer geeigneten Anzahl von Leerzeichen vor/hinter den Zahlen anzugeben. Dies müsste jedoch für jede Anwendung manuell abgestimmt werden.
Alternativ können Sie die Beschriftungselemente auswählen, nachdem sie gezeichnet wurden, und ein geeignetes transform
-Attribut hinzufügen, das sie entsprechend verschiebt. Dies müsste wiederum manuell abgestimmt werden.
Ihre dritte Option besteht darin, zwei verschiedene Achsen zu haben, eine für die Hilfsstriche und eine für die Beschriftungen. Die Idee ist, dass die Achse, die die Ticks bereitstellt, keine Labels und die andere keine Ticks hat. Sie müssten die Tick-Werte entsprechend einstellen, aber Sie müssten zumindest nicht den richtigen Offset erraten.
Sie können dies tun, indem Sie axis.tickSize(major[[,minor],end])
und .tickSubdivide()
verwenden. Ihre Häkchen sind so eingestellt, dass sie mit den großen Häkchen übereinstimmen. Wenn Sie jedoch die Höhe dieser Häkchen auf 0 setzen und eine Höhe für kleinere Häkchen festlegen und angeben, dass zwischen jedem Paar großer Häkchen ein kleiner Häkchen gesetzt ist, werden Sie enden mit Tick-Labels zwischen Ihren Ticks Ihr Code würde so aussehen:
var myAxis = d3.svg.axis()
.ticks(15)
.tickSubdivide(1)
.tickSize(0, 6, 0);
Beachten Sie, dass Sie explizit eine Endgröße festlegen müssen. Wenn Sie nur zwei Zahlen angeben, werden diese als major
und end
interpretiert, und minor
wird standardmäßig auf 0 gesetzt.
Hier ist eine Geige.
Schon ein paar gute Antworten, nur um noch eine hinzuzufügen. Beachten Sie die Verwendung von text-anchor
.
Gleiche Idee: Wählen Sie nach Ihrem Anruf den Text aus und positionieren Sie ihn neu.
.call(xAxis)
.selectAll(".tick text")
.style("text-anchor", "start")
.attr("x", axisTextAdjust)
Ich mache das oft durch Stapeln mehrerer Achsen, jede mit einem benutzerdefinierten .tickFormat()
.
Wenn ich Etiketten zwischen zwei Daten platziere, mache ich oft Folgendes:
@timeDaysAxisLabels = d3.svg.axis()
.scale(@timescale)
.orient('bottom')
.ticks(d3.time.hour.utc, 12) # I want ticks at noon, easiest to just get them ever 12 hours
.tickFormat((d) =>
# only draw labels at noon, between the date boundaries
if d.getUTCHours() == 12
# draw the label!
formatter = d3.time.format.utc('%a %d %b') # "Mon 12 Apr"
return formatter(d)
else
# not noon, don't draw anything
return null)
.tickSize(0)
.tickPadding(30)
Ich werde auch eine separate Achse ohne Beschriftungen erstellen und eine .tickSize()
ungleich Null, um Ticks zu zeichnen, aber dieser Block oberhalb positioniert Datumsbeschriftungen in der Mitte der "Spalte".
Vielleicht möchten Sie D3FC verwenden, das einen Drop-In-Ersatz für die D3-Achsenkomponente bietet, die diese Funktion unterstützt.
Hier ist ein Beispiel, das die D3-Achse d3.axisBottom
Durch das D3FC-Äquivalent fc.axisBottom
Ersetzt:
const axis = fc.axisBottom(linear)
.tickCenterLabel(true);
Das tickCenterLabel
zentriert die Achsenbeschriftungen wie gewünscht.
So sieht die Achse mit tickCenterLabel = false
Aus:
Und hier mit dem tickCenterLabel = true
:
Vollständige Offenlegung - Ich bin ein Betreuer und ein Mitwirkender an D3FC
svg.append("g")
.attr("class", "axis axis-years")
.attr("transform", "translate(0," + (height + 1) + ")")
.call(xAxis)
.selectAll("text")
.attr("x", "-1.8em")
.attr("y", ".00em")
.attr("transform", function (d) {
return "rotate(-90)"});