# Is there a way to put x-axis and y-axis labels on a Time-based chart?

**URL:** <https://community.forestadmin.com/t/is-there-a-way-to-put-x-axis-and-y-axis-labels-on-a-time-based-chart/3920>\
**Category:** Feature suggestions\
**Tags:** howtos\
**Created:** [December 17, 2021, 1:01am UTC](https://community.forestadmin.com/t/is-there-a-way-to-put-x-axis-and-y-axis-labels-on-a-time-based-chart/3920 "2021-12-17T01:01:36Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![muz](https://avatars.discourse-cdn.com/v4/letter/m/bc8723/32.png) [@muz](https://community.forestadmin.com/u/muz)\
**Post date:** [December 17, 2021, 1:01am UTC](https://community.forestadmin.com/t/is-there-a-way-to-put-x-axis-and-y-axis-labels-on-a-time-based-chart/3920/1 "2021-12-17T01:01:36Z")

</div>

I need to put x and y-axis labels on Time-based charts. There is no way to do so when using the ‘Simple’ or ‘SQL’ config options.

This is for a Ruby on Rails 6 setup.

This is the first time trying to create charts, and I would really appreciate any suggestions.

Thanks!

---

<div class="post-metadata">

**Author:** ![anon39848301](https://avatars.discourse-cdn.com/v4/letter/a/b9e5f3/32.png) [@anon39848301](https://community.forestadmin.com/u/anon39848301)\
**Post date:** [December 17, 2021, 8:52am UTC](https://community.forestadmin.com/t/is-there-a-way-to-put-x-axis-and-y-axis-labels-on-a-time-based-chart/3920/2 "2021-12-17T08:52:08Z")

</div>

Hey @muz, and welcome back to our community 👋

This is indeed not supported out of the box, so I’m pushing this as a suggestion on our product board.

The only workaround I can think of would be to create a Smart Chart, which may be a bit code heavy but would allow more chart customization in a long term.

Using an [API-based chart](https://docs.forestadmin.com/documentation/reference-guide/charts/create-an-api-based-chart#time-based-smart-chart) wouldn’t allow to add label on axis, but let you have more control on the data if required.

Let me know if that helps

---

<div class="post-metadata">

**Author:** ![muz](https://avatars.discourse-cdn.com/v4/letter/m/bc8723/32.png) [@muz](https://community.forestadmin.com/u/muz)\
**Post date:** [December 17, 2021, 6:18pm UTC](https://community.forestadmin.com/t/is-there-a-way-to-put-x-axis-and-y-axis-labels-on-a-time-based-chart/3920/3 "2021-12-17T18:18:07Z")

</div>

Thanks @anon39848301, I appreciate it.

I also looked into using Smart Chart to do that, but unfortunately there isn’t an example implementation of a Time-based chart. So I am now looking trying to quickly learn D3.js and use the other examples as a guide to create the time-based smart chart.

I also need to use data from our transaction model, and I am guessing I need to create a forest route, something like:  
get ‘/stats/transactions-per-day’ =\> ‘charts#transactions\_per\_day’

Am I on the right path?

Edit:

I think there is a typo in the Time-based API-based Chart Rails example code (charts\_controller.rb):

> else  
> ++entry[:values][:value]  
> end

should be:

> else  
> entry[:values][:value] += 1  
> end

I think that is why the example chart has a flat line?

Thanks for all your help!

---

<div class="post-metadata">

**Author:** ![muz](https://avatars.discourse-cdn.com/v4/letter/m/bc8723/32.png) [@muz](https://community.forestadmin.com/u/muz)\
**Post date:** [December 20, 2021, 5:24am UTC](https://community.forestadmin.com/t/is-there-a-way-to-put-x-axis-and-y-axis-labels-on-a-time-based-chart/3920/4 "2021-12-20T05:24:45Z")

</div>

Hi @anon39848301,

So I tried to create a time-based (line chart) smart chart, but I wasn’t able to get it to work.

I used the example bar chart as a template, and here is what I have so far:

```javascript
import Component from '@glimmer/component';
import { loadExternalStyle, loadExternalJavascript } from 'client/utils/smart-view-utils';
import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking';

export default class extends Component {
   constructor(...args) {
    super(...args);

    this.loadPlugin();
  }

  @tracked chart;
  @tracked loaded = false;

  async loadPlugin() {
    await loadExternalJavascript('https://d3js.org/d3.v6.min.js');

    this.loaded = true;
    this.renderChart()
  }

  async fetchData() {
    const response = await this.lianaServerFetch.fetch('/transactions');
    const data = await response.json();
    return data;
  }

  @action
  async renderChart() {
    if (!this.loaded) { return; }

    const color = 'steelblue';
    
    // Don't comment the lines below if you want to fetch data from your Forest server
    // const usersData = await this.fetchData();
    const data = await this.fetchData();
    // const data = Object.assign(usersData.sort((a, b) => d3.descending(a.points, b.points)), {format: "%", y: "↑ Frequency"})
    
// const data = 
// [{label: "15/11/21", value: 2},
// {label: "05/12/21", value: 1},
// {label: "14/12/21", value: 1},
// {label: "13/12/21", value: 1},
// {label: "12/12/21", value: 3}];

    const height = 500;
    const width = 800;
    const margin = ({top: 30, right: 0, bottom: 30, left: 40})

    const x = d3.scaleTime()
      .domain(d3.range(data.length))
      .range([margin.left, width - margin.right])
      .padding(0.1)
    const y = d3.scaleLinear()
      .domain([0, d3.max(data, d => d.value)]).nice()
      .range([height - margin.bottom, margin.top])
      
    const valueline = d3
      .line()
      .x((d) => { return x(d.label); })
      .y((d) => { return y(d.value); })
      .curve(d3.curveCardinal);

    const xAxis = g => g
    .attr("transform", `translate(0,${height - margin.bottom})`)
    .call(d3.axisBottom(x).tickFormat(i => data[i].label).tickSizeOuter(0))

    const yAxis = g => g
    .attr("transform", `translate(${margin.left},0)`)
    .call(d3.axisLeft(y).ticks(null, data.format))
    .call(g => g.select(".domain").remove())
    .call(g => g.append("text")
        .attr("x", -margin.left)
        .attr("y", 10)
        .attr("fill", "currentColor")
        .attr("text-anchor", "start")
        .text("↑ Transactions")
        .attr("dy", "1em"))

    const svg = d3.create("svg")
        .attr("viewBox", [0, 0, width, height]);

    svg.append("g")
      .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
      .attr("fill", color);
      // .data(data);
        
            
    const linePath = svg
        .append("path")
        .data(data)
        .attr("class", "line")
        .attr("d", valueline)
    
    const pathLength = linePath.node().getTotalLength();
    
    linePath
        .attr("stroke-dasharray", pathLength)
        .attr("stroke-dashoffset", pathLength)
        .attr("stroke-width", 3)
        .attr("stroke-width", 0)
        .attr("stroke-dashoffset", 0);
    

    svg.append("g").call(xAxis);

    svg.append("g").call(yAxis);

    this.chart = svg.node();
  }
}

```

Any ideas as to what I am doing wrong?

Thanks again!

Edit:  
I found this tutorial very helpful:  
“D3.js Line Chart Tutorial”

> **[D3.js Line Chart Tutorial](https://sharkcoder.com/data-visualization/d3-line-chart)**
>
> In this tutorial, I’ll explain how to create an animated line chart with tooltips using the D3.js library (v.6).

---

<div class="post-metadata">

**Author:** ![anon39848301](https://avatars.discourse-cdn.com/v4/letter/a/b9e5f3/32.png) [@anon39848301](https://community.forestadmin.com/u/anon39848301)\
**Post date:** [December 20, 2021, 1:27pm UTC](https://community.forestadmin.com/t/is-there-a-way-to-put-x-axis-and-y-axis-labels-on-a-time-based-chart/3920/5 "2021-12-20T13:27:14Z")

</div>

Hey @muz

Sorry for the delayed response.  
After your edit, did you manage to resolve your issue ?

---

<div class="post-metadata">

**Author:** ![muz](https://avatars.discourse-cdn.com/v4/letter/m/bc8723/32.png) [@muz](https://community.forestadmin.com/u/muz)\
**Post date:** [December 20, 2021, 1:32pm UTC](https://community.forestadmin.com/t/is-there-a-way-to-put-x-axis-and-y-axis-labels-on-a-time-based-chart/3920/6 "2021-12-20T13:32:36Z")

</div>

Hi @anon39848301

Unfortunately I am still not able to get it to work. Any ideas?

---

<div class="post-metadata">

**Author:** ![anon39848301](https://avatars.discourse-cdn.com/v4/letter/a/b9e5f3/32.png) [@anon39848301](https://community.forestadmin.com/u/anon39848301)\
**Post date:** [December 20, 2021, 1:36pm UTC](https://community.forestadmin.com/t/is-there-a-way-to-put-x-axis-and-y-axis-labels-on-a-time-based-chart/3920/7 "2021-12-20T13:36:52Z")

</div>

You should have an error in your browser console indicating the issue. Would you mind sharing it here so I can investigate on my end ?

---

<div class="post-metadata">

**Author:** ![muz](https://avatars.discourse-cdn.com/v4/letter/m/bc8723/32.png) [@muz](https://community.forestadmin.com/u/muz)\
**Post date:** [December 20, 2021, 2:02pm UTC](https://community.forestadmin.com/t/is-there-a-way-to-put-x-axis-and-y-axis-labels-on-a-time-based-chart/3920/8 "2021-12-20T14:02:27Z")

</div>

You are right, there is an error and I am trying to find the relevant error, and will post as soon as I find it.

Thanks.

---

<div class="post-metadata">

**Author:** ![muz](https://avatars.discourse-cdn.com/v4/letter/m/bc8723/32.png) [@muz](https://community.forestadmin.com/u/muz)\
**Post date:** [December 20, 2021, 2:09pm UTC](https://community.forestadmin.com/t/is-there-a-way-to-put-x-axis-and-y-axis-labels-on-a-time-based-chart/3920/9 "2021-12-20T14:09:47Z")

</div>

@anon39848301  
Is it possible to do a screen share? I have a couple of questions that could help me clarify this?

---

<div class="post-metadata">

**Author:** ![anon39848301](https://avatars.discourse-cdn.com/v4/letter/a/b9e5f3/32.png) [@anon39848301](https://community.forestadmin.com/u/anon39848301)\
**Post date:** [December 20, 2021, 2:13pm UTC](https://community.forestadmin.com/t/is-there-a-way-to-put-x-axis-and-y-axis-labels-on-a-time-based-chart/3920/10 "2021-12-20T14:13:02Z")

</div>

@muz,

Our community support is mainly done here in order to centralize the knowledge around the issues/potentials fixes around our product. Sorry about that.

I’m currently trying to take the code your provided to see if I’m able to have a clearer idea about that.  
If you find the relevant error (Which should be the last one once you clicked on “Run”), share it here so I can have a look 🙏

---

<div class="post-metadata">

**Author:** ![muz](https://avatars.discourse-cdn.com/v4/letter/m/bc8723/32.png) [@muz](https://community.forestadmin.com/u/muz)\
**Post date:** [December 20, 2021, 2:17pm UTC](https://community.forestadmin.com/t/is-there-a-way-to-put-x-axis-and-y-axis-labels-on-a-time-based-chart/3920/11 "2021-12-20T14:17:26Z")

</div>

Totally understand, and would have posted the solution here in any case.

---

<div class="post-metadata">

**Author:** ![muz](https://avatars.discourse-cdn.com/v4/letter/m/bc8723/32.png) [@muz](https://community.forestadmin.com/u/muz)\
**Post date:** [December 20, 2021, 2:27pm UTC](https://community.forestadmin.com/t/is-there-a-way-to-put-x-axis-and-y-axis-labels-on-a-time-based-chart/3920/12 "2021-12-20T14:27:29Z")

</div>

"Uncaught (in promise) " error here:

\_createClass(\_class2, [{  
key: “loadPlugin”,  
value: async function loadPlugin() {  
await (0, \_smartViewUtils.loadExternalJavascript)(‘[https://d3js.org/d3.v6.min.js](https://d3js.org/d3.v6.min.js)’);  
this.loaded = true;  
this.renderChart();  
}

---

<div class="post-metadata">

**Author:** ![anon39848301](https://avatars.discourse-cdn.com/v4/letter/a/b9e5f3/32.png) [@anon39848301](https://community.forestadmin.com/u/anon39848301)\
**Post date:** [December 20, 2021, 2:30pm UTC](https://community.forestadmin.com/t/is-there-a-way-to-put-x-axis-and-y-axis-labels-on-a-time-based-chart/3920/13 "2021-12-20T14:30:28Z")

</div>

It looks like you are missing a service import (Most likely an issue in our documentation as well, I’ll check)

```javascript
@service lianaServerFetch

```

Since I don’t have access to your `transactions` data I can’t really check, but at least that’s a good start 🙂

---

<div class="post-metadata">

**Author:** ![muz](https://avatars.discourse-cdn.com/v4/letter/m/bc8723/32.png) [@muz](https://community.forestadmin.com/u/muz)\
**Post date:** [December 20, 2021, 2:40pm UTC](https://community.forestadmin.com/t/is-there-a-way-to-put-x-axis-and-y-axis-labels-on-a-time-based-chart/3920/14 "2021-12-20T14:40:52Z")

</div>

I added the service import and still seeing the uncaught (in promise) error at the same spot.

---

<div class="post-metadata">

**Author:** ![Arnaud\_Moncel](https://dub1.discourse-cdn.com/flex013/user_avatar/community.forestadmin.com/arnaud_moncel/32/24_2.png) [@Arnaud\_Moncel](https://community.forestadmin.com/u/Arnaud_Moncel)\
**Post date:** [December 20, 2021, 5:08pm UTC](https://community.forestadmin.com/t/is-there-a-way-to-put-x-axis-and-y-axis-labels-on-a-time-based-chart/3920/15 "2021-12-20T17:08:19Z")

</div>

Hi @muz 👋 You can take exemple of this code to achieve your goal

```javascript
import Component from '@glimmer/component';
import { loadExternalStyle, loadExternalJavascript } from 'client/utils/smart-view-utils';
import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking';
import { inject as service } from '@ember/service';

export default class extends Component {
  @service lianaServerFetch;

   constructor(...args) {
    super(...args);

    this.loadPlugin();
  }

  @tracked chart;
  @tracked loaded = false;

  async loadPlugin() {
    await loadExternalJavascript('https://d3js.org/d3.v6.min.js');

    this.loaded = true;
    this.renderChart()
  }

  async fetchData() {
    const response = await this.lianaServerFetch.fetch('/forest/transactions');
    const data = await response.json();
    return data;
  }

  @action
  async renderChart() {
    if (!this.loaded) { return; }

    const color = 'steelblue';
    
    const parseDate = d3.timeParse("%m/%d/%Y");
    const formatDate = d3.timeFormat("%b %d");

    // const data = await this.fetchData();

    const data = [
      {label: parseDate("11/15/2021"), value: 2},
      {label: parseDate("12/05/2021"), value: 1},
      {label: parseDate("12/12/2021"), value: 3},
      {label: parseDate("12/13/2021"), value: 1},
      {label: parseDate("12/14/2021"), value: 1},
    ];
   
    const height = 500;
    const width = 800;
    const margin = ({top: 30, right: 0, bottom: 30, left: 40})

    const x = d3.scaleTime()
      .domain([d3.min(data, d => d.label), d3.max(data, d => d.label)])
      .range([margin.left, width - margin.right])
    const y = d3.scaleLinear()
      .domain([0, d3.max(data, d => d.value)]).nice()
      .range([height - margin.bottom, margin.top])

    const valueline = d3
      .line()
      .x((d) => { return x(d.label); })
      .y((d) => { return y(d.value); })
      .curve(d3.curveCardinal);

    const svg = d3
      .create("svg")
      .attr("width", width + margin.left + margin.right)
      .attr("height", height + margin.top + margin.bottom)
    
    const linePath = svg
      .append("path")
      .data([data])
      .attr("class", "line")
      .attr("d", valueline)
    
    const pathLength = linePath.node().getTotalLength();
    
    linePath
      .attr("stroke-dasharray", pathLength)
      .attr("stroke-dashoffset", pathLength)
      .attr("stroke-width", 3)
      .attr("stroke-width", 0)
      .attr("stroke-dashoffset", 0);
    
    const xAxis = g => g
    .attr("transform", `translate(0,${height - margin.bottom})`)
    .call(d3.axisBottom(x).tickFormat(i => formatDate(i)).tickSizeOuter(0));

    const yAxis = g => g
    .attr("transform", `translate(${margin.left},0)`)
    .call(d3.axisLeft(y).ticks(null, data.format))
    .call(g => g.select(".domain").remove())
    .call(g => g.append("text")
    .attr("x", -margin.left)
    .attr("y", 10)
    .attr("fill", "currentColor")
    .attr("text-anchor", "start")
    .text("↑ Transactions")
    .attr("dy", "1em"))

    svg.append("g").call(xAxis);

    svg.append("g").call(yAxis);

    this.chart = svg.node();
  }
}

```

---

<div class="post-metadata">

**Author:** ![muz](https://avatars.discourse-cdn.com/v4/letter/m/bc8723/32.png) [@muz](https://community.forestadmin.com/u/muz)\
**Post date:** [December 20, 2021, 5:32pm UTC](https://community.forestadmin.com/t/is-there-a-way-to-put-x-axis-and-y-axis-labels-on-a-time-based-chart/3920/16 "2021-12-20T17:32:23Z")

</div>

Hi @Arnaud_Moncel,

I will give that a try and will let you know how it goes.

Thanks!

---

<div class="post-metadata">

**Author:** ![muz](https://avatars.discourse-cdn.com/v4/letter/m/bc8723/32.png) [@muz](https://community.forestadmin.com/u/muz)\
**Post date:** [December 26, 2021, 8:36pm UTC](https://community.forestadmin.com/t/is-there-a-way-to-put-x-axis-and-y-axis-labels-on-a-time-based-chart/3920/17 "2021-12-26T20:36:08Z")

</div>

Hi @Arnaud_Moncel

I apologize for the delayed response.

The code above was missing the import component line at the top:

```javascript
import Component from '@glimmer/component';

```

and after adding that it produced a chart, but not a decent one. It is a good starting point though, and I will keep working on it until I get a good one, and will post the final result here.

Thank you for all your help, I really appreciate it!
