Using different fields for ordering and labeling
Hi,
My data looks like this:
[
{'commit': 'a', 'timestamp': 1234, 'benchmark': 'b', 'value': 1}
...
]
I am trying to plot ordinal values on the x axis using a temporal scale (timestamps). This
vl.markLine()
.encode(
vl.x()
.fieldT('timestamp')
.title("Commit")
.axis({
labelAngle: 90,
}),
vl.y().fieldQ('value').scale({ zero: false }).title("Run time (s)"),
vl.color().fieldN('benchmark').title("Benchmark"),
vl.tooltip().fieldN('commit')
)
puts each point in its proper place. However the axis labels are the timestamps themselves. I would like to print the commit field instead, placed at the proper timestamp (thus possibly irregularly spaced). I have tried a few things such as defining a new scale for the axis and proving a list of values, or registering a new vega.expressionFunction and calling it from a labelExpr, without success. The labelExpr is passed objects with scaled values. The information loss prevents me from easily retrieving the proper label.
I am sure this can be done in vega/vega-lite as this sounds relatively trivial. However I could not figure it out by reading the docs or the examples.
Thanks!
I should note that this is easy to do with bar charts. The difficulty lies in placing custom text labels at the proper fieldT points in a line or scatter plot. An alternative is doing this directly in d3, but that's something I'd rather avoid for now.
By the way, I would gladly take this discussion elsewhere as it is not an issue per se, but haven't found any support forums or Gitter channel, for example.
This is how I would draw the axis in d3:
const margin = {top: 20, right: 10, bottom: 20, left: 10};
const width = chartDiv.offsetWidth - margin.left - margin.right,
height = chartDiv.offsetHeight - margin.top - margin.bottom;
const g = d3.select("#chart").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
let xScale = d3.scaleTime()
.domain([start, end])
.range([0, width]);
let xAxisGenerator = d3.axisBottom(xScale)
.ticks(nTicks)
.tickValues(tickValues)
.tickFormat(textFromValue);
let xAxis = g.append("g")
.call(xAxisGenerator)
.selectAll("text")
.style("text-anchor", "start")
.attr("dx", ".8em")
.attr("dy", "-5px")
.attr("transform", function(d) {
return "rotate(90)"
});
which produces the following axis:
