D3.js : SELECTION

I am totally newbie in D3, so don’t expect me to share an advance tutorial for D3 XD I am still learning and this post would just be my another self-notes, wherever or whenever i need it :’)

This would be my first post about D3, and i just wanna share about what i think it’s important if you wanna start learning D3. Well, actually when i first try it, just look at the library, check the examples, download the code and try to run it inside my project. And it works fine. But, when i wanna go deeper about D3, like, you know, start to customize the view, i need to learn more about it and what i got first, i think about it’s Selection; I think it’s an important thing since to modify element, syling or adding event/action, i need to learn how i make selection to the element i want first.

Well, i’m not start by ‘how to make the chart/element’ bcz, as you know, i just download some chart already on github or bl.ocks.org/d3indepth XD sorry. But if you interested, you can visit this helpfull article right here : https://www.dashingd3js.com/

Okay, so we’ll start. I am already make the graph, like forced-directed graph, consist of nodes and links (the line to connect the nodes). And, i start to customize it. D3 selections allow DOM elements to be selected in order to do something with them, be it changing style, modifying their attributes, performing data-joins or inserting/removing elements. (http://d3indepth.com/selections/) – btw you should visit the site, it really helpful. In D3 we use SVG element.

Scalable Vector Graphics (SVG)

Scalable Vector Graphics (SVG) is a family of specifications for creating two-dimensional vector graphics. Vector graphics are not created out of pixels. Vector graphics are created with paths having a start and end point, as well as points, curves and angles in between. Since Vector Graphics are not created out of pixels, they can be scaled up to larger or smaller sizes without losing image quality.

SVG images and their behaviors are defined in XML text files. The XML text can be included in an HTML document. This text means that images can be created and edited in a text editor. Also, since the DOM includes XML as part of the DOM specification, we can use the DOM Tree to access and update the structure, content and style of SVG Images.

SVG comes with a basic set of shape elements:

  • Rectangle
  • Circle
  • Ellipse
  • Straight Line
  • Polyline
  • Polygon

Okay, i already make a force-directed-graph that looks like this :

D3 – forced network

Okay, it’s only circles (nodes) and links btw. But if you learn D3, you will need to check the element inspector ( i prefer use chrome). Why? Because it will help us to make selection. As you see on D3, we just write code like this :

var svg = d3.select("svg"),
width = +svg.attr("width"), height = +svg.attr("height");  

var node = g.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(nodes_data)
.enter()
.append("circle")
.attr("r", radius)
.attr("fill", circleColour);

and the result is as you can see above ( on the picture), but then we check inspector, and we got like this :

circle d3

Elements

You can see the <g> tag , it is the SVG Group Element is a container that contains all child SVG elements defined inside of it and that share the same attribute. In the example, it have 2 groups. One contains lines and the others contain circles. And there’s many circle elements that created with D3, we use .append("circle")and its populate the element as we can see in the element inspector.

D3 has two functions to make selections d3.select and d3.selectAll.

d3.select selects the first matching element whilst d3.selectAll selects all matching elements. Each function takes a single argument which specifies the selector string. Examples, we want to select all the circles, we can use d3.selectAll(“circle”); And when we use d3.select(“circle”); it will select the first matching element, only one, the first one. In my example, it is the line that i blocked. We can also select item by it class like d3.selectAll(“.classname”);

We can also updating the elements with functions, like this :

d3.selectAll('circle')
  .attr('cx', function(d, i) {
    return i * 100;
  });

The function typically accepts two arguments d and i. The first argument d is the joined data and i is the index of the element within the selection. If we want to update elements in a selection according to their position within the selection, we can use the iargument. For example to position some rect elements horizontally we can use: (http://d3indepth.com/selections/)

When i added events,  i add a function and i want to change radius of the element i clicked (for example) i can use “this“, so it will look like :

d3.select(this); and i can also modify element, like d3.select(this).attr('radius', 10);

d3 styling change radius

d3 styling change radius

We can also make selection like this:

// Add .selected class to 3rd circle
d3.select('circle:nth-child(3)')
	.classed('selected', true);

// Set checked property of checkbox
d3.select('input.robot-checkbox')
	.property('checked', true);

So it will just modify the element clicked, and change radius to 10.  You can also adding text, title, or changing the color, add borders etc, but i will write more about modifying element and styling on my next post ! See youu very sooon 🙂

Advertisements

D3.js : Modifying Elements

After selecetion, i would like to share about styling in D3.js. Modifying element atribut like change the circle radius, color, width, stroke, fill color etc, it means we change the style, so i called it styling.

I will make it so simple, so i have a circle like this :

var svg = d3.select(“svg”),
width = +svg.attr(“width”),
height = +svg.attr(“height”);

svg.append(“circle”) // attach a circle
.attr(“cx”, 200) // position the x
.attr(“cy”, 100) // position the y
.attr(“r”, 50) // set the radius
.style(“fill”, “red”); // set the fill

 

There’s some atribut  like x and y position, the radius and fill color. If we want no color just add .style(“fill”, “none”). And we can also add color like  (.style("fill", "rgb(255,0,0)");) or in hexadecimal (.style("fill", "#f00");)

Styles in D3:

  • fill
  • stroke
  • opacity
  • fill-opacity
  • stroke-opacity
  • stroke-width
  • stroke-dassharay
  • stroke-linecap
  • stroke-linejoin
  • writing-mode
  • glyph-orientation-vertical

I added some styles to the circle, and then it look like this :

 

d3.select(“circle”) // select a circle
.attr(“cx”, 200) // position the x
.attr(“cy”, 100) // position the y
.attr(“r”, 50) // set the radius
.style(“fill”, “red”) // set the fill colour
.style(“fill-opacity”, 0.4) // set fill opacity
.style(“stroke”, “blue”) // set the line color
.style(“stroke-width”, 3 ) // set the line width
.style(“stroke-dasharray”, (“10,3”)) // make the stroke dashed

Then, i tried to make lines and add some styles, looks like this:

svg.append(“line”) // attach a line
.style(“stroke”, “blue”) // colour the line
.style(“stroke-width”, 20) // adjust line width
.style(“stroke-linecap”, “butt”) // stroke-linecap type
.attr(“x1”, 100) // x position of the first end of the line
.attr(“y1”, 50) // y position of the first end of the line
.attr(“x2”, 300) // x position of the second end of the line
.attr(“y2”, 50); // y position of the second end of the line

svg.append(“line”) // attach a line
.style(“stroke”, “blue”) // colour the line
.style(“stroke-width”, 20) // adjust line width
.style(“stroke-linecap”, “round”) // stroke-linecap type
.attr(“x1”, 100) // x position of the first end of the line
.attr(“y1”, 100) // y position of the first end of the line
.attr(“x2”, 300) // x position of the second end of the line
.attr(“y2”, 100); // y position of the second end of the line

svg.append(“line”) // attach a line
.style(“stroke”, “blue”) // colour the line
.style(“stroke-width”, 20) // adjust line width
.style(“stroke-linecap”, “square”) // stroke-linecap type
.attr(“x1”, 100) // x position of the first end of the line
.attr(“y1”, 150) // y position of the first end of the line
.attr(“x2”, 300) // x position of the second end of the line
.attr(“y2”, 150); // y position of the second end of the line

Attrributes in D3:

      • xy ;
        Using the x and y attributes places the anchor points for these elements at a specified location. Of the elements that we have examined thus far, the rectangle element and the text element have anchor points to allow them to be positioned
      • x1x2y1y2

        • x1: The x position of the first end of the line as measured from the left of the screen.
        • y1: The y position of the first end of the line as measured from the top of the screen.
        • x2: The x position of the second end of the line as measured from the left of the screen.
        • y2: The y position of the second end of the line as measured from the top of the screen.
      • points
        The points attribute is used to set a series of points which are subsequently connected with a line and / or which may form the bounds of a shape. These are specifically associated with the polyline and polygonelements. Like the xy and x1x2y1y2 attributes, the coordinates are set from the top, left hand corner of the web page.
        The data for the points is entered as a sequence of x,y points in the following format;
        .attr("points", "100,50, 200,150, 300,50");
      • cxcy

        The cxcy attributes are associated with the circle and ellipse elements and designate the centre of each shape. The coordinates are set from the top, left hand corner of the web page.
        • cx: The position of the centre of the element in the x axis measured from the left side of the screen.
        • cy: The position of the centre of the element in the y axis measured from the top of the screen.
      • r, to set radius of the element
        .attr("5", "50");
      • rx, ry
        The rxry attributes are associated with the ellipse element and designates the radius in the x direction (rx) and the radius in the y direction (ry).
        • rx: The radius of the ellipse in the x dimension from the cxcy position to the perimeter of the ellipse.
        • ry: The radius of the ellipse in the y dimension from the cxcy position to the perimeter of the ellipse.
        • translate: Where the element is moved by a relative value in the x,y direction.
        • scale: Where the element’s attributes are increased or reduced by a specified factor.
        • rotate: Where the element is rotated about its reference point by an angular value.transform (translate(x,y), scale(k), rotate(a)) 
          The transform attribute is a powerful one which allows us to change the properties of an element in several different ways.
          .attr("transform", "translate(50,50)") // translate the circle
          .attr("transform", "scale(2)"); // scale the circle attributes

          The translate-rotate attribute will rotate an element and its attributes by a declared angle in degrees.

          svg.append("text") // append text
          .style("fill", "black") // fill the text with the colour black .attr("x", 200) // set x position of left side of text
          .attr("y", 100) // set y position of bottom of text
          .attr("dy", ".35em") // set offset y position .attr("text-anchor", "middle") // set anchor y justification .attr("transform", "rotate(10)") .text("Hello World"); // define the text to display
      • widthheight 

        width and height are required attributes of the rectangle element. width designates the width of the rectangle and height designates the height (If you’re wondering, I often struggle defining the obvious).

      • text-anchor

        The text-anchor attribute determines the justification of a text element
        Text can have one of three text-anchor types;
        • start where the text is left justified.
        • middle where the text is centre justified.
        • end where the text is right justified
      • dxdy
        dx and dy are optional attributes that designate an offset of text elements from the anchor point in the x and y dimension . There are several different sets of units that can be used to designate the offset of the text from an anchor point. These include em which is a scalable unit, px (pixels), pt (points (kind of like pixels)) and %(percent (scalable and kind of like em))
      • lenghtAdjust

        The lengthAdjust attribute allows the textLength attribute to have the spacing of a text element controlled to be either spacing or spacingAndGlyphs;
        • spacing: In this option the letters remain the same size, but the spacing between the letters and words are adjusted.
        • spacingAndGlyphs: In this option the text is stretched or squeezed to fit
      • textLength
        The textLength attribute adjusts the length of the text to fit a specified value.

And also i have summaries :

Source :

http://www.d3noob.org/2014/02/styles-in-d3js.html

http://www.d3noob.org/2014/02/attributes-in-d3js.html

http://www.tutorialsteacher.com/d3js

It’s a very useful site btw, i highly recommend you to visit the site if you wanna learn about D3 (as beginner). But so sad that the last post on that site in 2016. There’s some version D3, try the latest (V4)

Shiny from R Studio

Shiny is an R package that makes it easy to build interactive web apps straight from R. You can host standalone apps on a webpage or embed them in R Markdown documents or build dashboards. You can also extend your Shiny apps with CSS themes, htmlwidgets, and JavaScript actions. (http://shiny.rstudio.com/)

At least, that’s the sentences i read when i start to googling about Shiny. And, R is a language and environment for statistical computing and graphics. It is a GNU project which is similar to the S language and environment which was developed at Bell Laboratories (formerly AT&T, now Lucent Technologies) by John Chambers and colleagues. R can be considered as a different implementation of S. There are some important differences, but much code written for S runs unaltered under R. (https://www.r-project.org/about.html)

Shiny Features :

  • Build useful web applications with only a few lines of code—no JavaScript required.
  • Shiny applications are automatically “live” in the same way that spreadsheets are live. Outputs change instantly as users modify inputs, without requiring a reload of the browser.
  • Shiny user interfaces can be built entirely using R, or can be written directly in HTML, CSS, and JavaScript for more flexibility.
  • Works in any R environment (Console R, Rgui for Windows or Mac, ESS, StatET, RStudio, etc.)
  • Attractive default UI theme based on Twitter Bootstrap.
  • A highly customizable slider widget with built-in support for animation.
  • Pre-built output widgets for displaying plots, tables, and printed output of R objects.
  • Fast bidirectional communication between the web browser and R using the websockets package.
  • Uses a reactive programming model that eliminates messy event handling code, so you can focus on the code that really matters.
  • Develop and redistribute your own Shiny widgets that other developers can easily drop into their own applications (coming soon!).
    (http://rstudio.github.io/shiny/tutorial/)

Well, as i am currently learning about data visualization, so i hv to learn about some tools to create graph for visualisizing the data. There are some tools i can use, but i still learn of it. So many things i should learn, and i think i can start it. But, may be i just need time to understand it all. Well, and this is would be my first post about R and it’s Shiny project. I’ll write some post later and give you some sample code, cheers!

Dynamic Dependence Select Box using JQuery

Hi, there, sudah lammaaa sekali sejak saya posting terakhir kali disini, well, dikarenakan banyak sekali hal.

Kali ini, saya ingin posting yang ringan saja, a simple trick buat bikin dynamic dependence select box, disini saya akan pakai jquery, ajax. Ini sebenernya simple banget and soo many example out there, but, i’ll write on my own XD

Nah, dependence select box itu banyak sekali digunakan, contohnya adalah saat memilih alamat, misalnya select box negara, kemudian province, kota, yang dibuat dependence untuk memudahkan user. Misal, di Indonesa saat pilih Provinsi Jawa Tengah, maka select box Kota/Kabupaten hanya akan berisi Kota/Kabupaten di provinsi tersebut, dst sampai kecamatan, kelurahan dst. That’s very simple;

HTML :

Select Box Provinsi (misalnya)

Provinsi:<select name="prov" class="form-control" id="provinsi">

<option value=''>Pilih Provinsi </option>

</select>

Select Box Kabupaten (misalnya) :

Kabupten:<select name="kab" class="form-control" id="kabupaten">

<option value=''>PilihKabupaten</option>

</select>

Event yang digunakan adalah on-change function, dimana fungsi ini akan dieksekusi each time the event is triggered. Bisa dituliskan dengan $(‘#provinsi’).on(‘change’,function(){-your code-}); atau cukup $(‘#provinsi’).change(function(){ -your code to execute-}); No prob, yang kedua adalah shortcut dari yang pertama ( berdasarkan yang saya baca di JQuery docs)

JQUERY :

$(‘#provinsi’).on(‘change’,function(){

var kd_kantor = $(this).val();

$(‘#kabupaten‘).val(“”);

var provinsi= document.getElementById(“provinsi”).value;

//remove option

$(‘#kabupaten‘) .find(‘option’) .remove() .end() .append(‘Please wait..’) ;

$.ajax({

type: ‘GET’,

url: ‘getDataKabupaten’,

data: {

provinsi: provinsi,

},

success: function(response){

var res = JSON.parse(response);

var data = res.data;

console.log(data.length);

// populate option

var optionList = ”;

if (data.length <1) { optionList = ‘- No Data -‘; }

else {

for (var i=0; i<data.length; i++) {

optionList += “<option value = “+data[i].id_kabupaten+”>”+data[i].nm_kabupaten+”</option>”;

}

}

$(‘#kabupaten’)
.find(‘option’)
.remove()
.end()
.append(optionList)
;

}

});

 

Contoh diatas  membuat satu request ke server menggunakan ajax yaitu ke “getDataKabupaten” , disini saya menggunakan service dengan java, kalian tentu bisa membuatnya dengan bahasa lainnya. Data yang saya dapatkan adalah JSON data yang berisi data kabupaten yang ada pada provinsi yang dipilih. Itu saja.

 

A very simple post 😦

Getting Auth with Cookie vs Token | AngularJS

These last few days, i’ve been working with AngularJS, dealing with RESTFull-API concept in my back end. And now, i learn to get auth with AngularJS.
The scenario is, when user login, i’ll send username and password, server with validate user credentials and send the auth that must be saved and for the next request, i had send the auth. Ok, and it drives me into Cookies vs Token. Which one i’ll use?

My senior do some research and decided to try with cookie first. But, i still want to share about this matter.

Good articles is here : http://www.angulartutorial.net/2014/05/set-headers-for-all-http-calls-in.html and http://www.webdeveasy.com/interceptors-in-angularjs-and-useful-examples/

Ya, there some word about interceptors :

Interceptors allow you to:

  • Intercept a request by implementing the request function: This method is called before $http sends the request to the backend, so you can modify the configurations and make other actions. This function receives the request configuration object as a parameter and has to return a configuration object or a promise. Returning an invalid configuration object or promise that will be rejected, will make the $http call to fail.
  • Intercept a response by implementing the response function: This method is called right after $http receives the response from the backend, so you can modify the response and make other actions. This function receives a response object as a parameter and has to return a response object or a promise. The response object includes the request configuration, headers, status and data that returned from the backend. Returning an invalid response object or promise that will be rejected, will make the $http call to fail.
  • Intercept request error by implementing the requestError function: Sometimes a request can’t be sent or it is rejected by an interceptor. Request error interceptor captures requests that have been canceled by a previous request interceptor. It can be used in order to recover the request and sometimes undo things that have been set up before a request, like removing overlays and loading indicators, enabling buttons and fields and so on.
  • Intercept response error by implementing the responseError function: Sometimes our backend call fails. Other times it might be rejected by a request interceptor or by a previous response interceptor. In those cases, response error interceptor can help us to recover the backend call.

I found a good article here and here.

What are the benefits of using a token-based approach?

  • Cross-domain / CORS: cookies + CORS don’t play well across different domains. A token-based approach allows you to make AJAX calls to any server, on any domain because you use an HTTP header to transmit the user information.
  • Stateless (a.k.a. Server side scalability): there is no need to keep a session store, the token is a self-contanined entity that conveys all the user information. The rest of the state lives in cookies or local storage on the client side.
  • CDN: you can serve all the assets of your app from a CDN (e.g. javascript, HTML, images, etc.), and your server side is just the API.
  • Decoupling: you are not tied to a particular authentication scheme. The token might be generated anywhere, hence your API can be called from anywhere with a single way of authenticating those calls.
  • Mobile ready: when you start working on a native platform (iOS, Android, Windows 8, etc.) cookies are not ideal when consuming a secure API (you have to deal with cookie containers). Adopting a token-based approach simplifies this a lot.
  • CSRF: since you are not relying on cookies, you don’t need to protect against cross site requests (e.g. it would not be possible to <iframe> your site, generate a POST request and re-use the existing authentication cookie because there will be none).
  • Performance: we are not presenting any hard perf benchmarks here, but a network roundtrip (e.g. finding a session on database) is likely to take more time than calculating an HMACSHA256 to validate a token and parsing its contents.
  • Login page is not an special case: If you are using Protractor to write your functional tests, you don’t need to handle any special case for login.
  • Standard-based: your API could accepts a standard JSON Web Token (JWT). This is a standard and there are multiple backend libraries (.NET, Ruby, Java, Python, PHP) and companies backing their infrastructure (e.g. Firebase, Google, Microsoft). As an example, Firebase allows their customers to use any authentication mechanism, as long as you generate a JWT with certain pre-defined properties, and signed with the shared secret to call their API.

Ya, as you see, JSON Web Token is quite popular i think, and you can see some example here : https://auth0.com/learn/token-based-authentication-made-easy/

Create Simple Accordion with ionic and angular

Banyak trik bisa kita lakukan untuk membuat tampilan accordion, di jquery kita bisa tinggal pakai saja function yang ada. Nah kali ini saya mau share sedikit tentang ionic dan angular. Tapi kali ini saya melakukannya dengan ionic 1, karena memang sedang ada project dengan menggunakan framework ini meski pada beberapa post sebelumnya saya sempat ngeshare tentang ionic2, tenang, yang ionic 2 saya juga terus pakai kok, nanti akan saya share.

How to get start with Ionic 2

Choosing best mobile apps technology : native vs hybrid

About ionic creator

Ionic vs OnsenUI : UI Framework for Hybrid Mobile Apps 

How to install phonegap for android apps development

Kali ini, saya membuat tampilan accordion simple saja, saya tidak banyak cuma butuh 2, jadi untuk animasinya saya cukup pakai css. Saya menggunakan ng-show ini dari angular. Oke, langsung aja kita liat code nya

Sederhana, untuk header accordionnya saya cuma pakai list divider dari component ionic, tinggal saya modif sedikit seperti ini:

the html

<ion-item class=”item-icon-right item-divider”
ng-click=”toggleGroup(‘A’)”
ng-class=”{active: isGroupShown(‘A’)}”>
<i class=”icon” ng-class=”isGroupShown(‘A’) ? ‘ion-chevron-up icon-accessory’ : ‘ion-chevron-down icon-accessory'”></i>
List Group A
</ion-item>

<ion-list>

<!– ************************* LIST GROUP A *******************************************–>
<ion-item class=”item-remove-animate item-icon-right item-accordion” ng-repeat=”list in listdata” type=”item-text-wrap” ng-show=”isGroupShown(‘A’)” href=”#/detail”>
<h2>Barang {{list .name}}</h2>
<p>{{list .message}}</p>
<i class=”icon ion-chevron-right icon-accessory”></i>
</ion-item>
</ion-list>

 

itu untuk satu group, kalo mau nambah lagi tinggal tambahin code yang sama, cuma tinggal ganti nama grupnya aja itu misal jadi isGroupShown(‘B’). So its very simple, kalo mau yang lebih kompleks, bisa ja sih, but this is easier, hhaaaaaaa..

note : ini datanya saya ngambil dari service sederhana saja, cuma array :

.service(‘listdata’, function() {
return {
lists: [
{id: “1”,name : “A”,message: “Detail Informasi A”},
{id: “2”, name : “B”,message: “Detail Informasi B”},
{id: “3”, name : “C”,message: “Detail Informasi C”},
{id: “4”, name : “D”,message: “Detail Informasi D”},
{id: “5”, name : “E”,message: “Detail Informasi E”},
{id: “6”, name : “F”,message: “Detail Informasi F”}

],
getLists: function() {
return this.lists;
},
getList: function(listId) {
for(i=0;i<this.lists.length;i++) {
if(this.lists[i].id == listId) {
return this.lists[i];
}
}
}
}

 

okey, then the css; ini penting yah buat transisi pas itemnya dibuka dan ditutup, biar lebih halus, coba liat sendiri perbedannya yah, hapus aja line yang pertama dan bandingkan hasilnya..

.list .item.item-accordion {transition: 0.09s all linear;}
.list .item.item-accordion.ng-hide {line-height: 0px;}
.list .item.item-accordion.ng-hide-add,
.list .item.item-accordion.ng-hide-remove {display: block !important;}

 

and then the .js file tinggal taruh didalam controller nya saja:

$scope.shownGroup=null; //default nutup semua

$scope.isGroupShown = function(group) {
return $scope.shownGroup === group;
};
$scope.toggleGroup = function(group) {
if ($scope.isGroupShown(group)) {
$scope.shownGroup = null;
} else {
$scope.shownGroup = group;
}
};

 

Enjoyyy, atau kalian bisa mampir kesini -> https://codepen.io/ionic/pen/uJkCz

How to get start with Ionic 2

Now, i wanna share about how to start with ionic. Official site ; http://ionicframework.com/

Ionic 2 is still in beta release but, you may want to read about ionic 1 and 2 and should you upgrade to ionic 2 or not ->  here.

First of all you have to make sure this following things already installed to your computer :

  1. Android SDK
  2. Java JDK
  3. NodeJS
  4. AntJS
  5. Cordova Latest Version

And now, we’re ready to start about ionic. http://ionicframework.com/getting-started/

For you who just heard about ionic, you can visit my previos post about ionic right here.

We use Nodejs command line tools to run ionic command , you can read more here https://www.npmjs.com/package/ionic

  1. Install ionic
    $ npm install -g ionic@beta
  2. Create Project
    use –v2 to create ionic 2 project, if you do not add this line, it will install ionic 1 by default. ex : $ ionic start myApp ==> ionic 1 version

    $ ionic start myApp [template] --v2
    $ ionic start myApp tabs --v2 
    ionic create porject

    ionic create porject

    I can’t believe i’m having trouble when start ionic project, the installation is stuck on “installing npm packages…” this command try to call the npm packages source but i’ve been waiting for an hour and theres nothing changed. I terminated it, and then try to start a project test again and still the same. My friend, Hadi, wait for it, so long but end up with an error. My senior said, how about restart the PC? Then me and my friend doing that, and still failed. And then, we both try to uninstall the cordova, the ionic again and when start project it is still failed. We spent the day by doing that and still not working. I can’t believe i had something trouble like this, so frustating and finally,  i think this is about the connection -_- Okay, i start again this day. And i try to use my own connection instead of office’s. And i am get through it. Oh my god, i can’t belive, my senior said: ya, because office connection is too slow -_-

  3. Add platform
    $ cd myApp
    $ ionic platform add android
    
    $ ionic build android
    
    Oh, and let me show you my ionic info by run this command -> $ ionic info

    ionic info

    ionic info

  4. Emulate project
    $ ionic emulate android
    
    
  5. Run Project
    $ ionic run android
    
    
  6. Run in browsers
    $ ionic serve or $ ionic serve lab
    
    Next, i have to learn the components~ okay, noted! start from today yo! :D
  7. And here some commands that can help you :
    $ ionic g page detail -> will generate your page named 'detail' . A folder 'detail' and by contain detai.html, detail.js and detail.scss like this one :
    
    g page
    
    $ ionic g provider mydata -> will add new file named "mydata.js" under provider folder
    

    provider