Scatter chart not being displayed when used with line charts in different panes

1 Answer 63 Views
Charts
Alex
Top achievements
Rank 1
Alex asked on 31 Jul 2024, 10:38 PM

I have the following component. The Events are not being displayed. If I try Event by itself, it does get displayed but when I try it with line chart, it doesn't display anything and the Events don't show up in the ledger as well.

import React, { useEffect, useState } from 'react';
import axios from 'axios';
import {
  Chart,
  ChartTitle,
  ChartLegend,
  ChartCategoryAxis,
  ChartCategoryAxisItem,
  ChartSeries,
  ChartSeriesItem,
  ChartTooltip,
  ChartValueAxis,
  ChartValueAxisItem,
  ChartPane,
  ChartPanes,
} from '@progress/kendo-react-charts';
const TelemetryChart = () => {
  const [temperatureSeries, setTemperatureSeries] = useState([]);
  const [humiditySeries, setHumiditySeries] = useState([]);
  const [statePlotBands, setStatePlotBands] = useState([]);
  const [eventSeries, setEventSeries] = useState([]);
  const [eventsVisible, setEventsVisible] = useState(true);
  const [statesVisible, setStatesVisible] = useState(true);
  const [temperatureVisible, setTemperatureVisible] = useState(true);
  const [humidityVisible, setHumidityVisible] = useState(true);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  useEffect(() => {
    const fetchData = async () => {
      const testStateData = [
        { category: new Date('2024-07-19T18:22:07.339Z'), value: 'Idle' },
        { category: new Date('2024-07-19T19:22:07.339Z'), value: 'Busy' },
        { category: new Date('2024-07-19T20:22:07.339Z'), value: 'Offline' },
        { category: new Date('2024-07-19T21:22:07.339Z'), value: 'Idle' },
        { category: new Date('2024-07-19T22:22:07.339Z'), value: 'Busy' },
        { category: new Date('2024-07-19T23:22:07.339Z'), value: 'Offline' },
        { category: new Date('2024-07-19T23:25:10.188Z'), value: 'Idle' },
      ];
      const testEventData = [
        { category: new Date('2024-07-19T18:22:07.339Z'), value: 1 },
        //{ category: new Date('2024-07-19T19:22:07.339Z'), value: 1 },
        //{ category: new Date('2024-07-19T20:22:07.339Z'), value: 1 },
        { category: new Date('2024-07-19T21:22:07.339Z'), value: 1 },
        //{ category: new Date('2024-07-19T22:22:07.339Z'), value: 1 },
        //{ category: new Date('2024-07-19T23:22:07.339Z'), value: 1 },
        { category: new Date('2024-07-19T23:25:10.188Z'), value: 1 },
      ];
      try {
        console.log('Fetching data...');
        const response = await axios.get('http://localhost:5000/telemetry');
        const fetchedData = response.data;
        console.log('Fetched Data:', fetchedData);
        if (Array.isArray(fetchedData) && fetchedData.length > 0) {
          const temperatureData = fetchedData.map(item => ({
            category: item.creationDateTime ? new Date(item.creationDateTime) : new Date(),
            value: item.temperature !== null && item.temperature !== undefined ? item.temperature : 0
          }));
          const humidityData = fetchedData.map(item => ({
            category: item.creationDateTime ? new Date(item.creationDateTime) : new Date(),
            value: item.humidity !== null && item.humidity !== undefined ? item.humidity : 0
          }));
          console.log('Temperature Data:', temperatureData);
          console.log('Humidity Data:', humidityData);
          setTemperatureSeries(temperatureData);
          setHumiditySeries(humidityData);
          setStatePlotBands(generatePlotBands(testStateData));
          setEventSeries(testEventData);
        } else {
          console.error("Fetched data is not an array or is empty.");
          setTemperatureSeries([]);
          setHumiditySeries([]);
        }
      } catch (error) {
        setError("Error fetching telemetry data");
        console.error("There was an error fetching the telemetry data!", error);
      } finally {
        console.log('Data fetching completed');
        setLoading(false);
      }
    };
    fetchData();
  }, []);
  const generatePlotBands = (stateData) => {
    const stateColors = {
      Idle: 'rgba(76, 205, 131)', // Green
      Busy: 'rgba(253, 185, 19)', // Yellow
      Offline: 'rgba(219, 61, 61)' // Red
    };
    return stateData.map((item, index) => {
      const nextItem = stateData[index + 1];
      if (nextItem) {
        return {
          from: item.category,
          to: nextItem.category,
          color: stateColors[item.value],
        };
      }
      return null;
    }).filter(item => item !== null);
  };
  const handleLegendItemClick = (e) => {
    if (e.series.name === "Temperature (°C)") {
      setTemperatureVisible(!temperatureVisible);
    } else if (e.series.name === "Humidity (%)") {
      setHumidityVisible(!humidityVisible);
    } else if (e.series.name === "State") {
      setStatesVisible(!statesVisible);
    } else if (e.series.name === "Events") {
      setEventsVisible(!eventsVisible);
    }
  };
  if (loading) {
    console.log('Loading...');
    return <div>Loading...</div>;
  }
  if (error) {
    console.log('Error:', error);
    return <div>{error}</div>;
  }
  console.log('Rendering Chart with:', { temperatureSeries, humiditySeries });
  if (!Array.isArray(temperatureSeries) || !Array.isArray(humiditySeries)) {
    console.error("Temperature or Humidity data is not an array");
    return <div>Error: Invalid data structure</div>;
  }
  console.log('Temperature Series:', temperatureSeries);
  console.log('Humidity Series:', humiditySeries);
  console.log('Event Series:', eventSeries);
  return (
    <div style={{ height: '1000px', width: '100%' }}>
      <Chart          
        zoomable={{
          mousewheel: {
            //allow zoom only for X axis
            lock: 'y',
            //rate of zoom
            rate: 0.1,
          },
          //disable selection
          selection: false,
        }}
        style={{ height: '100%' }}
        onLegendItemClick={handleLegendItemClick}
      >
        <ChartTitle text="Telemetry Data" />
        <ChartLegend position="left" />
        <ChartPanes>                  
          <ChartPane name="humidityPane" height="25%" />
          <ChartPane name="temperaturePane" height="25%" />  
          <ChartPane name="eventsPane" height="24%" />
          <ChartPane name="statePane" height="16%" />
        </ChartPanes>
        <ChartCategoryAxis>
          <ChartCategoryAxisItem
            title={{ text: 'Time' }}
            baseUnit="minutes"
            labels={{
              dateFormats: { minutes: "yyyy/dd/mm HH:mm:ss" },
              rotation: "45",
              step: 10,
            }}
            plotBands={statesVisible ? statePlotBands : []}
            pane="statePane"
          />
          <ChartCategoryAxisItem
            baseUnit="minutes"
            labels={{
              dateFormats: { minutes: "yyyy/dd/mm HH:mm:ss" },
              visible: false,
              step: 10,
            }}
            visible={false}
            pane="eventsPane"
          />          
          <ChartCategoryAxisItem
            baseUnit="minutes"
            labels={{
              dateFormats: { minutes: "yyyy/dd/mm HH:mm:ss" },
              visible: false,
              step: 10,
            }}
            visible={false}
            pane="temperaturePane"
          />
          <ChartCategoryAxisItem
            baseUnit="minutes"
            labels={{
              dateFormats: { minutes: "yyyy/dd/mm HH:mm:ss" },
              visible: false,
              step: 10,
            }}
            visible={false}
            pane="humidityPane"
          />
        </ChartCategoryAxis>
        <ChartValueAxis>
          <ChartValueAxisItem name="humidityAxis" title={{ text: 'Humidity (%)' }} min={0} max={1} pane="humidityPane" />
          <ChartValueAxisItem name="temperatureAxis" title={{ text: 'Temperature (°C)' }} min={0} max={40} pane="temperaturePane" />
          <ChartValueAxisItem name="eventsAxis" title={{ text: 'Events' }} min={0} max={2} pane="eventsPane" />
          <ChartValueAxisItem name="stateAxis" title={{ text: 'State' }} visible={false} pane="statePane"
            majorGridLines={{ visible: false }}
            minorGridLines={{ visible: false }} />
        </ChartValueAxis>
        <ChartSeries>
          <ChartSeriesItem
            type="line"
            data={humiditySeries}
            name="Humidity (%)"
            field="value"
            categoryField="category"
            axis="humidityAxis"
            markers={{ visible: false }}
            pane="humidityPane"
            visible={humidityVisible}
          />
          <ChartSeriesItem
            type="line"
            data={temperatureSeries}
            name="Temperature (°C)"
            field="value"
            categoryField="category"
            axis="temperatureAxis"
            markers={{ visible: false }}
            pane="temperaturePane"
            visible={temperatureVisible}
          />          
          <ChartSeriesItem
            type="scatter"
            data={eventSeries}
            name="Events"
            xField="category"
            yField="value"
            markers={{
              size: 20,
              background: "blue",
              border: { color: "blue", width: 2 }
            }}
            pane="eventsPane"
            visible={eventsVisible}
          />
          <ChartSeriesItem
            type="line"
            data={[]}
            name="State"
            color="rgba(40, 67, 135)"
            visible={statesVisible}
          />
        </ChartSeries>
        <ChartTooltip />
      </Chart>
    </div>
  );
};
export default TelemetryChart;

1 Answer, 1 is accepted

Sort by
0
Accepted
Vessy
Telerik team
answered on 02 Aug 2024, 12:14 PM

Hello, Alex,

The Scatter series is numerical, while the Line one is categorical, therefore they cannot be used in one and the same chart (they expect different rendering). Using ScatterLine series instead of Line ones will allow you to render both series of the chart:

Regards,
Vessy
Progress Telerik

Do you have a stake in the designеr-developer collaboration process? If so, take our survey to share your perspective and become part of this global research. You’ll be among the first to know once the results are out.
-> Start The State of Designer-Developer Collaboration Survey 2024

Tags
Charts
Asked by
Alex
Top achievements
Rank 1
Answers by
Vessy
Telerik team
Share this question
or