Reacting™ & D3® Charting

First of all, please let me say this, React is designed for us native developer!(because of the similar API, lifecycle things…).

Long long ago, when Facebook tries to use HTML5 technology to build the mobile version of Facebook, it turns out to be a failure, at that time, there are not so many choices of front-end modularization framework to choose from.

But no pains, no gains.

I guess Facebook learns from it, and I guess they actually learn a lot from the process. Since then Facebook spend a lot of energy on iOS.(like building the very famous Paper™ APP)

So my point is, if there’s gonna be one technology to rule the mobile & web platform, that’s gonna be build by Facebook XD.

Flux

1
2
3
4
5
6
7
8
// some fancy usage in dispatcher, this looks awesome...
case 'BUY_SHOES':
AppDispatcher.waitFor([
ShoeStore.dispatcherIndex
], function() {
CheckoutStore.purchaseShoes(ShoeStore.getSelectedShoes());
});
break;

D3 Overview & concept

lower lever API, but more control

Behaviors - reusable interaction behaviors

Core - selections, transitions, data, localization, colors, etc.

Geography - project spherical coordinates, latitude & longitude math

Geometry - utilities for 2D geometry, such as Voronoi diagrams and quadtrees

Layouts - derive secondary data for positioning elements

Scales - convert between data and visual encodings

SVG - utilities for creating Scalable Vector Graphics

Time - parse or format times, compute calendar intervals, etc.

g

The g element is a container used to group objects. Transformations applied to the g element are performed on all of its child elements. Attributes applied are inherited by child elements. In addition, it can be used to define complex objects that can later be referenced with the element.

d3.select(selector)

Selects the first element that matches the specified selector string, returning a single-element selection. If no elements in the current document match the specified selector, returns the empty selection. If multiple elements match the selector, only the first matching element (in document traversal order) will be selected.

D3 + React

https://github.com/codesuki/react-d3-components

Let React have complete control over the DOM even when using D3. This way we can benefit from Reacts Virtual DOM.

https://github.com/esbullington/react-d3

With this approach, React itself is responsible for generating the SVG markup. d3.js is used for its tremendous collection of utility functions, such as those that calculate the path value for various chart types.

d3 example

From http://bl.ocks.org/mbostock

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
max-width: 640px;
margin: 40px auto;
}
input {
width: 100%;
}
</style>
<input type="range" min="0" max="1000" step="1" value="0">
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
d3.select("input").transition()
.duration(7500)
.tween("value", function() {
var i = d3.interpolate(this.value, this.max);
return function(t) { this.value = i(t); };
});
</script>

<!DOCTYPE html>

http://bl.ocks.org/mbostock/c501f6cae402ab5e90c9

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<!DOCTYPE html>
<meta charset="utf-8">
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script>
var data = [1, 1, 2, 3, 5, 8, 13, 21];
var width = 960,
height = 500,
radius = height / 2 - 10;
var arc = d3.svg.arc()
.innerRadius(radius - 40)
.outerRadius(radius)
.cornerRadius(20);
var pie = d3.layout.pie()
.padAngle(.02);
var color = d3.scale.category10();
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
svg.selectAll("path")
.data(pie(data))
.enter().append("path")
.style("fill", function(d, i) { return color(i); })
.attr("d", arc);
</script>

<!DOCTYPE html>










