Search code examples
javascriptd3.jsbar-chartc3.jstimeserieschart

c3js timeseries chart interval colors


I'm starting with the c3.js library and I want to make a time chart (timeseries) and color-code the values based on some intervals. I receive the data from a json after making a query in PHP. I make an array for the dates and an array for the values, and receive them in the javascript function to make the chart like so:

let xData = (data.date);
let yData = (data.value);

xData.unshift('x');
yData.unshift('Values');
var chart7 = c3.generate({
    bindto: '#chart7',
    data: {
        x:'x',
        xFormat: '%Y-%m-%d',
        columns:[
            xData,
            yData
        ],
        type: 'bar'
    },
    axis: {
        x:{
            label:{
                text:'Date',
                position:'outer-center'
            },
            type: 'timeseries',
            tick:{
                format: '%Y-%m-%d'
            }
        },
    },
    point: {
        show: true,
        //r:3.5
    },
    zoom: {
        enabled: true
    },
    legend: {
        show: false
    },
    color: {
        pattern: ['#b7b485', '#0E6A40', '#B73540', '#B73540']
    },
     padding: {
        top: 5,
        right: 5,
        bottom: 5,
        left: 30,
    },
    size:{
        height:240,
    }
});

the json data would be something like this: (I give an example):

 ['x', '2022-05-01', '2022-05-02', '2022-05-03', '2022-05-04', '2022-05-05', '2022-05-06', '2022-05-07', '2022-05-08', '2022-05-09', '2022-05-10', '2022-05-12', '2022-05-13', '2022-05-14', '2022-05-15', '2022-05-16', '2022-05-17', '2022-05-18', '2022-05-19', '2022-05-20', '2022-05-21']
 ['Values', '0.0249', '0.0163', '0.0163', '0.0163', '0.0094', '0.0066', '0.0066', '0.0066', '0.0066', '0.0066', '0.0011', '0.0011', '0.0011', '0.0006', '0.0042', '0.0163', '0.0163', '0.0163', '0.0011', '0.0011']

I want to be able to put them in three colors, green, yellow and red based on an intervals if the value is less than 0.3: green color if the value is greater than 0.3 and less than 0.6: yellow color if the value is greater than 0.6: red color I don't know if this is possible. I thought about creating 6 arrays already in php 3 for dates and 3 for values, but when trying to put them in the graph I was not able to represent them. If I put a single 'x' for a date, it gave me several values and it couldn't be because these values are unique. Does anyone know how I can represent color intervals?


Solution

  • You can use

    color: (_, d) => d.value < 0.3 ? '#0E6A40': d.value < 0.6 ? '#b7b485' : '#B73540'
    

    Here's your example adapted - I used other intervals to fit your example and a more elaborate color function to control the color outside the plot itself (e.g., in the legend) as the the last one (red).

    let xData = ['x', '2022-05-01', '2022-05-02', '2022-05-03', '2022-05-04', '2022-05-05', '2022-05-06', '2022-05-07', '2022-05-08', '2022-05-09', '2022-05-10', '2022-05-12', '2022-05-13', '2022-05-14', '2022-05-15', '2022-05-16', '2022-05-17', '2022-05-18', '2022-05-19', '2022-05-20', '2022-05-21']
    let yData =  ['Values', '0.0249', '0.0163', '0.0163', '0.0163', '0.0094', '0.0066', '0.0066', '0.0066', '0.0066', '0.0066', '0.0011', '0.0011', '0.0011', '0.0006', '0.0042', '0.0163', '0.0163', '0.0163', '0.0011', '0.0011'];
    let _defVal = 1;    
    const chart = c3.generate({
        bindto: '#chart7',
        data: {
            x:'x',
            xFormat: '%Y-%m-%d',
            columns:[
                xData,
                yData
            ],
            type: 'bar',
            color: (_, d) => {const val = d.value ?? _defVal; return val < 0.003 ? '#0E6A40': val < 0.006 ? '#b7b485' : '#B73540'}
        },
        axis: {
            x:{
                label:{
                    text:'Date',
                    position:'outer-center'
                },
                type: 'timeseries',
                tick:{
                    format: '%Y-%m-%d'
                }
            },
        },
        tooltip: {
            format:{
                value: function(val){
                    _defVal = val;
                    return ''+val
                }
            }
        },
        point: {
            show: true,
            //r:3.5
        },
        zoom: {
            enabled: true
        },
        legend: {
            show: false
        },
        padding: {
            top: 5,
            right: 5,
            bottom: 5,
            left: 30,
        },
        size:{
            height:240,
        }
    });
    <script src="https://unpkg.com/[email protected]/dist/d3.min.js"></script>
    <script src="https://unpkg.com/[email protected]/c3.js"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/c3/0.7.20/c3.css" rel="stylesheet">
    
    <div id="chart7"></div>