Telerik Forums
KendoReact Forum
1 answer
94 views

hi there

im building a gantt  chart components right now, and wondering if there is a way to reorder  the task it self to up/down?
i noticed there is an API for RowContextMenu which return a level in there which i believed is the one responsible in ordering the task
however there is no such function or api to exactly do the reordering

thank you

Yanko
Telerik team
 answered on 08 Aug 2024
1 answer
211 views

I've just upgraded my kendo-react-pdf from 8.0 to 8.1.1

"@progress/kendo-react-pdf": "8.1.1",
"@progress/kendo-theme-default": "^5.8.1",

but now the CSS isn't applied anymore. I'm using the CSS library 'Emotion' and this worked fine previously. For example I had a styled component in my PDF template with styling:

const Container = styled.div({
position: 'absolute',
top: '0px',
bottom: '0px',
left: '0px',
right: '0px',
display: 'flex',
flexDirection: 'column',
});

 

However, now the CSS only works if I add it inline:

<div
style={{
position: 'absolute',
top: '0px',
bottom: '0px',
left: '0px',
right: '0px',
display: 'flex',
flexDirection: 'column',
}}
>

 

I can change all the styling, but I'd prefer to keep my styled components as that's what we're using for the rest of the app as well.

Thanks!

Vessy
Telerik team
 answered on 07 Aug 2024
2 answers
134 views

I understand that KendoReact is 508 compliant by certain standards, but my agency tests to a different standard.

I'm getting reports that the grid is not associated cells with headers. I've researched different ways to get around this and the solution I've come up with is to add ID to the TH tags and then using the HEADERS attribute to the data cells with the ID in the associated header. Example below:

<table>
  <tr>
    <th id="colOneHeader">Col One</th>
    <th id="colTwoHeader">Col Two</th>
  </tr>
  <tr>
    <td headers="colOneHeader">Col One Data</td>
    <td headers="colTwoHeader">Col Two Data</td>
  </tr>
</table>

My issue is adding the ID attribute to the TH tags in the grid. I've attempted the following:

const HeaderCustomCell = (props: any) => {

  return (
    <HeaderThElement scope="col" columnId={ props.thProps?.columnId || "" } id={ props.thProps.title + "_Header" } { ...props.thProps }>
      { props.children }
    </HeaderThElement>
  );
};

<Grid  cells={{ headerCell: HeaderCustomCell }} ...

The SCOPE and ID attributes are ignored and do not show up in the TH tags in the source code. I also tried just returning a basic <th> node from the HeaderCustomCell method and it did not work.

Is there a different method to add custom attributes to the HeaderThElement?

Thanks in advance

Yanko
Telerik team
 answered on 07 Aug 2024
1 answer
504 views

Hi!

I tried to upgrade to version 8.1.1. The main reason was to solve the problem with pdfjs vulnerability. But after the upgrade it gives me an error:

[ERROR] Could not resolve "@progress/kendo-pdfviewer-common"

 node_modules/@progress/kendo-react-pdf-viewer/PDFViewer.mjs:22:287:
 22 │ ...Nt, download as Tt, print as Mt, DEFAULT_ZOOM_LEVEL as Pt } from "@progress/kendo-pdfviewer-common";
 â•µ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If I installed/Returned kendo-pdfviewer-common, in package-lock.json I see the requirementon pdfjs-dist in version 3.11.174 and the builder warns of a vulnerability problem with pdfjs.

I don't know what I am doing wrong or what is the correct way to avoid the vulnerability with pdf.js. I tried clean install, reset npm cache, nothing helped.

 

And sorry. The second question I noticed while testing. Build scss (@progress/kendo-theme-bootstrap/scss/all.scss) which took a few seconds on version 5.12 now takes about 180 seconds. I use Esbuild as a builder. I know the themes have been changed, but what could have caused it to take so long?

 

Well thank you.

Yanko
Telerik team
 answered on 06 Aug 2024
1 answer
116 views

I have a Tabstrip with 3 tabs, and those tabs have content that has a dynamic size. Currently when the user selects the different tabs, the tab control will change in size because it is set its width and height to 100% (the size is not known at design time)

I would like to set the size of the tabstrip to the largest size of the dynamic content so that the tab control will remain the same size when the user selects the different tabs. 

How would I achieve that?

Yanko
Telerik team
 answered on 05 Aug 2024
