2013-04-25 1 views
0

플롯 I d3에 새로 추가되었으며 자바 스크립트에도 새로 도입되었습니다. 대부분의 경험은 파이썬과 같습니다. 나는 최근에 도서에있는 자습서를 갔다 대화 형 데이터 시각화 : 웹에 대한 Scott Murray의 막대 차트 작성. 튜토리얼을 완료하는 데는 문제가 없었지만 책에서 취하는 접근법은 전역 변수를 사용하는 대부분 절차 적으로 보인다. 비슷한 차트를 만들고 싶지만 변수를 캡슐화하고 코드를 재사용하여 코드를 반복하지 않아도 하나의 스크립트에서 여러 차트를 생성 할 수있게하려면 객체 지향 접근 방식을 사용하십시오. 사람이 작동하지 않는 이유를 알고 않습니다d3에서 객체 지향 접근 방식을 사용하여 가로 막 대형 차트를 생성하려고 시도했습니다.

 function d3Chart(id, data, width, height, padding) { 
      this.id = id 
      this.data = data 
      this.width = width 
      this.height = height 
      this.padding = padding 
      this.svg = d3.select("body") 
       .append("svg") 
       .attr("width", width) 
       .attr("height", height) 
       .attr("class", "chart") 
       .attr("id". this.id); 
      this.yscale = d3.scale.linear() 
       .domain([0, d3.max(data)]) 
       .range([h - padding, padding]) 
      this.xscale = d3.scale.ordinal() 
       .domain(d3.range(data.length)) 
       .rangeRoundBands([padding,w-padding], 0.05) 
     }; 

     d3Chart.prototype.rect = function() { 

      this.rect = this.svg.selectAll("rect") 
       .data(this.data) 
       .enter() 
       .append("rect"); 
     } 

     d3Chart.prototype.plot = function() { 

      this.rect.attr("x", function(d, i) { 
        return this.xscale(i); 
       }) 
       .attr("y", function (d) { 
        return this.yscale(d); 
       }) 
       .attr("width", this.xscale.rangeBand()) 
       .attr("height", function(d) { 
        return this.height - this.padding - this.yscale(d); 
       }) 
       .attr("fill", function(d) { 
        return "rgb(" + (100 - d) + ", 0, " + (d*10) + ")"; 
       }); 
      } 

     var chart = new d3Chart("chart1", [5, 15, 10, 30, 20, 45, 15, 10, 5], 600, 400, 40); 
     chart.rect() 
     chart.plot() 

나는 내가 잘못 아주 간단 뭔가가있을거야, 또는이 심지어 경우 : 이것은 내가 운이없이 지금까지 시도한 것입니다 올바른 접근 방식을 취할 것인가? 어떤 도움이라도 대단히 감사 할 것입니다. 감사.

+0

드미트리 소 슈니 코브 (Dmitry Soshnikov)는 읽을만한 가치가있는 Javascript의 메커니즘에 대해 매우 짧고 감미로운 설명 (http://dmitrysoshnikov.com/ecmascript/javascript-the-core/)을 썼습니다. 대부분의 OOP 필요성은 변수가 설정되고 클로저 캡슐화 된 함수 내에서 함수를 반환하여 해결할 수 있습니다. 기본 객체를 확장해야하는 경우 [Object.create] (https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/create) 및 Object.defineProperty 메소드를 살펴보십시오. –

답변

1

코드의 첫 번째 문제는 몇 가지 오타가있는 것입니다. , 대신 .이고 height 대신 h 인 것입니다. 두 번째 문제는 모든 내용을 this의 속성으로 만들고 있다는 점입니다. 다른 컨텍스트에서는 다릅니다. 예를 들어,

this.rect.attr("x", function(d, i) { 
       return this.xscale(i); 
      }) 

에 두 this 다른 개체를 참조 - 두 번째 경우 this에 당신이에서 작동하고 당신이 언급하고있는 속성이없는 실제 DOM 요소입니다.

따라서 모든 것을 window과 같은 전역 개체의 특성에 저장해야합니다. 이것은 물론 전역 변수를 사용하는 것보다 낫지 않습니다. 보다 객체 지향적 인 접근을 위해서는 모든 정보를 담고있는 객체를 생성하고 전달해야하며, 객체에 대해 호출 할 수있는 메소드를 구현해야합니다.

고정 코드를 jsfiddle here에 넣었습니다.

+0

감사합니다. 매우 도움이됩니다. 내가 말했듯이, 나는 자바 스크립트에 익숙하지 않아서 여전히 "this"키워드에 대해 내 마음을 감싸는 데 어려움을 겪고있다. –

+0

당신은 "더 객체 지향적 인 접근을 위해서는 모든 정보를 담고있는 객체를 생성하고이를 전달하거나 객체를 호출 할 수있는 메소드를 구현해야합니다." 이것에 대한보다 구체적인 예가 있습니까? 변수를 "window"보다는 svg 요소에 바인딩 할 수 있습니까? –

+0

내가 말하고자하는 것은 특성에 사용할 사용자 지정 개체 (즉, 일반 개체)를 만드는 것입니다. 변수를 SVG 요소에 바인딩하는 것은 좋은 생각이 아닙니다. –

관련 문제