Strange behavior in a TVirtualStringTree - c++builder

Can someone explain to me why this is happening to me? I have this TVirtualStringTree:
As you can see, three nodes have been selected. I traverse the tree to delete the selected records with this loop:
PVirtualNode Nodo;
AnsiString cAux = "";
Query->Close();
Query->SQL->Text = "DELETE FROM Recibos WHERE CodPrv = :PrvIns AND RefInt = :RefInt AND ForPago = :Forma AND Junta = :Junta";
Nodo = Lista->GetFirst();
while (Nodo != NULL)
{
cAux = ((PTreeSelRec)Lista->GetNodeData(Nodo2))->Dato;
if (!Lista->HasChildren[Nodo] && Lista->CheckState[Nodo] > csUncheckedPressed)
{
try
{
Query->Close();
Query->ParamByName("PrvIns")->AsString = PrvIns;
Query->ParamByName("RefInt")->AsString = ((PTreeSelRec)Lista->GetNodeData(Nodo))->RefInt;
Query->ParamByName("Forma")->AsInteger = ((PTreeSelRec)Lista->GetNodeData(Nodo))->ForPago;
Query->ParamByName("Junta")->AsInteger = StrToInt(((PTreeSelRec)Lista->GetNodeData(Nodo))->Concepto);
Query->ExecSQL();
Query->Transaction->Commit();
}
catch(...)
{
fForBln->Hide();
Screen->Cursor = crArrow;
Query->Transaction->Rollback();
ShowMessage("Ha tenido lugar un error en el borrado de recibos.");
Application->ProcessMessages();
return;
}
}
Nodo = Lista->GetNext(Nodo);
}
I have set up with the debugger to tell me the values of HasChildren and CheckState. At no time do I modify, as you can see, the CheckState property of the nodes; however, when I start traversing the tree, the HasChildren property gives me the correct values (three times true and once false) but CheckState, when it enters the last level of each node (Tomelloso in the example), is only set to 0 (csUncheckedNormal). This is what the debugger returns:
As you can see, the first three times it takes the correct values: 10/01/2022, Ordinaries, Unknown. In all three cases HasChildren appears as true because in all three cases there is a child and CheckState as csCheckedNormal because the entire node is selected. But as soon as List->GetNext(Node) is done to take the TOMELLOSO value, without the code doing anything CheckState is set to csUncheckedNormal and, of course, the query is not executed.
I've tried forcing all nodes to expand (List->FullExpand()) but that doesn't work either; It only works well if before pressing the corresponding button the user manually displays the selected node, which is not very logical.
It seems that when the tree has more than three levels, not all nodes behave in the same way. What could I be doing wrong or what property of the object would I want to modify?

Related

Generic Linked Lists find duplicates

