자바스크립트 Hack

ipython notebook과 ipynb 모두에서 javascript를 정상작동하게 만들기 위한 hack.

In [233]:
%%javascript

// Setup Javascript playground
window.get_element = function(el){
    return (el !== undefined) ? el[0] : $('script').last().parent()[0];
};

element = undefined;

// Define external scripts
require.config({
    paths: {
        d3: "http://d3js.org/d3.v3.min"
    }
});

5.2.3 DOM 문서요소 선택하기

In [251]:
%%javascript

(function(){
    var target = get_element(element);

    require(['d3'], function() {
        d3.select(target)
          .selectAll("p")
          .data([1,2,3,4,5])
          .enter()
          .append("p")
          .text("New paragraph!");
    });
})();

6.4 막대 차트 만들기

In [252]:
%%javascript

(function(){
    var target = get_element(element);

    require(['d3'], function() {
        var w = 500;
        var h = 100;

        var dataset = d3.range(20);

        var svg = d3.select(target)
            .append('svg')
            .attr('width', w)
            .attr('height', h);

        svg.selectAll('rect')
            .data(dataset)
            .enter()
            .append('rect')
            .attr('x', 0)
            .attr('y', 0)
            .attr('width', 20)
            .attr('height', 100);
    });
})();
In [253]:
%%javascript

(function(){
    var target = get_element(element);

    require(['d3'], function() {
        var w = 500;
        var h = 100;

        var dataset = d3.range(20);

        var svg = d3.select(target)
            .append('svg')
            .attr('width', w)
            .attr('height', h);

        svg.selectAll('rect')
            .data(dataset)
            .enter()
            .append('rect')
            .attr('x', function(d, i){  // x 위치 차례대로 구분해주기
                return i * 21;
            })
            .attr('y', 0)
            .attr('width', 20)
            .attr('height', 100);
    });
})();
In [254]:
%%javascript

(function(){
    var target = get_element(element);

    require(['d3'], function() {
        var w = 500;
        var h = 100;

        // 데이터 개수 늘리기
        var dataset = d3.range(24);

        var svg = d3.select(target)
            .append('svg')
            .attr('width', w)
            .attr('height', h);

        svg.selectAll('rect')
            .data(dataset)
            .enter()
            .append('rect')
            // x 위치 차례대로 구분해주기
            .attr('x', function(d, i){ 
                return i * w / dataset.length;
            })
            .attr('y', 0)
            .attr('width', 20)
            .attr('height', 100);
    });
})();
In [257]:
%%javascript

(function(){
    var target = get_element(element);

    require(['d3'], function() {
        var w = 500;
        var h = 100;

        // 데이터 개수 줄이기
        var dataset = d3.range(5); 

        var svg = d3.select(target)
            .append('svg')
            .attr('width', w)
            .attr('height', h);

        svg.selectAll('rect')
            .data(dataset)
            .enter()
            .append('rect')
            .attr('x', function(d, i){
                 return i * w / dataset.length;
            })
            .attr('y', 0)
            .attr('width', 20)
            .attr('height', 100);
    });
})();
In [258]:
%%javascript

(function(){
    var target = get_element(element);

    require(['d3'], function() {
        var createGraph = function(data_num){
            var w = 500;
            var h = 100;

            // 막대 간격 변수 추가
            var barPadding = 1;

            var dataset = d3.range(data_num); 

            var svg = d3.select(target)
                .append('svg')
                .attr('width', w)
                .attr('height', h);

            svg.selectAll('rect')
                .data(dataset)
                .enter()
                .append('rect')
                .attr('x', function(d, i){
                     return i * w / dataset.length;
                })
                .attr('y', 0)
                // 막대 간격 동적으로 조절
                .attr('width', function(d, i){
                    return w / dataset.length - barPadding;
                })
                .attr('height', 100);
        }

        createGraph(100);
        createGraph(5);
    });
})();
In [260]:
%%javascript

(function(){
    var target = get_element(element);

    require(['d3'], function() {
        var w = 500;
        var h = 100;

        var barPadding = 1;

        var dataset = d3.range(20); 

        var svg = d3.select(target)
            .append('svg')
            .attr('width', w)
            .attr('height', h);

        svg.selectAll('rect')
            .data(dataset)
            .enter()
            .append('rect')
            .attr('x', function(d, i){
                 return i * w / dataset.length;
            })
            .attr('y', 0)
            .attr('width', function(d, i){
                return w / dataset.length - barPadding;
            })

            // 높이 데이터와 연동
            .attr('height', function(d){
                return d;
            });
    });
})();
In [261]:
%%javascript

(function(){
    var target = get_element(element);

    require(['d3'], function() {
        var w = 500;
        var h = 100;

        var barPadding = 1;

        var dataset = d3.range(20); 

        var svg = d3.select(target)
            .append('svg')
            .attr('width', w)
            .attr('height', h);

        svg.selectAll('rect')
            .data(dataset)
            .enter()
            .append('rect')
            .attr('x', function(d, i){
                 return i * w / dataset.length;
            })
            .attr('y', 0)
            .attr('width', function(d, i){
                return w / dataset.length - barPadding;
            })
            .attr('height', function(d){
                // 보기 좋게 높이 * 4
                return d * 4;
            });
    });
})();
In [262]:
%%javascript