1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
width: 960px;
height: 500px;
position: relative;
}
form {
position: absolute;
top: 1em;
left: 1em;
}
path {
fill-rule: evenodd;
stroke: #333;
stroke-width: 2px;
}
.sun path {
fill: #6baed6;
}
.planet path {
fill: #9ecae1;
}
.annulus path {
fill: #c6dbef;
}
</style>
<form>
<input type="radio" name="reference" id="ref-annulus">
<label for="ref-annulus">Annulus</label><br>
<input type="radio" name="reference" id="ref-planet" checked>
<label for="ref-planet">Planets</label><br>
<input type="radio" name="reference" id="ref-sun">
<label for="ref-sun">Sun</label>
</form>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var width = 960,
height = 500,
radius = 80,
x = Math.sin(2 * Math.PI / 3),
y = Math.cos(2 * Math.PI / 3);
var offset = 0,
speed = 4,
start = Date.now();
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")scale(.55)")
.append("g");
var frame = svg.append("g")
.datum({radius: Infinity});
frame.append("g")
.attr("class", "annulus")
.datum({teeth: 80, radius: -radius * 5, annulus: true})
.append("path")
.attr("d", gear);
frame.append("g")
.attr("class", "sun")
.datum({teeth: 16, radius: radius})
.append("path")
.attr("d", gear);
frame.append("g")
.attr("class", "planet")
.attr("transform", "translate(0,-" + radius * 3 + ")")
.datum({teeth: 32, radius: -radius * 2})
.append("path")
.attr("d", gear);
frame.append("g")
.attr("class", "planet")
.attr("transform", "translate(" + -radius * 3 * x + "," + -radius * 3 * y + ")")
.datum({teeth: 32, radius: -radius * 2})
.append("path")
.attr("d", gear);
frame.append("g")
.attr("class", "planet")
.attr("transform", "translate(" + radius * 3 * x + "," + -radius * 3 * y + ")")
.datum({teeth: 32, radius: -radius * 2})
.append("path")
.attr("d", gear);
d3.selectAll("input[name=reference]")
.data([radius * 5, Infinity, -radius])
.on("change", function(radius1) {
var radius0 = frame.datum().radius, angle = (Date.now() - start) * speed;
frame.datum({radius: radius1});
svg.attr("transform", "rotate(" + (offset += angle / radius0 - angle / radius1) + ")");
});
d3.selectAll("input[name=speed]")
.on("change", function() { speed = +this.value; });
function gear(d) {
var n = d.teeth,
r2 = Math.abs(d.radius),
r0 = r2 - 8,
r1 = r2 + 8,
r3 = d.annulus ? (r3 = r0, r0 = r1, r1 = r3, r2 + 20) : 20,
da = Math.PI / n,
a0 = -Math.PI / 2 + (d.annulus ? Math.PI / n : 0),
i = -1,
path = ["M", r0 * Math.cos(a0), ",", r0 * Math.sin(a0)];
while (++i < n) path.push(
"A", r0, ",", r0, " 0 0,1 ", r0 * Math.cos(a0 += da), ",", r0 * Math.sin(a0),
"L", r2 * Math.cos(a0), ",", r2 * Math.sin(a0),
"L", r1 * Math.cos(a0 += da / 3), ",", r1 * Math.sin(a0),
"A", r1, ",", r1, " 0 0,1 ", r1 * Math.cos(a0 += da / 3), ",", r1 * Math.sin(a0),
"L", r2 * Math.cos(a0 += da / 3), ",", r2 * Math.sin(a0),
"L", r0 * Math.cos(a0), ",", r0 * Math.sin(a0));
path.push("M0,", -r3, "A", r3, ",", r3, " 0 0,0 0,", r3, "A", r3, ",", r3, " 0 0,0 0,", -r3, "Z");
return path.join("");
}
d3.timer(function() {
var angle = (Date.now() - start) * speed,
transform = function(d) { return "rotate(" + angle / d.radius + ")"; };
frame.selectAll("path").attr("transform", transform);
frame.attr("transform", transform); // frame of reference
});
</script>
1
2
3
4
5
6
7
8
9
10
11
//var data = [{x: 5, y: 10}, {x: 20, y: 5}]
var circles = svg.selectAll('circle')
.data(data)
circles.enter().append('circle')
.attr('cx', function(d) { return d.x })
.attr('cy', function(d) { return d.y })
.attr('r', 0)
.transition().duration(500)
.attr('r', 5)

First we make a selection object of all the svg circles in the visualisation (initially there will be none). Then we bind some data to the selection (our data array).

D3 keeps track of which data point is bound to which circle in the diagram. So initially we have two datapoints, but no circles; we can then use the .enter() method to get the datapoints which have “entered”. For those points, we say we would like a circle added to the diagram, centered on the x and y values of the datapoint, with an initial radius of 0 but transitioned over half a second to a radius of 5.

1
2
3
4
5
6
7
#import "PNChart.h"
//For BarC hart
PNBarChart * barChart = [[PNBarChart alloc] initWithFrame:CGRectMake(0, 135.0, SCREEN_WIDTH, 200.0)];
[barChart setXLabels:@[@"SEP 1",@"SEP 2",@"SEP 3",@"SEP 4",@"SEP 5"]];
[barChart setYValues:@[@1, @10, @2, @6, @3]];
[barChart strokeChart];

super cool example
http://codepen.io/xna2/pen/Dmqso

TIP

  • There’s a confusing idiom “scale”.

“Scales are functions that map from an input domain to an output range.”

http://stackoverflow.com/questions/17562119/how-to-interpret-the-d3-statement-var-r-d3-scale-linear-domain0-1-range

  • React files can actually be named like “*.react.js”. Then you can require it like this:
1
var FluxCartApp = require('./components/FluxCartApp.react');

Hmmm… definitely cooler, not sure if it’s useful

  • Paperclip™ is a great way for you to play around with d3, you just copy those html into the editor and see how things are going on. I don’t know how to explain it better, but you just fucking do it.

https://github.com/wbkd/awesome-d3

Let’s Make a Bar Chart http://bost.ocks.org/mike/bar/

D3 and React - the future of charting components?
http://10consulting.com/2014/02/19/d3-plus-reactjs-for-charting/

Play with D3:

http://jsfiddle.net/enigmarm/3HL4a/13/

http://bl.ocks.org/mbostock

One repo to rule them all

Awesome-react

http://latentflip.com/imperative-vs-declarative/

D3 Tutorials

Book

https://leanpub.com/D3-Tips-and-Tricks

https://leanpub.com/reactd3js

http://chimera.labs.oreilly.com/books/1230000000345/

Get them for free… Holy High(好厉害).

Course

This one’s not for free… so if there are team coverage? XD
https://www.udemy.com/mastering-d3-js/

Reference

https://github.com/mbostock/d3/wiki/%E9%80%89%E6%8B%A9%E9%9B%86#d3_select
https://scotch.io/tutorials/getting-to-know-flux-the-react-js-architecture
https://developer.mozilla.org/en-US/docs/Web/SVG/Element/g

Tools Built with D3

When you want to use D3 without actually writing any D3 code, you can choose one of the many tools built on top of D3!

Crossfilter
A library for working with large, multivariate datasets, written primarily by Mike Bostock. This is useful for trying to squeeze your “big data” into a relatively small web browser.

Cubism
A D3 plug-in for visualizing time series data, also written by Mike Bostock. (One of my favorite demos.)

Dashku
An online tool for data dashboards and widgets updated in real time, by Paul Jensen.

dc.js
The “dc” is short for dimensional charting, as this library is optimized for exploring large, multidimensional datasets.

NVD3
Reusable charts with D3. NVD3 offers lots of beautiful examples, with room for visual customizations without requiring as much code as D3 alone.

Polychart.js
More reusable charts, with a range of chart types available. Polychart.js is free only for noncommercial use.

Rickshaw
A toolkit for displaying time series data that is also very customizable.

Tributary
A great tool for experimenting with live coding using D3, by Ian Johnson.

ECMAScript 2015 Language Specification Note

When a constructor creates an object, that object implicitly references the constructor’s prototype property for the purpose of resolving property references. The constructor’s prototype property can be referenced by the program expression constructor.prototype, and properties added to an object’s prototype are shared, through inheritance, by all objects sharing the prototype. Alternatively, a new object may be created with an explicitly specified prototype by using the Object.create built-in function.

Seven Concurrency Models in Seven Weeks

Actors

More Object-Oriented than Objects

Functional programming avoids the problems associated with shared mutable state by avoiding mutable state. Actor programming, by contrast, retains mutable state but avoids sharing it.
Computer graphics is all about manipulating data—huge amounts of data. And doing it quickly.

GPGPU Programming

To create a complete program, we need to embed our kernel in a host program that performs the following steps:

  1. Create a context within which the kernel will run together with a command queue.
  2. Compile the kernel.
  3. Create buffers for input and output data.
  4. Enqueue a command that executes the kernel once for each work-item.
  5. Retrieve the results.

JavaScript Allongé

Book Link: https://leanpub.com/javascript-allonge/read

“Café Allongé, also called Espresso Lungo, is a drink midway between an Espresso and Americano in strength. There are two different ways to make it. The first, and the one I prefer, is to add a small amount of hot water to a double or quadruple Espresso Ristretto. Like adding a splash of water to whiskey, the small dilution releases more of the complex flavours in the mouth.

iOS Design Defection

App name

For example, the Chinese app sometimes always don’t have an english name, so in the case of the user prefer English language, he can’t use siri to open the app.
The principle is: When you are in other language mode, play like a native.

Ruby on rails miscs-Notes

Find the mistake

1
2
3
4
5
6
7
8
9
10
class CommentsController < ApplicationController
def users_comments
posts = Post.all
comments = posts.map(&:comments).flatten
@user_comments = comments.select do |comment|
comment.author.username == params[:username]
end
end
end

This is a classic example of the notorious “n+1” bug. The first line will retrieve all of the Post objects from the database, but then the very next line will make an additional request for each Post to retrieve the corresponding Comment objects. To make matters worse, this code is then making even more database requests in order to retrieve the Author of each Comment.