Good day all,
I am studying Bsc-IT but am having problems.
With the current covid-19 situation we have been left to basically self-study and I need someone to put me in the right direction (not give me the answer) with my code.
I must write a program called appearsTwice that receives a linked list as parameter and return another list containing all the items from the parameter list that appears twice or more in the calling list.
My code so far(am I thinking in the right direction? What must I look at?)
public MyLinkedList appearsTwice(MyLinkedList paramList)
{
MyLinkedList<E> returnList = new MyLinkedList<E>(); // create an empty list
Node<E> ptrThis = this.head;//Used to traverse calling list
Node<E> ptrParam= paramList.head; //neither lists are empty
if (paramList.head == null) // parameter list is empty
return returnList;
if (ptrThis == null) //Calling list is empty
return returnList;
for (ptrThis = head; ptrThis != null; ptrThis = ptrThis.next)
{
if (ptrThis == ptrThis.element)
{
returnList.append(ptrThis.element);
}
}
Some issues:
Your code never iterates through the parameter list. The only node that is visited is its head node. You'll need to iterate over the parameter list for every value found in the calling list (assuming you are not allowed to use other data structures like hashsets).
if (ptrThis == ptrThis.element) makes little sense: it tries to compare a node with a node value. In practice this will never be true, nor is it useful. You want to compare ptrParam.element with ptrThis.element, provided that you have an iteration where ptrParam moves along the parameter list.
There is no return statement after the for loop...
You need a counter to address the requirement that a match must occur at least twice.
Here is some code you could use:
class MyLinkedList {
public MyLinkedList appearsTwice(MyLinkedList paramList) {
MyLinkedList<E> returnList = new MyLinkedList<E>();
if (paramList.head == null) return returnList; // shortcut
for (Node<E> ptrParam = paramList.head; ptrParam != null; ptrParam = ptrParam.next) {
// For each node in the param list, count the number of occurrences,
// starting from 0
int count = 0;
for (Node<E> ptrThis = head; ptrThis != null; ptrThis = ptrThis.next) {
// compare elements from both nodes
if (ptrThis.element == ptrParam.element) {
count++;
if (count >= 2) {
returnList.append(ptrParam.element);
// no need to look further in the calling list
// for this param element
break;
}
}
}
}
return returnList; // always return the return list
}
}

Vaadin Chart: Second and Subsequent Item Does Not Show on Each X-Tick in Column Stack Chart

Base on the resultset below, I have created a column stack chart. They have been converted to an 4-attribrute object list (called as SKUQtyMetric - all are strings except for Quantity as Integer)
When converting this to a stack chart, I could not get the second item to appear next to the first item in each of the x-ticks (X represents hour). If I am not mistaken, there should only be four DataSeries objects, each representing an outlet and then do an inner loop. Just as a side note, each outlet is designated a color even if there's more than one item (I am keeping a limit of three items to be selected for searching in database), hence there's the outletFromH code below.
The current rendering of the code (using Vaadin Charts 4) is as below:
Map<String, Set<String>> myMaps = new HashMap<String, Set<String>>();
for (SkuQtyMetric item : objList) {
if (!myMaps.containsKey(item.getOutletName())) {
myMaps.put(item.getOutletName(), new HashSet<String>());
}
myMaps.get(item.getOutletName()).add(item.getItemName());
}
String asgnColor = "#ffcccc";
for(Map.Entry<String, Set<String>> map: myMaps.entrySet()) {
DataSeries dataSeries = new DataSeries(map.getKey()+"");
PlotOptionsColumn plotOptions = new PlotOptionsColumn();
plotOptions.setStacking(Stacking.NORMAL);
DataLabels labels = new DataLabels(true);
Style style = new Style();
style.setFontSize("9px");
style.setTextShadow("0 0 3px black");
labels.setStyle(style);
labels.setColor(new SolidColor("white"));
plotOptions.setDataLabels(labels);
ls.add(dataSeries);
for(String itemName: map.getValue()) {
System.out.println("Inside " + map.getKey() + ", value is: " + itemName);
dataSeries.setId(itemName);
for(SkuQtyMetric metric : objList) {
for (Map.Entry<String, String> outletfromH : Constant.SYCARDA_COLOR.entrySet()) {
if (outletfromH.getKey().equalsIgnoreCase(map.getKey())) {
asgnColor = outletfromH.getValue();
}
}
System.out.println("DataSeries Id: " + dataSeries.getId() + " , Item metric name is: "+metric.getItemName());
if(dataSeries.getName().equalsIgnoreCase(metric.getOutletName())) {
if(dataSeries.getId().equalsIgnoreCase(metric.getItemName())) {
DataSeriesItem dataSeriesItem = new DataSeriesItem(xFor(metric.getHourNumber()), metric.getQuantityAmt());
dataSeriesItem.setId(metric.getItemName()+"_setSeriesId");
dataSeriesItem.setColor(new SolidColor(asgnColor));
dataSeries.setStack(metric.getItemName());
plotOptions.setColor(new SolidColor(asgnColor));
dataSeries.setPlotOptions(plotOptions);
dataSeries.add(dataSeriesItem);
}
}
}
}
}
for (int j = 0; j < ls.size(); j++) {
listSeries.add(ls.get(j));
}
chart.getConfiguration().getSubTitle().setText(subpageName);
chart.getConfiguration().setSeries(listSeries);
When rendered, I could only get this result:
That's the current chart but second item (coconut water) is missing, shown with red scribbling. What I am not sure is whether my Map class OR my list objects controlled isn't correct OR it might be that there should be eight not four DataSeries (each being a outlet and a product). If not, is there a much more efficient way to handle the code to render the chart than what I am doing right now?
It should be possible to have multiple DataSeriesItem in the same series that go in the same stack. Four series should be enough, no need to have 8.
You can do it by setting the name of the DataSeriesItem and set the XAxis type to category so that the categories are computed from the point names.
Or by setting numeric X values to the DataSeriesItem and setting the categories to the XAxis as a String[].
Having separate series makes some things easier, like tooltips, and showing/hiding data from the legend. But in theory everything can be in a single series.
In some cases you might need to be sure that data is sorted by X value, or by name if you use the name as categories otherwise some points might not show correctly, you can check if that's your case by checking the browser console for error or warnings about that.

Repast: how to get a particular agent set based on the specific conditions?

I am previously working with Netlogo and there are some very good built-in methods that allow me to filter and control the desired agents from the total population. (see: http://ccl.northwestern.edu/netlogo/docs/dictionary.html#agentsetgroup). For instance, I could very easily to command the different class of people agent in a simulation with simple codes like:
ask peoples with [wealth_type = "rich"] [donate money...]
ask peoples with [wealth_type = "poor"] [get money from rich people...]
In Repast, are there list of methods specifically built for easy controlling of agent set?
The equivalent in Repast Simphony Java is to use a Query. Queries apply a predicate to each agent in the Context and returns those that evaluate to true in an iterator. The PropertyEquals query evaluates an agent's property w/r to some value (e.g. "wealth_type" and "rich"). Note that "property" here refers to a Java property, i.e., a getter type method:
String getWealthType() {
return wealthType;
}
where "wealthType" is the name of the property.
As an example, in the JZombies example model, we can query Humans whose energy is equal to 5.
Query<Object> query = new PropertyEquals<Object>(context, "energy", 5);
for (Object o : query.query()) {
Human h = (Human)o;
System.out.println(h.getEnergy());
}
The query() iterator returns all the humans whose energy is equal to 5.
You can get a bit more complicated in the equivalence test by providing your own predicate. For example,
PropertyEqualsPredicate<Integer, Integer> pep = (a, b) -> {
return a * 2 == b;
};
Query<Object> query2 = new PropertyEquals<Object>(context, "energy", 8, pep);
for (Object o : query2.query()) {
Human h = (Human)o;
System.out.println(h.getEnergy());
}
Here, we are checking if the energy * 2 == 8. The predicate is passed the agent's property value in the first parameter and the value to compare against in the second parameter. Given that the predicate returns a boolean, you could also test for inequality, greater than etc.
Simphony has a variety of queries available. See,
https://repast.github.io/docs/api/repast_simphony/repast/simphony/query/package-summary.html
https://repast.github.io/docs/RepastReference/RepastReference.html#_repast_model_design_fundamental_concepts
for more info.
You can also do this in Simphony's ReLogo dialect:
ask (turtles()){
if (wealth_type == "rich") {
donateMoney()
}
if (wealth_type == "poor") {
getMoneyFromRichPeople()
}
}
If you want to just collect the richTurtles you can do (where "it" is the default method to access the individual turtle that is iterated over with findAll):
richTurtles = turtles().findAll{
it.wealth_type == "rich"
}
or with an explicit closure argument:
richTurtles = turtles().findAll{x->
x.wealth_type == "rich"
}

lua: user input to reference table

I am having trouble with my tables, I am making a text adventure in lua
local locxy = {}
locxy[1] = {}
locxy[1][1] = {}
locxy[1][1]["locdesc"] = "dungeon cell"
locxy[1][1]["items"] = {"nothing"}
locxy[1][1]["monsters"] = {monster1}
The [1][1] refers to x,y coordinates and using a move command I can successfully move into different rooms and receive the description of said room.
Items and monsters are nested tables since multiple items can be held there (each with their own properties).
The problem I am having is getting the items/monsters part to work. I have a separate table such as:
local monsters = {}
monsters["rat"] = {}
monsters["rat"]["Name"] = "a rat"
monsters["rat"]["Health"] = 5
monsters["rat"]["Attack"] = 1
I am using a table like this to create outlines for various enemy types. The monster1 is a variable I can insert into the location table to call upon one of these outlines, however I don't know how to reference it.
print("You are in ", locxy[x][y]["locdesc"]) -- this works
print("You can see a ", locxy[x][y]["monsters]["Name"],".") - does not work
So I would like to know how I can get that to work, I may need a different approach which is fine since I am learning. But I would also specifically like to know how to / if it possible to use a variable within a table entry that points to data in a separate table.
Thanks for any help that can be offered!
This line
locxy[x][y]["monsters]["Name"]
says
look in the locxy table for the x field
then look in the y field of that value
look in the "monsters"` field of that value
then look in the "Name" field of that value
The problem is that the table you get back from locxy[x][y]["monsters"] doesn't have a "Name" field. It has some number of entries in numerical indices.
locxy[x][y]["monsters][1]["Name"] will get you the name of the first monster in that table but you will need to loop over the monsters table to get all of them.
Style notes:
Instead of:
tab = {}
tab[1] = {}
tab[1][1] = {}
you can just use:
tab = {
[1] = {
{}
}
}
and instead of:
monsters = {}
monsters["rat"] = {}
monsters["rat"]["Name"] = "foo"
you can just use:
monsters = {
rat = {
Name = "foo"
}
}
Or ["rat"] and ["Name"] if you want to be explicit in your keys.
Similarly instead of monsters["rat"]["Name"] you can use monsters.rat.Name.

jqTreeView - getting selected node's value in select event

Following is how I populate my jqTreeView.
View
#Html.Trirand().JQTreeView(
new JQTreeView
{
DataUrl = Url.Action("RenderTree"),
Height = Unit.Pixel(500),
Width = Unit.Pixel(150),
HoverOnMouseOver = false,
MultipleSelect = false,
ClientSideEvents = new TreeViewClientSideEvents()
{
Select="spawnTabAction"
}
},
"treeview"
)
<script>
function spawnTabAction(args, event) {
alert(args);
}
</script>
Controller
public JsonResult RenderTree()
{
var tree = new JQTreeView();
List<JQTreeNode> nodes = new List<JQTreeNode>();
nodes.Add(new LeafNode { Text = "Products", Value="Product/Product/Index" });
FolderNode fNode = new FolderNode { Text = "Customers" };
fNode.Nodes.Add(new LeafNode() { Text = "Today's Customers", Value = "Customer/Customer/Today" });
nodes.Add(fNode);
nodes.Add(new LeafNode { Text = "Suppliers", Value = "Supplier/Supplier/Index" });
nodes.Add(new LeafNode { Text = "Employees", Value = "Employee/Employee/Index" });
nodes.Add(new LeafNode { Text = "Orders", Value = "Order/Order/Index" });
return tree.DataBind(nodes);
}
What I want to do is spawn a tab based on the Value of the selected node. I tried a lot but couldn't get hold of the selected node's value.
Later I checked the DOM of rendered page and found that the value is nowhere added to the node but magically when I select the node the value appears in a hidden control by the name treeview_selectedState (treeview being the id of the control). I even traced all ajax calls but couldn't find anything.
Questions:
1) Where does it keep the Values of tree nodes?
2) How do I get the Selected Node's value in select event?
I even tried to get the treeview_selectedState control's value in select event but it returned [].
Then I added a button the view and hooked that onto a js function and found the value there. It makes me think that the value is not available in select event, am I right in thinking that?
I don't think getting selected node's value should be a this big deal? Am I missing something very obvious?
Thanks,
A
After trying so many things , I checked their demo and found the hints there (I shouldve done this as the first thing).
It was actually pretty straight forward
function spawnTabAction(args, event) {
alert($("#treeview").getTreeViewInstance().getNodeOptions(args).value);
}
Thanks,
A

Resources