Hi,
I am currently working on a project that import data from an API call to get fuel prices and display them in a line graph format. I am currently having trouble with the display of the X-axis when it comes to the dateTime formatting. Before I explain the problem, below is the data that I am working with from the API call:
[{id: 9142, dateTime: "2022-03-09T05:05:07.913", state: "Oregon", regular: 4.66, midGrade: 4.79,…},…] 0: {id: 9142, dateTime: "2022-03-09T05:05:07.913", state: "Oregon", regular: 4.66, midGrade: 4.79,…} 1: {id: 9193, dateTime: "2022-03-10T05:05:04.947", state: "Oregon", regular: 4.72, midGrade: 4.87,…} 2: {id: 9244, dateTime: "2022-03-11T05:04:54.91", state: "Oregon", regular: 4.74, midGrade: 4.92,…} 3: {id: 9295, dateTime: "2022-03-12T05:04:53.517", state: "Oregon", regular: 4.74, midGrade: 4.92,…} 4: {id: 9346, dateTime: "2022-03-13T05:04:53.54", state: "Oregon", regular: 4.73, midGrade: 4.92,…} 5: {id: 9397, dateTime: "2022-03-14T05:05:06.73", state: "Oregon", regular: 4.74, midGrade: 4.92,…} 6: {id: 9448, dateTime: "2022-03-15T05:04:55.69", state: "Oregon", regular: 4.74, midGrade: 4.92,…} 7: {id: 9499, dateTime: "2022-03-16T05:05:00.057", state: "Oregon", regular: 4.73, midGrade: 4.92,…} 8: {id: 9550, dateTime: "2022-03-17T05:05:14.053", state: "Oregon", regular: 4.71, midGrade: 4.92,…} 9: {id: 9601, dateTime: "2022-03-18T05:05:27.097", state: "Oregon", regular: 4.7, midGrade: 4.92,…} 10: {id: 9652, dateTime: "2022-03-19T05:05:15.56", state: "Oregon", regular: 4.7, midGrade: 4.91,…} 11: {id: 9703, dateTime: "2022-03-20T05:05:06.317", state: "Oregon", regular: 4.71, midGrade: 4.91,…} 12: {id: 9754, dateTime: "2022-03-21T05:05:06.853", state: "Oregon", regular: 4.71, midGrade: 4.9,…} 13: {id: 9805, dateTime: "2022-03-22T05:05:03.377", state: "Oregon", regular: 4.71, midGrade: 4.91,…}
The problem I am having with this is once the AJAX called the API to get the data, I have to flip the array in the reverse order for it to display the correctly and below is the output of how it looks like:
As shown above, the start date is in the wrong position and the end date is at the start position of the graph. If I didn't reverse the array, I would have the opposite direction of the graph but the graph does not align correctly (shown below):
I was wondering if the igDataChart has it way of configuring the timeDate format or is it something else? Any suggestion would be great!
Thank you
Hello Tu,
Thank you for contacting Infragistics Support!
I believe that you will find the following sample I have prepared for you very helpful. As you can observe when setting the axisX type to categoryDateTimeX, the igDataChart manages successfully to order the items and you won’t have to reverse or sort the array. For example, I have placed the following date “2022-03-02T05:05:04.947” in the middle of the array and it is still displayed at the beginning of the chart. Please let me know if you need any additional information.
Best Regards, Martin Evtimov Software Developer Infragistics, Inc.
Hi Martin,
Thank you for your reply and helping out, I tried to implement this and test it out and it works when the array is static. Currently, I'm working on this with an API call and using ajax to get the data, and the data would not update on the DataChart with the ajax call with this layout. Is there a way to use this layout calling the usage of a dynamically rather than static?
Thank you,
Thank you for getting back to me!
I’m glad that the suggested approach with static data works as expected. Having this in mind, I believe that the described behavior is because the chart is not notified that its data has been changed and it is not updated.
Please note that in order to configure the igDataChart to work with dynamic data, the following methods could be used: notifyClearItems, notifyInsertItems, notifyRemoveItems or notifySetItem. Another possible approach could be rebinding the data:
$(".selector").igDataChart("option", "dataSource", newData);
Please let me know if you need any further information!
Thank you for getting back to me, I tried to implement the rebinding data and still have nothing display for me on the graph. Below is a screenshot of the AJAX call that I am using to rebind the data onto the global array I setup (which is called "oregonData"):
I am still stuck on this subject with the igDataChart. I was wondering can you give me a snippet demonstration on how to do it with the "insert, remove, set" method and the "rebinding" method?
I think I might be going down the wrong way with this but below is also how I setup the datachart in the JQUERY also, so you get the context of how I setup up. Any help is great! Thank you for taking your time helping me out with this!
CreateChart("#chart", "Line"); function CreateChart(chartID, chartTitle) { $(chartID).igDataChart({ width: "1000px", height: "500px", title: chartTitle, horizontalZoomable: true, verticalZoomable: true, dataSource: oregonData, axes: [{ name: "xAxis", type: "categoryDateTimeX", dateTimeMemberPath: "dateTime", lateb: "dateTime", labelAngle: -70, formatLabel: function(item) { var res = ''; res += item.getFullYear(); res += "/"; res += item.getMonth() + 1; res += "/"; res += item.getDate(); res += ' ' res += ("0" + item.getHours()).slice(-2); res += ':'; res += ("0" + item.getMinutes()).slice(-2); return res; }, labelTextStyle: "8pt Verdana", }, { name: "yAxis", type: "numericY", title: "Price(s)", labelTextStyle: "8pt Verdana", } ], series: [{ type: "line", markerType: "circle", xAxis: "xAxis", yAxis: "yAxis", name: "Oregon", valueMemberPath: "diesel", isTransitionInEnabled: true, isHighlightingEnabled: true, }] }); }
Tu
In this sample is demonstrated how igDataChart with the same configuration as yours can work properly with dynamic data.
Please check if there is something missing in your local project. If you are still facing the issue with the updating of the data source please feel free to modify the provided sample and send it back to me along with steps to reproduce.
Alternatively, if the behavior cannot be replicated please feel free to provide your own runnable sample. Please keep in mind to remove any dependencies and code that is not directly related to the issue.
Having a working sample on my side, which I can debug, is going to be very helpful in finding the root cause of this behavior.
Thank you for your cooperation.
Looking forward to hearing from you.
Regards,Viktor KombovEntry Level Software DeveloperInfragistics, Inc.
Hi Viktor,
Thank you so much for your help, I was able to got it to work and stuff on my end. Everything is working correctly. Thank so much again for your help.
One last thing I wanted to let you guys know, I don't know if it is a bug with igDataChart or not, but I have a dropdown box of states list. But every time I selected states that starts with the letter A (Alaska, Alabama, Arkansas, Arizona) won't populate on graph if they are combine together with other states and only populate if that is the only state selected.
Everything else work fine with other states either alone or combining them to display on chart like from California and onward.
I was just wondering if this is a bug on the igDataChart side or is it something wrong with my code?
[PS: I checked the data was store correctly on the array before it is pass into datachart so I know data is correctly format]
Tu Lam
As we have already mentioned, in order to be able to assist you further we will need a working sample which we can debug on our sides in order to find the root cause of described behavior.
What I would suggest you is to modify the sample that I have provided and send it back to us for further investigation. Alternatively, if the behavior cannot be replicated, please feel free to provide your own isolated sample, where the issue is reproducible. Please keep in mind to remove any dependencies and code that is not directly related to the issue.
Looking forward to hearing from you!
Below will be couple snippet of code on how I setup the entire thing, and I will divide it up and give you each what each function does:
IgDataChart Setup: This is the code using the same example Viktor gave me and I modify it around a bit to fit what my project require.
// Setup a function for calling data chart function CreateChart(chartID, seriesType, chartTitle, chartData) { // Create a variable to map each unique dateTime & States var uniqueDates = chartData.map(rec => rec.dateTime) .filter((value, index, self) => self.indexOf(value) === index) .map((item) => { return { dateTime: new Date(item) } }); var uniqueStates = chartData.map(rec => rec.state) .filter((value, index, self) => self.indexOf(value) === index); // Setup an empty array to store the series of each states var seriesStates = []; // Go through each states and push the data for that state by creating a series for it uniqueStates.forEach(stateName => seriesStates.push(CreateSeries('line', stateName, chartData))) // Setup the igDataChart $(chartID).igDataChart({ width: "1300px", height: "600px", title: chartTitle, dataSource: data, gridMode: "beforeSeries", legend: { element: 'legend', type: 'legend' }, axes: [{ name: "xAxis", type: "categoryDateTimeX", title: "Date & Time of Fuel", dataSource: uniqueDates, dateTimeMemberPath: "dateTime", label: "dateTime", labelAngle: 0, formatLabel: function(item) { var res = ''; res += item.getMonth() + 1; res += "/"; res += item.getDate(); res += "/"; res += item.getFullYear(); res += ' ' return res; }, labelTextStyle: "9pt Verdana", }, { name: "yAxis", type: "numericY", title: "Diesel Fuel Price(s)", labelTextStyle: "9pt Verdana", }], series: seriesStates }); } // Setup a function to create per series to match with states' data function CreateSeries(seriesType, stateName, chartData) { // Create a series variable to filter through date and states var seriesData = chartData.filter(rec => { if (rec.state === stateName) { return true; } }).map((item) => { return { ...item, dateTime: new Date(item.dateTime), }; }); // Setup some variables to create series line var thickness = 2; var markerType = "none"; // Check for some seriesType and set it correctly if (seriesType == "column" || seriesType == "waterfall") { thickness = 1; } if (seriesType == "point") { markerType = "circle"; } if (seriesType == "line") { markerType = "circle"; } // Create the series to show on graph/data chart var series = { type: seriesType, dataSource: seriesData, markerType: markerType, xAxis: "xAxis", yAxis: "yAxis", name: stateName + "series", title: stateName, valueMemberPath: "diesel", isTransitionInEnabled: true, isHighlightingEnabled: true, showTooltip: true, thickness: thickness } // Return the series to the chart return series; }
GetGridData: This function called the igcombo to get the selected states from the box and get the date to be pass into another function (in the code below too) where it uses AJAX call to get the data to that specific states to bind it onto the chart and grid:
// Create a function to get data for the grid function GetDataForGrid() { // Create an array that store the states was selected var statesSelected = []; var selectedStates = $("#SelectedStatesList").igCombo("selectedItems"); // Check to see if states was selected or is it a default states if(selectedStates == null) { statesSelected.push({stateName: "Oregon"}); statesSelected.push({stateName: "Washington"}); } else { $.each(selectedStates, function(index, value){ statesSelected.push({stateName: value.data.stateName}); }); } // Store the start & end dates to be used later var start = $("#StartDate").val(); var end = $("#EndDate").val(); // Call the function to get data from the states selected PostAndGetDataForGridandChart(start, end, statesSelected); } // Create the POST & GET data for Grid function & the Data Chart function PostAndGetDataForGridandChart(start, end, statesSelected) { $.ajax({ type: "POST", url: '@Url.Action("GetGridData", "Home")', data: { StartDate: start , EndDate: end, SelectedStates: statesSelected }, dataType: "json" }) .done(function (json) { // Bind the data onto the grid $("#mainGrid").igGrid("option", "dataSource", json); $("#mainGrid").igGrid("dataBind"); // First destroy the chart with old data $("#chart").igDataChart("destroy"); // Then generate the updated one with the new data CreateChart("#chart", "line", "Fuel Price(s) Web Statistic", json); }) .fail(function (jqXhr, textStatus, errorThrown) { console.warn(jqXhr.responseText); alert(errorThrown + ' getJSON request failed for grid & chart ' + textStatus); }); }
Setup of IgCombo: The setup of combo box in the on-load event
// Setup the stateSelection Box $("#SelectedStatesList").igCombo({ dataSource: states, textKey: "stateName", valueKey: "stateName", width: "250px", height: "30px", dropDownWidth: "200px", format: "auto", multiSelection: { enabled: true, addWithKeyModifier: false, showCheckboxes: true, itemSeparator: ', ' }, selectionChanged: function(evt, ui){ GetDataForGrid(); } });
This is how setup layout is. The result from the data to be parse onto the chart follow the same format as the data I gave back in a couple comments ago about how the AJAX return the data. And the parsing can be found under the code GetGridData snippet. If there is anything else you guys need. Feel free to reach out to me. And thank you for taking the time looking into this for me.
Sincerely,
Hello Lu,
Thank you for getting back to us!
Please note that as Viktor have mentioned without having a small working sample which we can debug on our sides it is going to be very hard to find the root cause of the described behavior. There are multiple approaches for appending new data to the chart (expanding the data source, appending new series which data comes from another data source and etc.) and in order to be able to assist you further we need to make sure that we start from the same point.
Having this in mind I could suggest modifying the sample Viktor has provided and send it back to us for further investigation. You can add a combobox with only 3 states, 2 starting with the letter “A” and one different. Please make sure that you’re using the exact same logic for populating the igDataChart as the one in your main project and that the issue when selecting the states starting with the letter “A” is still reproducible.