-1

Does anyone know of a chart layout that functions like a schedule/timeline?

I currently have a chart that shows the on/off status of 3 valves over time. It's a stacked line/area chart, it's works ok, but it's not the easiest to follow.

See linked screenshot of what I'm looking to achieve: Chart actual vs desired (Top is current chart, bottom is what I want to achieve).

Is this possible with apache echarts?

fnm-luke
  • 21
  • 1
  • Youre looking for something called a Gant Chart https://jscharting.com/examples/chart-types/gantt/#:~:text=JavaScript%20Gantt%20charts%20offer%20project,support%20HTML%20and%20CSS%20formatting. – Yesthe Cia Aug 10 '22 at 08:22
  • The example of the Profile chart, under Custom Chart, is a traditional Timeline chart (not Gantt), so it is basically exactly what you are looking for. But since it is a Custom chart, there would be additional work to do to make it behave the way you want it to. Check out this example: https://echarts.apache.org/examples/en/editor.html?c=custom-profile – pthomson Aug 12 '22 at 23:00

1 Answers1

1

Thanks to @pthomson for pointing me in the right direction.

Here is what I've come up with: Codepen chart example

I'm still having some issues with the min/max values for the xAxis. The min/max seems to be calculated on values in index 1, which is the end timestamp of each schedule piece, so not ideal.

var dom = document.getElementById('chart-container');
var myChart = echarts.init(dom, null, {
  renderer: 'canvas',
  useDirtyRect: false
});
var app = {};

var option;


const valveColors = [
    "#f59527",
    "#00e200",
    "#2da8f3",
]

var data = [
  {
      "name": "Valve 1",
      "value": [
          1655647200000,
          1657980000000,
          0
      ]
  },
  {
      "name": "Valve 3",
      "value": [
          1657980000000,
          1659448800000,
          2
      ]
  },
  {
      "name": "Valve 1",
      "value": [
          1659448800000,
          1660526144467,
          0
      ]
  },
  {
      "name": "Valve 2",
      "value": [
          1655647200000,
          1660526144467,
          1
      ]
  }
];

option = {
            xAxis: {
                type: "time",
        //Min is getting values from index 1, not sure why
                min: range => range.min - (7 * 24 * 60 * 60 * 1000), //Subtract 7 days
            },
            yAxis: {
                type: "category",
                data: [ "Valve 3", "Valve 2", "Valve 1" ]
            },
            series: [
                {
                    type: "custom",
                    renderItem: (params, api) => {
                        var catIndex = api.value(2);
                        var timeSpan = [api.value(0), api.value(1)];
                        var start = api.coord([timeSpan[0], 2 - catIndex]);
                        var end = api.coord([timeSpan[1], 2 -catIndex]);
                        var size = api.size([0,1]);
                        var height = size[1] * 0.6;
                        var rect = echarts.graphic.clipRectByRect(
                            { x: start[0], y: start[1] - height / 2, width: end[0] - start[0], height: height},
                            { x: params.coordSys.x, y: params.coordSys.y, width: params.coordSys.width, height: params.coordSys.height}
                        );
                        return (
                            rect && {
                                type: "rect",
                                transition: ["shape"],
                                shape: rect,
                                style: {
                                    fill: valveColors[catIndex],
                                },
                            }
                        );
                    },
                    encode: {
                        x: [0,1],
                        y: 0,
                    },
                    data: data,
                }
            ],
            tooltip: {
                show: true,
                trigger: "item",
                formatter: params => {
                    return `${params.data.name}<br/> ${params.data.value[0]} - ${params.data.value[1]}` //Unix timestamps should be converted to readable dates
                }
            },
            dataZoom: [
                {
                    type: "slider",
                    filterMode: "none"
                },
            ],
        }

if (option && typeof option === 'object') {
  myChart.setOption(option);
}

window.addEventListener('resize', myChart.resize);
fnm-luke
  • 21
  • 1