What is the best way to show only the weekdays on the x-axis?

My goal is to create a scatter-linked graph using D3.js, showcasing the people count for various shifts on different dates in January 2020. Here is the code snippet I am working with:

<!DOCTYPE html>
<html lang="en" >
<head>
  <meta charset="UTF-8">
  <title>Line Chart</title>
 <style>
   svg {
    font-family: Sans-Serif, Arial;
}
.line {
  stroke-width: 2;
  fill: none;
}

.axis path {
  stroke: black;
}

.text {
  font-size: 12px;
}

.title-text {
  font-size: 12px;
}
 </style>

</head>
<body>
<!-- partial:index.partial.html -->
<html>
  ...

I am seeking assistance in displaying only weekdays (Mon, Tue, etc.) on the x-axis without showing the month in between. Any help would be greatly appreciated!

Thank you.

Answer №1

To enhance your code, consider adding

.tickFormat(d3.timeFormat("%a"))
right after declaring the xAxis variable.

For an example, check out this link: https://codepen.io/nufrankz/pen/VwabXzJ

UPDATE: Use %a for abbreviated weekdays and %A for full weekday names. You can find a complete list of formatting options here

Answer №2

Make sure to utilize the tickFormat function with your desired timeFormat, for example:

var xAxis = d3.axisBottom(xScale)
            .tickFormat(d3.timeFormat("%a"))
            .ticks(7);

Here is a practical demonstration that may not be precisely what you need, but it demonstrates how to manage axis labels.

var data = [
  {
    name: "Regular",
    values: [
      {date: "2020-01-01", count: "2"},
      {date: "2020-01-02", count: "4"},
      {date: "2020-01-03", count: "8"},
      {date: "2020-01-04", count: "3"},
      {date: "2020-01-05", count: "5"}
    ]
  },
  {
    name: "Shift1",
    values: [
      {date: "2020-01-01", count: "2"},
      {date: "2020-01-02", count: "4"},
      {date: "2020-01-03", count: "8"},
      {date: "2020-01-04", count: "6"},
      {date: "2020-01-05", count: "1"}
    ]
  },
  {
    name: "Shift2",
    values: [
      {date: "2020-01-01", count: "3"},
      {date: "2020-01-02", count: "8"},
      {date: "2020-01-03", count: "4"},
      {date: "2020-01-04", count: "7"},
      {date: "2020-01-05", count: "6"}
    ]
  }
];

var width = 500;
var height = 300;
var margin = 50;
var duration = 250;

var lineOpacity = "0.25";
var lineOpacityHover = "0.85";
var otherLinesOpacityHover = "0.1";
var lineStroke = "1.5px";
var lineStrokeHover = "2.5px";

var circleOpacity = '0.85';
var circleOpacityOnLineHover = "0.25"
var circleRadius = 3;
var circleRadiusHover = 6;


/* Data Formatting */

var parseDate = d3.timeParse("%Y-%m-%d");

data.forEach(function(d) { 
  d.values.forEach(function(d) {
    d.date = parseDate(d.date);
    d.count = +d.count;    
  });
});

/* Scaling */
var xScale = d3.scaleTime()
  .domain(d3.extent(data[0].values, d => d.date))
  .range([0, width-margin]);

var yScale = d3.scaleLinear()
  .domain([0, d3.max(data[0].values, d => d.count)])
  .range([height-margin, 0]);

var color = d3.scaleOrdinal(d3.schemeCategory10);

/* Append SVG */
var svg = d3.select("#chart").append("svg")
  .attr("width", (width+margin)+"px")
  .attr("height", (height+margin)+"px")
  .append('g')
  .attr("transform", `translate(${margin}, ${margin})`);


/* Add line to SVG */
var line = d3.line()
  .x(d => xScale(d.date))
  .y(d => yScale(d.count));

let lines = svg.append('g')
  .attr('class', 'lines');