This can all be avoided by changing the first line in the method to:

posts = Post.includes(comments: [:author]).all
This tells ActiveRecord to retrieve the corresponding Comment and Author records from the database immediately after the initial request for all Posts, thereby reducing the number of database requests to just three.

Please note that the above answer is only one of a few ways that it is possible to avoid incurring an “n+1” penalty, and each alternative will have its own caveats and corner cases. The above answer was selected to be presented here since it requires the smallest change to the existing code and makes no assumptions regarding the reverse association of Comment to Post.

Incidentally, there’s another issue here (although not what we’re focused on in this question and answer); namely, erforming a query in Ruby that could instead be done in the database (and which would very likely be faster there!). A relatively complex query like this can instead be constructed in ActiveRecord pretty easily, thus turning a 3 database query operation (plus some Ruby code executing) into a single database query.


1
2
3
4
5
6
7
8
9
10
11
12
class MyController < ApplicationController
def options
options = {}
available_option_keys = [:first_option, :second_option, :third_option]
all_keys = params.keys.map(&:to_sym)
set_option_keys = all_keys & available_option_keys
set_option_keys.each do |key|
options[key] = params[key]
end
options
end
end

It’s dangerous to convert user supplied parameters to symbols, since Symbol objects in Ruby are not garbage collected. An attacker could send a series of requests with random keys that would be turned into symbols, quickly exhausting your server’s available memory and taking down your site.

There are two ways that this could be fixed. The first would be to use slice to eliminate values from the params hash that are not valid option keys. This would look something like:

params.slice(*available_option_keys)
An alternative, some would argue better, option would simply be to use String keys for your options. Unless you have an extremely large number of possible option keys, you won’t actually save that much memory by using Symbol keys instead.


CSRF

CSRF stands for Cross-Site Request Forgery. This is a form of an attack where the attacker submits a form on your behalf to a different website, potentially causing damage or revealing sensitive information. Since browsers will automatically include cookies for a domain on a request, if you were recently logged in to the target site, the attacker’s request will appear to come from you as a logged-in user (as your session cookie will be sent with the POST request).

In order to protect against CSRF attacks, you can add protect_from_forgery to your ApplicationController. This will then cause Rails to require a CSRF token to be present before accepting any POST, PUT, or DELETE requests. The CSRF token is included as a hidden field in every form created using Rails’ form builders. It is also included as a header in GET requests so that other, non-form-based mechanisms for sending a POST can use it as well. Attackers are prevented from stealing the CSRF token by browsers’ “same origin” policy.


1
2
3
h = HashWithIndifferentAccess.new
h[:my_value] = 'foo'
h['my_value'] #=> will return "foo"

Flatten:

Hash

1
2
3
a = {1=> "one", 2 => [2,"two"], 3 => "three"}
a.flatten # => [1, "one", 2, [2, "two"], 3, "three"]
a.flatten(2) # => [1, "one", 2, 2, "two", 3, "three"]

Array

1
2
3
4
5
6
s = [ 1, 2, 3 ] #=> [1, 2, 3]
t = [ 4, 5, 6, [7, 8] ] #=> [4, 5, 6, [7, 8]]
a = [ s, t, 9, 10 ] #=> [[1, 2, 3], [4, 5, 6, [7, 8]], 9, 10]
a.flatten #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
a = [ 1, 2, [3, [4, 5] ] ]
a.flatten(1) #=> [1, 2, 3, [4, 5]]

Link:

http://www.toptal.com/ruby-on-rails/interview-questions

Let's talk about PHP, Book Note

Recently I’ve been watching some “PHP, the good part”, here’s some thing i think good in it XD.

Integration with Web Pages

One of the greatest features of PHP is that it gives you the ability to generate HTML based on integration with a web server, be that Apache, IIS, or any other leading web server.

$_GET

The next superglobal entity to discuss is $_GET. The $_GET value is created automatically with the existence of a query string within a URL, or if a form is submitted with the

It’s important to understand that the $_GET array is refreshed on each page call, so you have to pass it on to each page being called further down the call stack. It’s different than the session concept in this regard.

$_POST

$_REQUEST

You can control the overall environment of superglobal arrays with the php.ini directive known as variables_order. The setting on my server is GPC. This means that the arrays are loaded and created in GET, POST, and COOKIE order, with the latter elements taking precedence over the former if they are similarly named. The “G” stands for GET, the “P” for POST, and the “C” is for cookie. If you remove one of the letters in GPC, save the .ini file and restart your server. The array rep- resented by that letter will not be created in the superglobal space on the web server.