1 answer
127 views

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;
Vessy
Telerik team
 answered on 02 Aug 2024
1 answer
130 views

Hi there! We are using GridColumnMenuCheckboxFilter to filter a numeric column for a field called "fruits" in our data grid. The filtering works fine, but we would like to see the checkbox filter menu display a different label name, conditionally.

For example, if we have the checkbox filter menu showing the options(checkbox label) as numeric values -1, 0, 1. Please see attached image.

Is it possible to update the text for the checkbox label? like if the value for "fruits" = -1 then display the label as "Apples",  if the value for "fruits" = 0 then display the label as "Oranges",  or if the value for "fruits" = 1 display as "Bananas", etc?

Konstantin Dikov
Telerik team
 answered on 01 Aug 2024
1 answer
120 views
I am using combobox inside the kendo grid. the problem i am facing is when i select the combobox & if i click outside the grid or inside the empty space in the grid, the combo box is still in active state. i want to remove the active state of the combobox after clicking outside the grid or in the empty space of the grid 
Vessy
Telerik team
 answered on 01 Aug 2024
1 answer
126 views
If the filter is applied, it has found the elements and the number of elements does not exceed the visible area - the scrollbar disappears, it's ok. But if the filter is applied and it hasn't found the elements - the scrollbar doesn't disappear. The expected behavior in this case is to reset the scrollbar, since there are no found items and the grid list is empty.
Are there any planned changes to this case?
Konstantin Dikov
Telerik team
 answered on 01 Aug 2024
1 answer
171 views

I am encountering an issue with saving and restoring the zoom state in the Kendo React Charts component. The problem arises when I attempt to save the zoom level and reapply it whenever the chart data updates. Although the zoom state values are captured correctly, the chart resets to its default zoom level after each zoom interaction.

This is the parent Component:

function Monitor () {
  const { chartDataByParameter, treshholdRangeData } = useTable()
  const [zoomState, setZoomState] = useState({})

  const handleZoomChange = (newZoomState) => {
    setZoomState(newZoomState)
  }

  return 
          <ChartComponent dataProps={chartDataByParameter} rangeData={treshholdRangeData} zoomState={zoomState} onZoomChange={handleZoomChange} />
}

export default Monitor


And this is the Chart Component. Note that i have two axis because is the only way I found to deal with negative values.

