JavaScript UI Libraries & Blazor Components Suite – Smart UI › Forums › Table › Blazor Table Selection › Reply To: Blazor Table Selection
An issue
I have a table, and a graph below it. When a row on the table is selected, I want to create the graph (data pulled from SQL server to graph).
The data in the table are updated every 1 second with new data, but I do not want the table to update, except when I select it (or change the selection).
I am getting an issue where when I press the selection,
- the 1st time, the graph gets made, but the selection unselects by itself. The graph does not reupdate as is expected.
- The second time (select a different row), the same happens but now the graph updates every second as well
- and the third time, the selection remains on the screen, and cannot be unselected (but can be changed to another selection). The second timer stops firing
- If I never render the chart, the same happens
Questions?
- Is there some interaction – maybe incomplete render? when the rendering is made to occur every second.
- Is there a way to just rerender one column in the table, without rendering the whole thing
- is there a timer function built in to any of the widgets to make the update driver internally by the widget?
The code is listed below in case required
@page “/DataList”
@inject HttpClient Http
@inject IJSRuntime JSRuntime
@using EnviroWatch.Shared
@using EnviroWatch.Client.Components
@using System.Reflection
<p> </p>
@inject HttpClient Http
<DropDownList @ref=”EWDeviceList” SelectedIndexes=”@selectedIndexes” Label=”Select Device” OnChange=”ChangeDevice” />
<p> </p>
<h5>Parameter Data</h5>
@if (devPars == null)
{
<p>Loading…</p>
}
else
{
<Table @ref=EWtable DataSource=”@devParsTableData” Columns=”@DPDcolumns” @key=”updateFlag” class=”table-hover table-striped table-bordered” Selection=true SelectionMode=”TableSelectionMode.One” OnChange=”SelectGraph”></Table>
}
@if (dispChart == false)
{
}
else
{
<Chart @ref=”lineChart” DataSource=”EWparData” Animation=”Animation.None” Caption=”” Description=””
ShowLegend=”false” ShowBorderLine=”false” Padding=”new Padding() { Left = 5, Top = 15, Right = 25, Bottom = 5 }”
XAxis=”xAxis” SeriesGroups=”seriesGroups” ColorScheme=”ChartColorScheme.Scheme01″ OnReady=”OnChartReady” @key=”updateChart” />
}
@code {
private List<EnviroWatchDevice>? EWdevs;
Table EWtable = new Table();
DropDownList EWDeviceList = new DropDownList();
private int[] selectedIndexes = new int[] { 0 };
private string deviceGet;
private string deviceResData;
private HttpClient httpClientRes = new HttpClient();
int updateFlag = 0;
int updateChart = 0;
private string Time { get; set; }
System.Threading.Timer timer;
bool didTimeInit = false;
List<Ewdata> EWparData = new List<Ewdata>();
Chart lineChart;
int? lastGraphpId = null;
bool dispChart = false;
ChartXAxis xAxis = new ChartXAxis()
{
DataField = “DateTm”,
DisplayText = “Date”,
BaseUnit = ChartBaseUnit.Minute,
};
IEnumerable<object> chartData;
List<ChartSeriesGroup> seriesGroups = new List<ChartSeriesGroup>(){
new ChartSeriesGroup()
{
Type = ChartType.Line,
ValueAxis = new ChartValueAxis()
{
UnitInterval = 10,
MinValue = 0,
MaxValue = 100,
Description = “Val”
},
Series = new List<ChartSeriesGroupSerie>()
{ new ChartSeriesGroupSerie()
{
DataField = “”,
DisplayText = “”
}
}
}
};
private class DPtableData
{
public string Parameter { get; set; }
public float Result { get; set; }
public float MinVal { get; set; }
public float MaxVal { get; set; }
public DPtableData(string _p, float _r, float _mn, float _mx)
{
Parameter = _p;
Result = _r;
MinVal = _mn;
MaxVal = _mx;
}
}
private List<DeviceParameter>? devPars;
private List<DPtableData>? devParsTableData = new List<DPtableData>();
TableColumn[] DPDcolumns = new TableColumn[]
{
new TableColumn()
{
Label=”Parameter”,
DataField=”Parameter”,
},
new TableColumn()
{
Label=”Result”,
DataField=”Result”,
},
new TableColumn()
{
Label = “Min Normal”,
DataField = “MinVal”,
},
new TableColumn()
{
Label = “Max Normal”,
DataField = “MaxVal”,
}
};
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
EWdevs = await Http.GetFromJsonAsync<List<EnviroWatchDevice>>(“/api/EnviroWatchDevices”);
// insert the data into the drop down list
if (EWdevs != null)
{
int i = 0;
foreach (EnviroWatchDevice EWdev in EWdevs)
{
EWDeviceList.Insert(i++, EWdev.DeviceName);
}
}
EWDeviceList.SelectedIndexes[0] = 0;
StateHasChanged();
}
private async void SelectGraph()
{
var selected = EWtable.Selected;
int? pId = null;
foreach (object item in selected)
{
if (item is string id)
{
var parameter = await EWtable.GetValue(id, “Parameter”);
string par = parameter.ToString();
// par contains the parameter name
// now need to get the ParamId for that parameter from the List<devPars>
foreach (var devParam in devPars)
{
if (par == devParam.ParamName)
{
pId = devParam.ParamId;
break;
}
}
if (pId == lastGraphpId) // only display graph once per selection – no updates
{
return;
}
else
{
if (pId != null)
{
// we have the para ID – get the data from SQL
EWparData = await Http.GetFromJsonAsync<List<Ewdata>>($”/api/Ewdata?pId={Uri.EscapeDataString(pId.ToString())}”);
// insert the data into the drop down list
if (EWparData != null)
{
// data to graph
// Use a regulkar chart, nor range area, as more data present – the min max values area will be the last entry’s min max values (in devParam)
chartData = EWparData;
seriesGroups.ElementAt(0).Series.ElementAt(0).DataField = “Result”;
seriesGroups.ElementAt(0).Series.ElementAt(0).DisplayText = par;
dispChart = true;
//updateFlag++;
updateChart++;
StateHasChanged();
}
}
}
}
}
}
private void OnChartReady(Chart chart)
{
var seriesGroups = chart.SeriesGroups;
var description = chart.Description;
var xAxis = chart.XAxis;
}
private async void ChangeDevice(Event chEv)
{
//ListBoxChangeEventDetail detail = chEv[“Detail”] as ListBoxChangeEventDetail;
if (devPars != null)
{
devPars.Clear();
devParsTableData.Clear();
}
// add dev par data
selectedIndexes[0] = EWDeviceList.SelectedIndexes[0];
string devNm = EWDeviceList.SelectedValues[0].ToString();
if (devNm != null)
{
devPars = await Http.GetFromJsonAsync<List<DeviceParameter>>($”/api/DeviceParameter?devNm={Uri.EscapeDataString(devNm)}”);
deviceGet = “http://” + EWdevs.ElementAt(selectedIndexes[0]).Ipaddress.ToString().TrimEnd() + “/getVars”;
System.Diagnostics.Debug.WriteLine(deviceGet);
deviceResData = await httpClientRes.GetStringAsync(deviceGet);
System.Diagnostics.Debug.WriteLine(deviceResData);
foreach (var dp1 in devPars)
{
var dptd = new DPtableData(dp1.ParamName, 0, (float)dp1.MinVal, (float)dp1.MaxVal);
devParsTableData.Add(dptd);
}
PasteDataToTable(deviceResData);
try
{
var selected = EWtable.Selected;
if (selected.Count() == 0) // only render updates if no graph is displayed
{
updateFlag++;
dispChart = false;
}
}
catch
{
updateFlag++; // if before EWtable has been rendered, then there will be an exception, and just render it
}
base.OnInitialized();
if (didTimeInit == false)
{
didTimeInit = true;
var timer = new System.Threading.Timer((_) =>
{
InvokeAsync(async () =>
{
Time = await GetValue(deviceResData);
PasteDataToTable(Time); // paste the new data into the table
updateFlag++;
Console.WriteLine(updateFlag);
});
}, null, 0, 1000);
}
StateHasChanged();
// EWtable.Render();
}
}
private async Task<string> GetValue(string drd)
{
return await httpClientRes.GetStringAsync(deviceGet);
}
private string PasteDataToTable(string deviceResData)
{
string errStr;
string[] s2Info = deviceResData.Split(“|”);
if (s2Info[0] != EWDeviceList.SelectedValues[0].ToString())
{
errStr = “Invalid Device Name: ” + s2Info[0];
return errStr;
}
// paste time here
int iVar = 0;
for (var iStr = 2; iStr < s2Info.Count() – 1;)
{
float res = float.Parse(s2Info[iStr++]);
float mn = float.Parse(s2Info[iStr++]);
float mx = float.Parse(s2Info[iStr++]);
devParsTableData.ElementAt(iVar).Result = res;
devParsTableData.ElementAt(iVar).MinVal = mn;
devParsTableData.ElementAt(iVar).MaxVal = mx;
iVar++;
}
StateHasChanged();
return null;
}
public void Dispose()
{
timer?.Dispose();
Console.WriteLine(“Timer Disposed”);
}
}
I wil paste the code below, but I am not sure how helpful it will be