Thursday, 10 May 2018

Converting svg to base64

So i was trying to to convert some svg string to base64. Was using this nice module and them get an error. When looked into it I found out the core function to do that is URL.createObjectURL. And my bug was eventually solved by adding xmlns="http://www.w3.org/2000/svg" to my svg element. I have no idea why that happened...

Wednesday, 7 February 2018

Python dynamic function call example

dynamic function call python

class dataWriter(object):

def __init__(self, data):
self.data = data

#main function
def write(self):

#if contains this data, execute the corresponding writing function
for category,value in self.data.items():
self.__getattribute__(
'write'+category)(value)

def writeA(self, A):
print(
'A: ' + str(A))

def writeB(self, B):
print(
'B: ' + str(B))

def writeC(self, C):
print(
'C: '+ str(C))


a = dataWriter(data={
'A':100, 'B': 10})
a.write()
##result
#A: 100
#B: 10

Tuesday, 23 January 2018

On d3's Data Join and Why Sometimes Method Chaining is Troublesome

Don't get me wrong. D3 is a very powerful library, and data join is a very powerful feature. However, I have problem with its tendency to advertise method chaining in the official examples.

If you are using d3, the general updating pattern is probably the first thing you’ve learned.

Let's take the force-directed graph for example. The code below is directly copied from here.

var link = svg.append("g")
.attr(
"class", "links")
.selectAll(
"line")
.data(graph.links)
.enter().append(
"line")
.attr(
"stroke-width", function(d) { return Math.sqrt(d.value); });


And you probably have noticed the method chaining. Everything up to this point seems quite natural. let’s read it together line by line.

So, we append a group element to the svg, add a class attribute, select all the line elements(which gives us an empty collection at this point), binding it to our data graph.links. Then calling enter() gives us the the unbound data (If you don’t know how that happens, go to this official introduction), to which we append a line for each.

How neat, you would think! Yep, it is neat, for now.

But wait! One of the the merit of data binding is to modify the data and have our elements changing accordingly. So what say if we want to have an update function, which we call each time the data changes? Luckily there’s another example we can referring to. The parts relating to modifying link elements are copied below.

var link = g.append("g").selectAll("line");
function restart() {
// Apply the general update pattern to the links.
link = link.data(links,
function(d) { return d.source.id + "-" + d.target.id; });
link.exit().remove();
link = link.enter().append(
"line").merge(link);
...
}

Chances are you’ve never gone beyond the vanilla version of updating in the first part, and these three lines would throw you off the balance. So we know link.data do the data binding, but what does it really return? Digging a little bit into the reference and we know the answer:

It returns the overlapping part of the data and the existing elements - the update collection, as it is called. It also has two collections appending to it, calling enter() gives you the unbound data collection, and calling exit() gives you the unbound elements.

So we removes the unbound elements, adding new elements to new data. But what is merge doing here? The parameter ‘link’ is our update collection, and the caller on left side is still the newly bound elements, so we are adding the newly bound to the existing bound, which gives us all the elements at this point. Re-assigning it to link, next time when restart is called, we can again bind our new data to this collection.

Then you realize there’s no reason at all, to name the data binding return as ‘link’! We could name it as something else like linkUpdate, which is far clearer.

linkUpdate = link.data(links, function(d) { return d.source.id + "-" + d.target.id; });
linkUpdate.exit().remove();
link = linkUpdate.enter().append(
"line").merge(linkUpdate);

Right, so now let’s say our existing code is exactly like the first code, and we try to extend it to accommodate updating. Which parts should you put into the update function? So we read through the code, and saying oh, so up till the selectAll line will give me the initial data collection, so I should first cut this out. Then next line is data binding, then call enter gives me the new collection, wait, i need to delete the unbound elements, so I should first stop at data binding and make an assignment, with which later I can call exit()... Cover up the second code and try it yourself. Realize how cumbersome this process is?

var link = svg.append("g")
.attr(
"class", "links")
.selectAll(
"line")//cut here
.data(graph.links)//cut here so we call call exit
.enter().append(
"line")
.attr(
"stroke-width", function(d) { return Math.sqrt(d.value); });

var link = svg.append("g")
.attr(
"class", "links")
.selectAll(
"line")

var linkUpdate = link.data(graph.links);
linkUpdate.enter().append(
"line")
.attr(
"stroke-width", function(d) { return Math.sqrt(d.value); });

But what if we start with something like above? For one we just need to move sentences around and adding new ones, instead of reading through the whole chain trying to break it up.

But why is it better, you might ask? And why the previous one gives us problem?

You see, when we are using method chain, we usually hold the idea that we will always get the same object back each time we call a new function on it.

So for example in Jquery, you will be very comfortable with the following.

myEl.text('helloworld').css("color", "red").addClass("myclass")

Navigation is also not that hard to understand.

myEl.next().css("color", "red")

But be careful, in the second example we have context switching. After we call next, we are no long referring to the same object as before. But it is a very simple one so you mind bends without effort.

But in the previous no-break chain, how many times have we switched context? Five times! Big chances you might need to reuse some of the intermediate steps in the future. And everytime you are reading it, your mind is doing an extra hard round of twister. Why?

For one, the data() call for data binding and enter() call for getting to unbound collection are hardly very natural for human mind, as least not as self-explanatory as functions like next(). That, plus the example’s naming convention, aka calling these different contexts the same name, you will have headache 3 months later trying to read through your code ( which is exactly what happened to me yesterday).

So do yourself a favour, think twice when you are using method chain, and breaking them up if you notice you are switching context too many times.

Sunday, 21 January 2018

A useful pattern: disallow an action for a certain time

So I run into this problem when I have a socket event that fires quite frequently( but is supposed to work that way), and have an animation linking to this event, but do not want to fire the animation as frequently as the socket event itself. The solusion I deviced is to use a custom timer.