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

时间:2018-01-02 11:21:33

标签: 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);
}

1 个答案:

答案 0 :(得分:2)

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

  

如果比例尺没有实现scale.ticks,则此方法无效,   与带和点尺度一样

但是,您可以使用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以适应数据的长度,但这应该是一个开始。