Дублирование дат на оси

Я пытаюсь отобразить некоторые пары даты/значения на своем графике, но на оси X есть повторяющиеся значения:

Это код для рендеринга тиков:

chart
    .select(".x-axis")
    .attr("transform", `translate(0,${height})`)
    .call(d3.axisBottom(xScale).ticks(data.length).tickFormat(d3.timeFormat("%y-%m")));

Полный фрагмент кода:

var data = [{
        date: "2020-01-01",
        popularity: 50
    },
    {
        date: "2020-02-01",
        popularity: 150
    },
    {
        date: "2020-03-01",
        popularity: 200
    },
    {
        date: "2020-04-01",
        popularity: 250
    },
    {
        date: "2020-05-01",
        popularity: 200
    },
    {
        date: "2020-06-01",
        popularity: 250
    },
    {
        date: "2020-07-01",
        popularity: 350
    }
];

// Create SVG and padding for the chart
const svg = d3
    .select("#chart")
    .append("svg")
    .attr("height", 400)
    .attr("width", 600);
    
const margin = {
    top: 50,
    bottom: 50,
    left: 50,
    right: 50
};

const chart = svg.append("g").attr("transform", `translate(${margin.left},0)`);
const width = +svg.attr("width") - margin.left - margin.right;
const height = +svg.attr("height") - margin.top - margin.bottom;
const grp = chart
    .append("g")
    .attr("transform", `translate(-${margin.left},-${margin.top})`);

// Add empty scales group for the scales to be attatched to on update 
chart.append("g").attr("class", "x-axis");
chart.append("g").attr("class", "y-axis");


function updateScales(data) {
    // Create scales
    const yScale = d3
        .scaleLinear()
        .range([height, 0])
        .domain([0, d3.max(data, dataPoint => dataPoint.popularity)]);

    // Set Date Range
    var earliestDate = new Date(data[0].date);
    var lastDate = new Date(data[data.length - 1].date);

    // Setting up date on the X axis
    const xScale = d3
        .scaleLinear()
        .range([0, width])
        .domain([earliestDate, lastDate]);

    return {
        yScale,
        xScale
    };
}

function updateAxes(data, chart, xScale, yScale) {
    chart
        .select(".x-axis")
        .attr("transform", `translate(0,${height})`)
        .call(d3.axisBottom(xScale).ticks(data.length).tickFormat(d3.timeFormat("%y-%m")));

    chart
        .select(".y-axis")
        .attr("transform", `translate(0, 0)`)
        .call(d3.axisLeft(yScale));
}


function updateChart(data) {
    const {
        yScale,
        xScale
    } = updateScales(data);
    updateAxes(data, chart, xScale, yScale);
}

updateChart(data);
#chart {
    text-align: center;
    margin-top: 40px;
  }
<!DOCTYPE html>
<head>
  <meta charset = "utf-8">
</head>

<body>
<button>Update Chart</button>
<div id = "chart"></div>
</body>


<script src = "https://cdnjs.cloudflare.com/ajax/libs/d3/6.3.1/d3.js" integrity = "sha512-CQk1Bd5qczb5n31LOjQ8nmasspRasRP95SzVXcjM2Crm+3pmP/evOvFqrHeR26IA6pkgraiKom0aGWF29d8xqQ= = " crossorigin = "anonymous"></script>
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
98
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

используйте .scaleTime() со списком дат

 var extent = d3.extent(data.map(_d=>new Date(_d.date)));

 const xScale = d3.scaleTime().range([0, width])
            .domain(extent);

var data = [{
        date: "2020-01-01",
        popularity: 50
    },
    {
        date: "2020-02-01",
        popularity: 150
    },
    {
        date: "2020-03-01",
        popularity: 200
    },
    {
        date: "2020-04-01",
        popularity: 250
    },
    {
        date: "2020-05-01",
        popularity: 200
    },
    {
        date: "2020-06-01",
        popularity: 250
    },
    {
        date: "2020-07-01",
        popularity: 350
    }
];

// Create SVG and padding for the chart
const svg = d3
    .select("#chart")
    .append("svg")
    .attr("height", 400)
    .attr("width", 600);
    
const margin = {
    top: 50,
    bottom: 50,
    left: 50,
    right: 50
};

const chart = svg.append("g").attr("transform", `translate(${margin.left},0)`);
const width = +svg.attr("width") - margin.left - margin.right;
const height = +svg.attr("height") - margin.top - margin.bottom;
const grp = chart
    .append("g")
    .attr("transform", `translate(-${margin.left},-${margin.top})`);

// Add empty scales group for the scales to be attatched to on update 
chart.append("g").attr("class", "x-axis");
chart.append("g").attr("class", "y-axis");


function updateScales(data) {
    // Create scales
    const yScale = d3
        .scaleLinear()
        .range([height, 0])
        .domain([0, d3.max(data, dataPoint => dataPoint.popularity)]);

    var extent = d3.extent(data.map(_d=>new Date(_d.date)));
    // Setting up date on the X axis
    const xScale = d3
        .scaleTime()
        .range([0, width])
        .domain(extent);

    return {
        yScale,
        xScale
    };
}

function updateAxes(data, chart, xScale, yScale) {
    chart
        .select(".x-axis")
        .attr("transform", `translate(0,${height})`)
        .call(d3.axisBottom(xScale).ticks(data.length).tickFormat(d3.timeFormat("%y-%m")));

    chart
        .select(".y-axis")
        .attr("transform", `translate(0, 0)`)
        .call(d3.axisLeft(yScale));
}


function updateChart(data) {
    const {
        yScale,
        xScale
    } = updateScales(data);
    updateAxes(data, chart, xScale, yScale);
}

updateChart(data);
#chart {
    text-align: center;
    margin-top: 40px;
  }
<!DOCTYPE html>
<head>
  <meta charset = "utf-8">
</head>

<body>
<button>Update Chart</button>
<div id = "chart"></div>
</body>


<script src = "https://cdnjs.cloudflare.com/ajax/libs/d3/6.3.1/d3.js" integrity = "sha512-CQk1Bd5qczb5n31LOjQ8nmasspRasRP95SzVXcjM2Crm+3pmP/evOvFqrHeR26IA6pkgraiKom0aGWF29d8xqQ= = " crossorigin = "anonymous"></script>

Другие вопросы по теме