function ChartComponent ({ dataProps, rangeData, zoomState, onZoomChange }) {
  const chartRef = useRef(null)

  useEffect(() => {
    setIsChartLoading(false)
    if (chartRef.current && chartRef.current.kendoChart) {
      chartRef.current.kendoChart.setOptions({
        categoryAxis: {
          min: zoomState.xAxis.min,
          max: zoomState.xAxis.max
        },
        valueAxis: {
          min: zoomState.valueAxis.min,
          max: zoomState.valueAxis.max
        }
      })
    }
  }, [dataProps])

  const handleZoom = (event) => {
    const newZoomState = {
      xAxis: {
        min: event.axisRanges?.xAxis?.min,
        max: event.axisRanges?.xAxis?.max
      },
      valueAxis: {
        min: event.axisRanges?.valueAxis?.min,
        max: event.axisRanges?.valueAxis?.max
      }
    }
    onZoomChange(newZoomState)
  }

  const colors = ['#718ad5', '#424242', '#ffe162', '#4cd180', '#8634b7']
  const categoryAxisMaxDivisions = 10


  return (
<div style={{ height: '55vh, width: '100%' }}>
      {(dataProps && dataProps.length > 0) || (rangeData && rangeData.length > 0)
        ? (
        <Chart
          ref={chartRef}
          style={{ height: '100%', width: '100%' }}
          pannable={true}
          zoomable={true}
          transitions={false}
          className='custom-chart'
          onZoom={handleZoom}
        >
          <ChartLegend position="top" />
          <ChartCategoryAxis>
            <ChartCategoryAxisItem name="xAxis" maxDivisions={categoryAxisMaxDivisions} visible={false} />
            <ChartCategoryAxisItem name="xAxis2" maxDivisions={categoryAxisMaxDivisions} />
          </ChartCategoryAxis>
          <ChartSeries>
            {dataProps.map((item, index) => (
              <ChartSeriesItem
                key={index}
                type="line"
                data={item}
                field="value"
                categoryField="category"
                name={item[0].parameter}
                style="smooth"
                color={item[0].parameter === 'Anomalies' ? '#d75d5d' : colors[index]}
                width={item[0].parameter === 'Anomalies' ? 0 : 2}
                legendItem={item[0].parameter === 'Anomalies' ? customLegendItem : customLegendItem2}
                tooltip={{ visible: true, render: lineTooltipRender }}
              />
            ))}
            {rangeData.length > 0 && (
              <ChartSeriesItem
                type="rangeArea"
                data={rangeData}
                fromField="min"
                toField="max"
                categoryField="Datetime"
                name="Anomaly sensitivity"
                color='#80cf63'
              >
                <ChartTooltip render={rangeTooltipRender} />
              </ChartSeriesItem>
            )}
          </ChartSeries>
          <ChartValueAxis>
            <ChartValueAxisItem
              name="valueAxis"
              axisCrossingValue={[0, Number.NEGATIVE_INFINITY]}
              labels={{ format: (value) => value.toFixed(2) }}
            />
          </ChartValueAxis>
        </Chart>
          )
        : (
        <div style={{ height: chartHeight, width: '100%' }}></div>
          )}
    </div>
  )
}
}

const MemoizedChartComponent = React.memo(ChartComponent)
export default MemoizedChartComponent

Thank you in advance!

Xavier

Konstantin Dikov
Telerik team
 answered on 31 Jul 2024
Narrow your results
Selected tags
Tags
General Discussions
Grid
Wrappers for React
Charts
Scheduler
Filter 
DropDownList
Form
Styling / Themes
DatePicker
Editor
TreeList
Styling
PDF Processing
ComboBox
Excel Export
Dialog
Input
TreeView
Upload
Drawer
Button
Drag and Drop
MultiSelect
Tooltip
Accessibility
NumericTextBox
Checkbox
Menu
Gantt
DateTimePicker
PDF Viewer
Popup
Window
AutoComplete
DateInput
Sortable
Data Query
Licensing
TabStrip
Drawing
Calendar
Pager 
Labels 
Localization
TimePicker
GridLayout
FontIcon
Animation
PanelBar
TaskBoard
PivotGrid
Card
DropDownButton
Conversational UI 
DateRangePicker
Splitter
Badge 
Security
Slider
Spreadsheet
ContextMenu
MultiViewCalendar
Stepper
MultiColumnComboBox
MultiSelectTree
TextBox
AppBar
File Saver
ListView
MaskedTextBox
RadioButton
Switch
TextArea
Toolbar
DropDownTree
TileLayout
Map
Avatar
Date Math
Gauge
RadioGroup
RangeSlider
Rating
Loader
ExpansionPanel
SvgIcon
Typography
ProgressBar
ScrollView
Popover
StockChart
RadialGauge
Server Components
AIPrompt
Page Templates / Building Blocks
AI Coding Assistant
Chat
ColorGradient
ColorPalette
ColorPicker
Notification
Ripple
Skeleton
ButtonGroup
Chip
ChipList
FloatingActionButton
SplitButton
ActionSheet
Barcode
QR Code
FlatColorPicker
Signature
BottomNavigation
BreadCrumb
StackLayout
Timeline
ListBox
ChunkProgressBar
Sparkline
FileManager
ArcGauge
CircularGauge
LinearGauge
ExternalDropZone
OrgChart
Sankey
VS Code Extension
InlineAIPrompt
SpeechToTextButton
Chart Wizard
Agentic UI Generator
SmartPasteButton
PromptBox
SegmentedControl
+? more
Top users last month
Miljana
Top achievements
Rank 2
Iron
Iron
Joel
Top achievements
Rank 3
Bronze
Bronze
Bronze
Cynthia
Top achievements
Rank 1
John
Top achievements
Rank 1
Iron
Mozart
Top achievements
Rank 1
Iron
Veteran
Want to show your ninja superpower to fellow developers?
Top users last month
Miljana
Top achievements
Rank 2
Iron
Iron
Joel
Top achievements
Rank 3
Bronze
Bronze
Bronze
Cynthia
Top achievements
Rank 1
John
Top achievements
Rank 1
Iron
Mozart
Top achievements
Rank 1
Iron
Veteran
Want to show your ninja superpower to fellow developers?
Want to show your ninja superpower to fellow developers?