javascript - 无法将基于时间的 x 轴上的刻度数设置为条形图的自定义数量

标签 javascript d3.js bar-chart axis-labels

我目前正在使用以下代码将基于时间的 x 轴上的刻度数设置为 5;但是,无论我在“ticks()”中插入什么数字,每个滴答声都会继续显示。

我用来将刻度数设置为 5 的代码

let xAxisLower = d3.axisBottom(x)
        .ticks(5)
        .tickFormat(d3.timeFormat("%m-%d"))
        .tickPadding(15);

如何将 x 轴上的刻度数设置为 5,为什么我不能使用 .ticks(5) 这样做?

JavaScript 代码(请参阅 JSFiddle 了解更多详情)

tradeArr = [
    {date: "2017-06-15" , bps: 0},
    {date: "2017-06-14" , bps: 0},
    {date: "2017-06-13" , bps: 0},
    {date: "2017-06-12" , bps: 0},
    {date: "2017-06-09" , bps: 0},
    {date: "2017-06-08" , bps: 0},
    {date: "2017-06-07" , bps: 0},
    {date: "2017-06-06" , bps: 0},
    {date: "2017-06-05" , bps: 0},
    {date: "2017-06-02" , bps: 0},
    {date: "2017-06-01" , bps: 13.9},
    {date: "2017-05-31" , bps: 0},
    {date: "2017-05-30" , bps: 0},
    {date: "2017-05-29" , bps: 0},
    {date: "2017-05-26" , bps: 0},
    {date: "2017-05-25" , bps: 0},
    {date: "2017-05-24" , bps: 0},
    {date: "2017-05-23" , bps: 0},
    {date: "2017-05-22" , bps: 0},
    {date: "2017-05-19" , bps: 0},
    {date: "2017-05-18" , bps: 0},
    {date: "2017-05-17" , bps: 0},
    {date: "2017-05-16" , bps: 1.95},
    {date: "2017-05-15" , bps: 0},
    {date: "2017-05-12" , bps: 0}
];

tradeArr.forEach(obj => {
    obj.date = d3.timeParse("%Y-%m-%d")(obj.date);
})

generateBarChart(tradeArr);

function generateBarChart(data) {
    console.log(data);

    // chart configuration
    let margin = {
        top: 20,
        right: 20,
        bottom: 30,
        left: 50
    };

    let width;
    let height;

    let x = d3.scaleBand()
        .domain(data.map(function(d) { return d.date; }));

    let y = d3.scaleLinear()
        .domain([d3.min(data, function(d) { return d.bps; }), d3.max(data, function(d) { return d.bps; })])

    let xAxisLower = d3.axisBottom(x)
        .ticks(5)
        .tickFormat(d3.timeFormat("%m-%d"))
        .tickPadding(15);

    let yAxis = d3.axisLeft(y)
        .ticks(2)
        .tickSize(0)
        .tickPadding(15);

    let svg = d3
        .select("#price-chart-graph")
            .style("position", "relative") // strictly for the tooltip
        .append("svg") // append an svg to the div
            .style("overflow", "hidden")
            .style("position", "relative");

    let artboard = svg
                    .append("g")
                        .attr("transform", "translate(" + margin.left + ", " + margin.right + ")");

    let xAxisLowerEl = artboard.append("g") // x-axis
        .attr("class", "x-axis")
        .style("font-size", "14px");

    let yAxisEl = artboard.append("g") // y-axis
        .attr("class", "y-axis")
        .style("font-size", "14px");

    let bars = artboard.selectAll(".bar")
                    .data(data)
                    .enter().append("rect")
                    .style("fill", "black")

    function drawChart() {
        width = parseInt(d3.select("#price-chart-graph").style("width")) - margin.left - margin.right;
        height = parseInt(d3.select("#price-chart-graph").style("height")) - margin.top - margin.bottom;

        svg.attr("width", width + margin.left + margin.right) // give it width
        svg.attr("height", height + margin.top + margin.bottom) // give it height

        x.rangeRound([0, width], .05).padding(0.1);
        y.range([height, 0]);
        // call new x axis
        xAxisLowerEl.attr("transform", "translate(0," + height + ")").call(xAxisLower);
        yAxisEl.call(yAxis);

        bars
            .attr("x", function(d) { return x(d.date); })
            .attr("width", function(d) { return x.bandwidth()})
            .attr("y", function(d) { return y(d.bps); })
            .attr("height", function(d) { return height - y(d.bps); })

    }

    drawChart();

    window.addEventListener('resize', drawChart);
}

最佳答案

您的 x 轴是 scaleBand 类型,ticks() 不适用于带状轴。来自documentation :

This method has no effect if the scale does not implement scale.ticks, as with band and point scales

但是,您可以使用 tickValues() 显式设置值,因此您可以尝试将域过滤为五个值并手动设置。这可能会让您朝着正确的方向前进:

let tickInterval = 5;
let tickValues = data.map(function(d) { return d.date; }).filter(function(d, i) { return i % tickInterval === 0 });
let xAxisLower = d3.axisBottom(x)
    .tickFormat(d3.timeFormat("%m-%d"))
    .tickValues(tickValues)
    .tickPadding(15);

您可能需要调整 tickInterval 以适合您的数据长度,但这应该是一个开始。

关于javascript - 无法将基于时间的 x 轴上的刻度数设置为条形图的自定义数量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48060046/

相关文章:

javascript - 为什么当我指示更高版本的 NodeJS 时 "npm install"没有失败?

javascript - 动态处理时 Jquery 不工作

javascript - "sprite"在哪里定义的?

python - 将 x 轴刻度标签向左移动一位

javascript - 文档签名 : Getting an embedded recipient view without having templateID

javascript - 是否可以将 D3.tree() 与包含 parent 而不是 child 的数据集一起使用?

javascript - 更改 forceNetwork for networkD3 中图例文本的颜色

javascript - d3js 强制布局为每个节点动态添加图像或圆圈

javascript - 在 chart.js 的堆叠条形图中显示百分比和总数

javascript - D3 比例域不会使用所选数据进行更新。我得到负值