#108944
salasidis
Participant

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,

  1. the 1st time, the graph gets made, but the selection unselects by itself. The graph does not reupdate as is expected.
  2. The second time (select a different row), the same happens but now the graph updates every second as well
  3. 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
  4. 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>&nbsp;</p>

@inject HttpClient Http

<DropDownList @ref=”EWDeviceList” SelectedIndexes=”@selectedIndexes” Label=”Select Device” OnChange=”ChangeDevice” />

<p>&nbsp;</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://&#8221; + 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