Is it possible to use custom mappers in cytoscape.js 2.0? - cytoscape.js

I can see that there is already support for direct mapping from a data attribute or a predefined linear mapping with mapData, is there a best-practice for using custom mapping functions?
http://cytoscape.github.io/cytoscape.js/#style/mappers
i.e. doing something like this:
...
style: cytoscape.stylesheet()
.selector('node')
.css({
'width': function() { return nonLinearFunction(this.data("attr")); }
})
...

What kind of function are you looking for? For performance reasons, it's important that the stored style values are not truly "dynamic": Mapper values are cached, and updated only on changes to data, for example.
It would be easier to add the kind of function you're looking for if it's something like a logarithmic function, some type of mathematical function, or similar. The main thing to keep in mind is that a callback function for "custom mappers" is not performant.

Related

Kotlin data class equality when one of the properties is a function

I wonder if a data class with one of the properties being a function, such as:
data class Holder(val x: Data, val f: () -> Unit)
can work at all, since the following test fails.
val a = {}
val b = {}
Assert.assertEquals(a, b)
Update: Use case for this could be to have a
data class ButtonDescriptor(val text: String, val onClick: () -> Unit)
and then flow it to UI whilst doing distinctUntilChanged()
I don't think this is possible, I'm afraid.
You can of course check reference equality (===, or == in this case because functions don't generally override equals()).  That would give you a definite answer where you have references to the same function instance.  But that doesn't check structural equality, and so reports the two lambdas in the question as different.
You can check whether the two functions are instances of the same class by checking their .javaClass property.  If the same, that would imply that they do the same processing — though I think they could still have different variables/captures.  However, if different, that wouldn't tell you anything.  Even the simple examples in the question are different classes…
And of course, you can't check them as ‘black boxes’ — it's not feasible to try every possible input and check their outputs.  (Even assuming they were pure functions with no side effects, which in general isn't true!)
You might be able to get their bytecode from a classloader, and compare that, but I really wouldn't recommend it — it'd be a lot of unnecessary work, you'd have to allow for the difference in class names etc., it would probably have a lot of false negatives, and again I think it could return the same code for two functions which behaved differently due to different parameters/captures.
So no, I don't think this is possible in JVM languages.
What are you trying to achieve with this, and could there be another way?  (For example, if these functions are under your control, can you arrange for reference equality to do what you need?  Or could you use function objects with an extra property giving an ID or something else you could compare?)
When you create your data class, if you pass the function by reference it will work with DiffUtils and distinctUntilChanged(). Function references do not break the isEquals() method of data classes in the same way that a lambda does.
For example, you create a function for your onClick:
private fun onClick() { // handle click }
and create your data class like
BottomDescriptor("some text", ::onClick)

Object aggregations in Querydsl-jpa

I would like to ask if there is any possibility to use object aggregation functions in JPA (which uses HQL). Functions like json_agg()
I would like to achieve something like. So the goal is to take entity and transform it into string.
Expressions.stringTemplate("jsonb_agg(json_build_object('entity', {0}))", qEntity.id)
Why I try to do I am getting org.hibernate.QueryException: No data type for node: org.hibernate.hql.internal.ast.tree.MethodNode error. I´ve read that problem is I can not use HQL cause I can not use the HQL object properties in json aggregation functions.
I would like to avoid using querydsl-sql as much as I can (It makes complications in docker app deployment, It needs to be connected to database etc). So is there any way how to agregate objects like this using HQL? I am using spring-data-jpa so these is opportunity to use this tool to if there is better solution in it.
Your QueryDSL snippet looks just fine, but you need to register custom functions for JSONB_AGG and JSON_BUILD_OBJECT as well as custom types for the JSONB result.
For the custom JSONB type you can use the JsonBinaryType from the hibernate-types library.
For the custom function, you need to create a MetadataBuilderInitializer that registers the SQL functions with Hibernate. you can take inspiration from my hibernate-types-querydsl-apt library (for example ArrayFunctionInitializer). Applied to JSON functions specifically, you would end up with something along the lines of:
public class ArrayFunctionInitializer implements MetadataBuilderInitializer {
#Override
public void contribute(MetadataBuilder metadataBuilder, StandardServiceRegistry standardServiceRegistry) {
metadataBuilder.applySqlFunction("json_build_object", new StandardSQLFunction("json_build_object", JsonBinaryType.INSTANCE));
metadataBuilder.applySqlFunction("jsonb_agg", new StandardSQLFunction("jsonb_agg", JsonBinaryType.INSTANCE));
}
}

Expressions vs computed properties in templates in Vue.js

What is better to use in templates: expressions or computed properties?
Ex:
<span :class="'static_part' + dynamic_part"></span>
...
data: {
dynamic_part: 'xxx',
}
or
<span :class="span_class"></span>
...
data: {
dynamic_part: 'xxx',
},
computed: {
span_class() {
return 'static_part' + dynamic_part;
}
}
1-st way is smaller and easier to understand. But what about performance?
According to official docs
In-template expressions are very convenient, but they are meant for simple operations. Putting too much logic in your templates can make them bloated and hard to maintain
and
Instead of a computed property, we can define the same function as a method. For the end result, the two approaches are indeed exactly the same. However, the difference is that computed properties are cached based on their reactive dependencies
I see that using computed property could also separate the logic from the content and help other who will read your code that this properties are calculated and based on other ones

A shorter way to transform enumValues to a multi-value map

New to Kotlin. I was thinking if there is a shorter way to write the following piece of code. It means to categorize enum values into a multi-value map.
fun androidPermissionsByCategory(): Map<String, List<String>> {
val result = hashMapOf<String, MutableList<String>>()
enumValues<AndroidPermission>().onEach {
result.getOrPut(it.permissionGroup, { mutableListOf() }).add(it.value())
}
return result
}
Suggestions?
That's good, solid code (especially if you're not experienced in Kotlin): good use of types, and the getOrPut() function.  (The only tweak I'd suggest would be to change hashMapOf() to mutableMapOf(), since you don't care about the exact type of map.  You could also replace the add() call with += operator, though that's more disputable.)
However, there's a shorter alternative in a more functional style:
fun androidPermissionsByCategory(): Map<String, List<String>>
= enumValues<AndroidPermission>()
.groupBy({ it.permissionGroup }, { it.value() })
(Disclaimer: I don't have Android libs, so I can't test this exactly.)
This uses the standard library's groupBy() function, which does exactly what you want: it compares items (using a key-selector lambda you provide), and uses it to create a multimap from them.
Here we're using the enum's permissionGroup field as the key.
We're also using the optional second parameter to transform the values in the multimap, in this case getting their value().
You'll find that Kotlin has functional alternatives to many of the common imperative patterns for constructing and transforming maps, lists, and similar structures; these are often more concise, more declarative, and easier to read.  Any time you find yourself looping over a list or similar, it's worth asking whether there's a better way.  (As you have here!  Your intuition is clearly working well :-)

DoJo get/set overriding possible

I don't know much about Dojo but is the following possible:
I assume it has a getter/setter for access to its datastore, is it possible to override this code.
For example:
In the dojo store i have 'Name: #Joe'
is it possible to check the get to:
get()
if name.firstChar = '#' then just
return 'Joe'
and:
set(var)
if name.firstChar = '#' then set to #+var
Is this sort of thing possible? or will i needs a wrapper API?
You can get the best doc from http://docs.dojocampus.org/dojo/data/api/Read
First, for getting the data from a store you have to use
getValue(item, "key")
I believe you can solve the problem the following way. It assumes you are using a ItemFileReadStore, you may use another one, just replace it.
dojo.require("dojo.data.ItemFileReadStore");
dojo.declare("MyStore", dojo.data.ItemFileReadStore, {
getValue:function(item, key){
var ret = this.inherited(arguments);
return ret.charAt(0)=="#" ? ret.substr(1) : ret;
}
})
And then just use "MyStore" instead of ItemFileReadStore (or whatever store you are using).
I just hacked out the code, didn't try it, but it should very well show the solution.
Good luck
Yes, I believe so. I think what you'll want to do is read this here and determine how, if it will work:
The following statement leads me to believe the answer is yes:
...
By requiring access to go through
store functions, the store can hide
the internal structure of the item.
This allows the item to remain in a
format that is most efficient for
representing the datatype for a
particular situation. For example, the
items could be XML DOM elements and,
in that case, the store would access
the values using DOM APIs when
store.getValue() is called.
As a second example, the item might be
a simple JavaScript structure and the
store can then access the values
through normal JavaScript accessor
notation. From the end-users
perspective, the access is exactly the
same: store.getValue(item,
"attribute"). This provides a
consistent look and feel to accessing
a variety of data types. This also
provides efficiency in accessing items
by reducing item load times by
avoiding conversion to a defined
internal format that all stores would
have to use.
...
Going through store accessor function
provides the possibility of
lazy-loading in of values as well as
lazy reference resolution.
http://www.dojotoolkit.org/book/dojo-book-0-9/part-3-programmatic-dijit-and-dojo/what-dojo-data/dojo-data-design
I'd love to give you an example but I think it's going to take a lot more investigation.