@salasidis
@salasidis
Forum Replies Created
-
AuthorPosts
-
October 14, 2023 at 10:20 pm in reply to: Update Chart – always showing first graph, and not new graph #108990salasidisParticipant
After the first update, I tried this
if (updateChart > 0)
{
lineChart.Update();
}
dispChart = true;
//updateFlag++;
updateChart++;
graphOpened = true;
StateHasChanged();The results are inconsistent, most of the time the wrong label is present on the Value axis. Sometimes the scale is not present, but if move the range Selector, then the axis values are correct. Othertimes, the scale is always displayed correctly
October 14, 2023 at 12:01 am in reply to: Update Chart – always showing first graph, and not new graph #108981salasidisParticipantI managed to get the graph to update by using the DataSource directly with EWparData (the data comoing directly from SQL)
Then I set the – each time the chart is opened
lineChart.DataSource = EWparData;
However the seriesGroups are not updated, even though new values are entered into them.
I am not sure if the entire seriesGroup class/lists needs to be recreated each time, or if there is an easier way.
- This reply was modified 1 year, 1 month ago by salasidis.
salasidisParticipantI changed the Bands definition to ChartSeriesGroupBand (instead of ChartValueAxisBand)
Bands = new List<ChartSeriesGroupBand>()
{
new ChartSeriesGroupBand()
{
Opacity = (float)0.05,
MinValue = 10,
MaxValue = 20
}
},The setting of the data is
seriesGroups.ElementAt(0).Bands.ElementAt(0).Opacity = (float)0.05;
seriesGroups.ElementAt(0).Bands.ElementAt(0).MinValue = (float)minN;
seriesGroups.ElementAt(0).Bands.ElementAt(0).MaxValue = (float)maxN;This compiles successfully, but I get no visible bands
salasidisParticipantThe example did not have any bands in it, is it possible to repost. Thanks
I programmatically set the DisplayField and TextField elsewhere, and tried to set the Band values there as well (but the latter part did not work – likely because the actual elements were not properly created by me)
chart is defined as
<Chart @ref=”lineChart” DataSource=”chartData” 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” showToolTips=”true” />some elements are altered
chartData = EWparData;
seriesGroups.ElementAt(0).Series.ElementAt(0).DataField = “Result”;
seriesGroups.ElementAt(0).Series.ElementAt(0).DisplayText = par;seriesGroups.ElementAt(0).ValueAxis.Description = par;
seriesGroups.ElementAt(0).ValueAxis.Bands.ElementAt(0).Opacity = (float)0.05;
seriesGroups.ElementAt(0).ValueAxis.Bands.ElementAt(0).MinValue = (float)minN;
seriesGroups.ElementAt(0).ValueAxis.Bands.ElementAt(0).MaxValue = (float)maxN;dispChart = true;
salasidisParticipantThanks will try it.
In the end, I am popping up a modal window that covers the table, so coming out of the window, it is actually OK that it gets cleared, so I might leave it as is.
salasidisParticipantNever mind – found it under UI elements
salasidisParticipantAn 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 SQLEWparData = 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 dataselectedIndexes[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
salasidisParticipantThanks, that worked
salasidisParticipantI did, but the Area component has a dataFieldFrom and To (2 variables), but only a single displayText – the demo does not alter the pop up graph tip labels when you hover over a point. It still says Low and High – which are the actual variable names – only the legend changes to say Temperature Range.
I would like to change the y1 and y2 in my example, to Min and Max in the ToolTip that pops up. For now I called y1 ‘<‘ and y2 ‘>’ – but text would be better. I don’;t weant to actually call them min and max in the dataset, in order to save RAM space in the embedded device.
Thanks
salasidisParticipantThanks, that would work.
I commented out the data.splice function in the demo, as I would want to display all the data all at once. The X axis gets very crowded, and does not seem to update the distance between labels, etc.
Is there a way to do this.
Also presumably in my application, I could just push the data x 24 or so times, and do a single update at the end (should be faster).
salasidisParticipantWhat do I do if I am using a rangearea
type: ‘rangearea’,
series: [
{ dataFieldFrom: ‘y1’, dataFieldTo: ‘y2’, displayText: ”, opacity: 0.4 }
]? comma delimited
salasidisParticipantI created a rule in Azure CDN, such that all accesses to htmlelements/ will have the
”Access-Control-Allow-Origin”, “*”
Header appended.
Seems to have worked, but will post an update if other issues crop up
July 20, 2022 at 3:27 pm in reply to: Change Axis Labels, Range, Intervals, horizontal areas via JS #103417salasidisParticipantThanks – I had tried both square and round brackets just in case one or the other worked. It was the chart.refresh() that I was missing.
July 19, 2022 at 3:00 pm in reply to: Change Axis Labels, Range, Intervals, horizontal areas via JS #103411salasidisParticipantThanks – got that working
How about for elements that are arrays – for example horizontal bands
I can get them working via the main initialization, but not sure how to access them individually
I tried
chart.seriesGroups(0).bands(0).minValue = 0;
chart.seriesGroups(0).bands(0).maxValue = 100;
chart.seriesGroups(0).bands(0).color = ‘light gray’;but that did not work.
-
AuthorPosts