Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to show c3.js No data but with legend for empty column?

I have managed to display "No data available message" on my chart. But trouble is that I want to show legend with data name even when there is no data.

If the values are null, the "No data" message will disappear. If there is no data, message will appear but legend will disappear.

var chart = c3.generate({
  data: {
    bindto: "#chart",
    x: 'x',
    columns: [
      ['x', '2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04', '2013-01-05', '2013-01-06'],
      //Uncomment to see the legend ['data1', null, null, null, null, null, null] 
      ['data1'] //Comment out to see the legend
    ],
    empty: {
      label: {
        text: "No Data Available"
      }
    }
  },
  axis: {
    x: {
      type: 'timeseries',
      tick: {
        format: '%Y-%m-%d'
      }
    }
  }
});
chart.load({});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.js"></script>
<div id='chart'></div>
like image 230
Radovan Skendzic Avatar asked Dec 08 '17 10:12

Radovan Skendzic


1 Answers

It looks like c3 do not have the behaviour that you want. I can suggest you write the function and in this function, you can check if you have data you create chart normal way:

c3.generate(config).load({})

But if you do not have the data you can fill the data with null values and append an element with text No data available to the root chart node. You can style this text and it will look like default c3 message for empty data:

function createC3ChartWithConfig(config) {
  if (config.data.columns[1].length < 2) { // if data not exist
    const lengthOfTicks = config.data.columns[0].length - 1;

    for (var i = 0; i < lengthOfTicks; i++) {
      config.data.columns[1].push(null)
    }

    var chart = c3.generate(config);

    chart.load({})

    var element = document.createElement('div');

    element.setAttribute('class', 'message');
    element.innerText = 'No data available';
    chart.element.appendChild(element)
  } else {
    c3.generate(config).load({})
  }
}

Check the demos below. First for config without data:

{
  data: {
    bindto: "#chart",
    x: 'x',
    columns: [
      ['x', '2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04', '2013-01-05', '2013-01-06'],
      ['data1'] // data is empty
    ],
  },
  axis: {
    x: {
      type: 'timeseries',
      tick: {
        format: '%Y-%m-%d'
      }
    }
  }
}

var config = {
  data: {
    bindto: "#chart",
    x: 'x',
    columns: [
      ['x', '2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04', '2013-01-05', '2013-01-06'],
      //['data1', 6, 4, 5, 5, 5, 5] 
      ['data1'] //Comment out to see the legend
    ],
  },
  axis: {
    x: {
      type: 'timeseries',
      tick: {
        format: '%Y-%m-%d'
      }
    }
  }
}

function createC3ChartWithConfig(config) {
  if (config.data.columns[1].length < 2) { // if data not exist
    const lengthOfTicks = config.data.columns[0].length - 1;

    for (var i = 0; i < lengthOfTicks; i++) {
      config.data.columns[1].push(null)
    }

    var chart = c3.generate(config);

    chart.load({})

    var element = document.createElement('div');

    element.setAttribute('class', 'message');
    element.innerText = 'No data available';
    chart.element.appendChild(element)
  } else {
  	c3.generate(config).load({})
  }
}

createC3ChartWithConfig(config);
.message {
  position: absolute;
  top: 120px;
  width: 100%;
  font-size: 2em;
  font-family: sans-serif;
  color: #808080;
  text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id='chart'></div>

And second for config with data:

{
  data: {
    bindto: "#chart",
    x: 'x',
    columns: [
      ['x', '2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04', '2013-01-05', '2013-01-06'],
      ['data1', 6, 4, 5, 4, 5, 2] 
    ],
  },
  axis: {
    x: {
      type: 'timeseries',
      tick: {
        format: '%Y-%m-%d'
      }
    }
  }
}

var config = {
  data: {
    bindto: "#chart",
    x: 'x',
    columns: [
      ['x', '2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04', '2013-01-05', '2013-01-06'],
      ['data1', 6, 4, 5, 4, 5, 2] 
    ],
  },
  axis: {
    x: {
      type: 'timeseries',
      tick: {
        format: '%Y-%m-%d'
      }
    }
  }
}

function createC3ChartWithConfig(config) {
  if (config.data.columns[1].length < 2) { // if data not exist
    const lengthOfTicks = config.data.columns[0].length - 1;

    for (var i = 0; i < lengthOfTicks; i++) {
      config.data.columns[1].push(null)
    }

    var chart = c3.generate(config);

    chart.load({})

    var element = document.createElement('div');

    element.setAttribute('class', 'message');
    element.innerText = 'No data available';
    chart.element.appendChild(element)
  } else {
  	c3.generate(config).load({})
  }
}

createC3ChartWithConfig(config);
.message {
  position: absolute;
  top: 120px;
  width: 100%;
  font-size: 2em;
  font-family: sans-serif;
  color: #808080;
  text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id='chart'></div>
like image 61
Mikhail Shabrikov Avatar answered Oct 25 '22 01:10

Mikhail Shabrikov