lines.selectAll('.line-group')
  .data(data).enter()
  .append('g')
  .attr('class', 'line-group')  
  .on("mouseover", function(d, i) {
      svg.append("text")
        .attr("class", "title-text")
        .style("fill", color(i))        
        .text(d.name)
        .attr("text-anchor", "middle")
        .attr("x", (width-margin)/2)
        .attr("y", 5);
    })
  .on("mouseout", function(d) {
      svg.select(".title-text").remove();
    })
  .append('path')
  .attr('class', 'line')  
  .attr('d', d => line(d.values))
  .style('stroke', (d, i) => color(i))
  .style('opacity', lineOpacity)
  .on("mouseover", function(d) {
      d3.selectAll('.line')
                    .style('opacity', otherLinesOpacityHover);
      d3.selectAll('.circle')
                    .style('opacity', circleOpacityOnLineHover);
      d3.select(this)
        .style('opacity', lineOpacityHover)
        .style("stroke-width", lineStrokeHover)
        .style("cursor", "pointer");
    })
  .on("mouseout", function(d) {
      d3.selectAll(".line")
                    .style('opacity', lineOpacity);
      d3.selectAll('.circle')
                    .style('opacity', circleOpacity);
      d3.select(this)
        .style("stroke-width", lineStroke)
        .style("cursor", "none");
    });


/* Add circles on the line */
lines.selectAll("circle-group")
  .data(data).enter()
  .append("g")
  .style("fill", (d, i) => color(i))
  .selectAll("circle")
  .data(d => d.values).enter()
  .append("g")
  .attr("class", "circle")  
  .on("mouseover", function(d) {
      d3.select(this)     
        .style("cursor", "pointer")
        .append("text")
        .attr("class", "text")
        .text(`${d.count}`)
        .attr("x", d => xScale(d.date) + 5)
        .attr("y", d => yScale(d.count) - 10);
    })
  .on("mouseout", function(d) {
      d3.select(this)
        .style("cursor", "none")  
        .transition()
        .duration(duration)
        .selectAll(".text").remove();
    })
  .append("circle")
  .attr("cx", d => xScale(d.date))
  .attr("cy", d => yScale(d.count))
  .attr("r", circleRadius)
  .style('opacity', circleOpacity)
  .on("mouseover", function(d) {
        d3.select(this)
          .transition()
          .duration(duration)
          .attr("r", circleRadiusHover);
      })
    .on("mouseout", function(d) {
        d3.select(this) 
          .transition()
          .duration(duration)
          .attr("r", circleRadius);  
      });


/* Add Axis to SVG */
var extent = d3.extent(data[0].values, d => d.date);
var xAxis = d3.axisBottom(xScale)
            .tickFormat(d3.timeFormat("%a"))
            .ticks(Math.floor(( Date.parse(extent[1]) - Date.parse(extent[0]) ) / 86400000));

var yAxis = d3.axisLeft(yScale).ticks(7);

svg.append("g")
  .attr("class", "x axis")
  .attr("transform", `translate(0, ${height-margin})`)
  .call(xAxis);

svg.append("g")
  .attr("class", "y axis")
  .call(yAxis)
  .append('text')
  .attr("y", 15)
  .attr("transform", "rotate(-90)")
  .attr("fill", "#000")
  .text("Total values");
svg {
  font-family: Sans-Serif, Arial;
}

.line {
  stroke-width: 2;
  fill: none;
}

.axis path {
  stroke: black;
}

.text {
  font-size: 12px;
}

.title-text {
  font-size: 12px;
}
<html>
  <head>
    <script src="https://d3js.org/d3.v4.min.js"></script>
  </head>
  <body>
    <div id="chart"></div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
  </body>
</html>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Guide on utilizing Redux's Provider in React applications

I have been diving into the world of ReduxJS by closely following the documentation provided here. Towards the end of the document, it talks about utilizing the provider object. I have taken the step to wrap my App component in the provider as shown below ...

Interactive Show Map with Autocompletion Feature

I attempted to implement autocompletion for my application and integrate it with Google Maps, but I'm encountering issues. The code for autocompletion is located in a separate JavaScript file called autocomplete.js. Since I already have a Google Map ...

Update background to full screen and include text when hovering over DIV

Currently, I am utilizing Bootstrap and have a layout with 6 columns containing icons/text within. I desire to implement a hover effect where each column triggers a background change in transition for the entire section. In addition, text and button elemen ...

Discovering if a page can be scrolled in Angular

Hey there, I recently started working with Angular and created an app using the angular material stepper. The issue I'm facing is that some of the steps have longer content, causing the page to become scrollable. I am now trying to find a way to deter ...