(function(){
    var target = get_element(element);

    require(['d3'], function() {
        var w = 500;
        var h = 100;

        var barPadding = 1;

        var dataset = d3.range(20); 

        var svg = d3.select(target)
            .append('svg')
            .attr('width', w)
            .attr('height', h);

        svg.selectAll('rect')
            .data(dataset)
            .enter()
            .append('rect')
            .attr('x', function(d, i){
                 return i * w / dataset.length;
            })
            .attr('y', 0)
            .attr('width', function(d, i){
                return w / dataset.length - barPadding;
            })
            .attr('height', function(d){
                return d * 4;
            })
            // 막대에 색 입히기
            .attr('fill', 'teal');
    });
})();
In [263]:
%%javascript

(function(){
    var target = get_element(element);

    require(['d3'], function() {
        var w = 500;
        var h = 100;

        var barPadding = 1;

        var dataset = d3.range(20); 

        var svg = d3.select(target)
            .append('svg')
            .attr('width', w)
            .attr('height', h);

        svg.selectAll('rect')
            .data(dataset)
            .enter()
            .append('rect')
            .attr('x', function(d, i){
                 return i * w / dataset.length;
            })
            .attr('y', 0)
            .attr('width', function(d, i){
                return w / dataset.length - barPadding;
            })
            .attr('height', function(d){
                return d * 4;
            })
            // 막대에 동적으로 색 입히기
            .attr('fill', function(d){
                return 'rgb(0, 0,' + (d * 10) + ')';
            });
    });
});
In [264]:
%%javascript

(function(){
    var target = get_element(element);

    require(['d3'], function() {
        var w = 500;
        var h = 100;

        var barPadding = 1;

        var dataset = d3.range(20); 

        var svg = d3.select(target)
            .append('svg')
            .attr('width', w)
            .attr('height', h);

        svg.selectAll('rect')
            .data(dataset)
            .enter()
            .append('rect')

            // attr에 한꺼번에 속성 지정하기
            .attr({
                x: function(d, i) { return i * w / dataset.length; },
                y: function(d) { return h - (d * 4) },
                width: w / dataset.length - barPadding,
                height: function(d) { return d * 4 },
                fill: function(d) { return 'rgb(0, 0,' + (d * 10) + ')'}
            })
    });
})();
In [265]:
%%javascript

window.dataset = [5, 10, 13, 19, 21, 25, 22, 18, 15, 13, 
                    11, 12, 15, 20, 18, 17, 16, 18, 23, 25]

window.draw_graph = function(el, callback){
    var target = get_element(el);

    require(['d3'], function() {
        var w = 500;
        var h = 100;

        var barPadding = 1;

        var dataset = window.dataset; 

        var svg = d3.select(target)
            .append('svg')
            .attr('width', w)
            .attr('height', h);

        svg.selectAll('rect')
            .data(dataset)
            .enter()
            .append('rect')

            // attr에 한꺼번에 속성 지정하기
            .attr({
                x: function(d, i) { return i * w / window.dataset.length; },
                y: function(d) { return h - (d * 4) },
                width: w / dataset.length - barPadding,
                height: function(d) { return d * 4 },
                fill: function(d) { return 'rgb(0, 0,' + (d * 10) + ')'}
            })
        
        if(callback !== undefined){
            callback(svg, w, h)
        }
    });
};
In [266]:
%%javascript

draw_graph(element);
In [267]:
%%javascript

draw_graph(element, function(svg, w, h){
    // Text Label 추가하기
    svg.selectAll('text')
        .data(window.dataset)
        .enter()
        .append('text')
        .text(function(d){
            return d;
        })
        .attr('x', function(d, i){
            return i * (w / dataset.length);
        })
        .attr('y', function(d){
            return h - (d * 4);
        })
});
In [268]:
%%javascript

draw_graph(element, function(svg, w, h){

    svg.selectAll('text')
        .data(window.dataset)
        .enter()
        .append('text')
        .text(function(d){
            return d;
        })
        .attr('x', function(d, i){
            // 5 더하기
            return i * (w / dataset.length) + 5;
        })
        .attr('y', function(d){
            // 15 더하기
            return h - (d * 4) + 15;
        })
});
In [269]:
%%javascript

draw_graph(element, function(svg, w, h){

    svg.selectAll('text')
        .data(window.dataset)
        .enter()
        .append('text')
        .text(function(d){
            return d;
        })
        .attr('x', function(d, i){
            return i * (w / dataset.length) + 5;
        })
        .attr('y', function(d){
            return h - (d * 4) + 15;
        })
    
        // Font 스타일링
        .attr('font-family', 'sans-serif')
        .attr('font-size', '11px')
        .attr('fill', 'white')
});
In [270]:
%%javascript

draw_graph(element, function(svg, w, h){
    var barPadding = 1;

    svg.selectAll('text')
        .data(window.dataset)
        .enter()
        .append('text')
        .text(function(d){
            return d;
        })
    
        // 각 막대의 왼쪽 끝과 막대 폭의 절반 값을 더하도록 바꿈
        .attr('x', function(d, i){
            return i * (w / dataset.length) + (w / dataset.length - barPadding) / 2;
        })
    
        // 15 -> 14
        .attr('y', function(d){
            return h - (d * 4) + 14;
        })
        .attr('font-family', 'sans-serif')
        .attr('font-size', '11px')
        .attr('fill', 'white')
    
        // text-anchor 속성 추가
        .attr('text-anchor', 'middle')
});