Failed to add a new entry to the Sharepoint 2013 List

Having trouble saving an item to a SharePoint list using Knockout.js and REST. In my Ajax POST request, I've used ko.toJSON but the entry doesn't show up in the SharePoint list. It's possible that I'm passing the wrong parameter value. ...

Tips for directing attention to a specific row with an input field in JavaScript

I duplicated a table and added an input field for users to search or focus on a specific row. However, there are two issues: When a user enters a row number, the table displays the wrong row - for example, if the user enters 15, the table shows row number ...

UCS-2 in Node.JS: Understanding Big-Endian Byte Order

Currently, I am utilizing Node.JS. In my project, I require support for big-endian UCS-2 buffers, which is not natively offered by Node's buffers that only support little-endian format. How can I achieve this specific requirement? ...

What is a sophisticated method to hide an element from view?

My dilemma involves a dropdown menu and a list of elements that are initially set to hidden using CSS. When an item is selected from the dropdown, it becomes visible. However, I am struggling with finding a way to revert the previously selected element b ...

Refresh the page with cleared cache using window.location.reload

Is there a way to reload a page using JavaScript and still clear the cache, ensuring that the refreshed page shows the latest content from the server? It seems that other browsers are not displaying the most up-to-date versions of the content. Anyone have ...

Is it advisable to avoid using `&apos;` for escaping single quotes?

According to the insights shared in conversations about the popularity of single quotes in HTML and Jquery embedded quote in attribute, the Wikipedia page on HTML highlights that: The use of the single-quote character ('), as a way to quote an attri ...

VueJS component fails to properly sanitize the readme file, as discovered by Marked

Could someone explain why the output from the compiledMarkdown function is not sanitized, resulting in unstyled content from the markdown file? <template> <div style="padding:35px;"> <div v-html="compiledMarkdown" ...

Elements shifting positions based on the size of the window

I am facing an issue with positioning the register form on my website. I want it to be fixed at the bottom-right corner of the window, without reaching the top. Although I managed to achieve this, the problem arises when the screen resolution changes. For ...

Gridsome server-side rendering encounters issues with Auth0 authentication when the window object is not defined

After successfully following the Auth0 Vuejs tutorial with Gridsome during development, I encountered a problem when trying to build using gridsome build. The build failed because window was undefined in a server context. I discovered some issues in the A ...

Maintaining active navigation state in JQuery/JavaScript after clicking a link: tips and tricks

While many resources discuss adding the active class to a nav link using jquery, there is less information on maintaining the active state after the nav link has been clicked. After experimenting with code from various sources, I have attempted to set ses ...

Double submission issue with Angular form (multiple ajax requests)

My controller seems to be causing a form submission issue in AngularJS where the form is being submitted twice via a get request. Upon checking my database and the console network tab, I noticed that two submissions are logged, with the first submission sh ...

The CSS file seems to be ineffective when building Vue in production

In my Vue project, I am using a single file component with a chart module. In order to customize the styles of the chart module's CSS, I created a custom CSS file in the assets folder where I added lines to override certain styles (such as changing th ...

The collapse feature in react-bootstrap is malfunctioning

I've been experimenting with the Collapse feature from react-bootstrap in order to implement a collapsible table row. The goal is to have table rows that expand and collapse when clicked, revealing more information specific to that row. While it see ...

Tips for correcting the `/Date(xxxxxxxxxxxxx)/` formatting issue in asp.net mvc

As a programming novice, I am trying to display data from my database server on the web using a datatable in asp.net mvc. After following a tutorial video on YouTube, I encountered an issue where the date and time columns in my table are displaying as /Dat ...

Infinite loop readiness with JQuery

My current project involves preloading images and seamlessly fading them in once they are fully loaded using JQuery. To achieve this, I attempted to create an invisible image tag where the images would load before setting the source back to the original im ...

What is the best way to retrieve an array of other models from a parent model in Mongoose using queries?

Two Schema exist for user and todo. Each todo is associated with an owner who is a user, and each user has an array of todos. // user.js const TodoSchema = require('./todo').TodoSchema; var UserSchema = mongoose.Schema({ name: { type: String, ...