2016-09-12 18 views
5

Tôi biết bạn có thể tự hỏi barchart tự làm? Tại sao không phải là thư viện hiện có? Tôi ghét sử dụng các tệp có 20.000 dòng mã trong khi chỉ cần 500 mã.Thêm truyền thuyết vào barchart tự tạo

Oh và thật thú vị :) Mục tiêu chính là tôi sẽ sử dụng tập lệnh này cho ứng dụng tôi sẽ thực hiện bằng Phonegap. Vì vậy, kích thước càng thấp thì càng tốt.

Vì vậy, ý tưởng là để đạt được những điều sau đây: enter image description here

tôi đã có thể để vẽ các quán bar, chắc chắn rằng họ đang có chiều rộng bằng nhau và có chiều cao của họ phụ thuộc vào chiều cao của phụ huynh thùng đựng hàng. Như bạn sẽ thấy trong mã bên dưới, tôi cũng đã thêm kích thước phông chữ vào các tùy chọn. Như một số biểu đồ sẽ mở rộng khoảng 300px chiều cao (mà sẽ được sử dụng mặc định 16px ví dụ). Và một số chỉ có 50px với kích thước phông chữ từ 12 trở xuống. Vì vậy, tôi đã giảm thanh ChartContainer bằng 3 x phông chữ (+ phần còn lại) để đảm bảo có đủ không gian cho phần trên cùng (số tiền) & dưới (chú thích + tiêu đề)

Bây giờ tôi không hoàn toàn chắc chắn cách thêm và tập trung số tiền. Tôi đã thử tìm kiếm các thư viện biểu đồ hiện có để kiểm tra xem tất cả các thư viện đã được hiển thị như thế nào, rất tiếc là tất cả chúng đều sử dụng các thùng chứa hoặc các vùng chứa SVG. Bất kỳ đề xuất?

/* dataset 
 
    ------------------ 
 

 
    add legends 
 
    add result/amount 
 
    add bottom-border: 8px extra to both sides? 
 
    add chart name 
 

 
*/ 
 

 
(function ($) { 
 

 
    var methods = { 
 
     init : function(options) { 
 
      return this.each(function() { 
 

 
       var $this = $(this), 
 
        dataset = options.dataset, 
 
        fontSize = options.fontSize, 
 
        widthOfContainer = $this.width(), 
 
        heightOfContainer = $this.height() - (3 * (fontSize + 4)), // make room for title (bottom), legend (bottom), amounts (top) 
 
        widthOfBar = parseInt(widthOfContainer/options.dataset.length) - 2, 
 
        bar; 
 

 
       $this.bind('draw', function(e) { 
 
        $this.empty(); 
 

 
        var maxValueInDataset = Math.max.apply(Math, dataset.map(function(o){return o.a;})), 
 
         heightPerUnit = parseInt(heightOfContainer/maxValueInDataset); 
 
        for (var i = 0; i < dataset.length; i++) { 
 
         bar = $(document.createElement('div')); 
 
         bar.addClass('bar'); 
 
         bar.css({ 
 
          'height': parseInt(dataset[i].a * heightPerUnit) + 'px', 
 
          'width': parseInt(widthOfBar) + 'px', 
 
          'margin-left': parseInt(i * 2 + i * widthOfBar) + 'px', 
 
          'bottom': 2 * (fontSize + 4) 
 
         }); 
 
         $this.append(bar); 
 
        } 
 
       }); 
 

 
       $this.trigger('draw'); 
 
      }); 
 
     }, 
 
     draw : function(n) { 
 
      $(this).trigger('draw'); 
 
     } 
 
    }; 
 

 
    $.fn.chart = function(methodOrOptions) { 
 
     if (methods[methodOrOptions]) { 
 
      return methods[ methodOrOptions ].apply(this, Array.prototype.slice.call(arguments, 1)); 
 
     } else if (typeof methodOrOptions === 'object' || ! methodOrOptions) { 
 
      // Default to "init" 
 
      return methods.init.apply(this, arguments); 
 
     } else { 
 
      $.error('Method ' + methodOrOptions + ' does not exist on jQuery.tooltip'); 
 
     } 
 
    }; 
 

 
    $(document).ready(function(){ 
 
     $('div.barchart').chart({ 
 
      // Add font-size? 
 
      fontSize: 14, 
 
      name: 'mana cost', 
 
      dataset: [ 
 
       {a: 2, label: '0'}, 
 
       {a: 8, label: '1'}, 
 
       {a: 9, label: '2'}, 
 
       {a: 4, label: '3'}, 
 
       {a: 7, label: '4'}, 
 
       {a: 3, label: '5'}, 
 
       {a: 1, label: '6'}, 
 
       {a: 1, label: '7'}, 
 
       {a: 2, label: '8'}, 
 
       {a: 5, label: '9'} 
 
      ] 
 
     }); 
 
    }); 
 
}(jQuery));
/* Barchart 
 
    ========================================================================== */ 
 

 
.barchart { 
 
    color: black; 
 
} 
 

 
/* Bar 
 
    ========================================================================== */ 
 

 
.bar { 
 
    position: absolute; 
 
    height: 0px; 
 
    width: 0px; 
 
    margin-left: 0px; 
 
    bottom: 0px; 
 
    background: black; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div style="padding: 20px;"> 
 
      <div class="barchart" style="height: 100px; position: relative"></div> 
 
     </div>

Trả lời

2

đẹp biểu đồ! Nó trông sạch sẽ. Tôi hiểu bạn muốn nói gì. Tôi đã dành hàng tháng cố gắng để thao tác bố trí của bxSlider sau đó tôi nhận ra đó là ít mã để viết của riêng tôi. Đây là một nỗ lực để trả lời truy vấn của bạn. Tôi đã làm cho nó có chiều rộng đáp ứng bằng cách sử dụng tỷ lệ phần trăm (đừng lo lắng; dễ dàng thay đổi lại), thêm một lớp css bổ sung cho chú giải, giá trị, và đếm và sửa đổi plugin của bạn để bao gồm tùy chọn tên của bạn (được gọi là chú giải) . Các bit này sau đó được định dạng và nối thêm. Hi vọng điêu nay co ich.

/* dataset 
 
    ------------------ 
 

 
    add legends 
 
    add result/amount 
 
    add bottom-border: 8px extra to both sides? 
 
    add chart name 
 

 
*/ 
 

 
(function ($) { 
 

 
    var methods = { 
 
     init : function(options) { 
 
      return this.each(function() { 
 

 
       var $this = $(this), 
 
        dataset = options.dataset, 
 
        fontSize = options.fontSize, 
 
        legend = options.name, 
 
        widthOfContainer = $this.width(), 
 
        heightOfContainer = $this.height() - (3 * (fontSize + 4)), // make room for title (bottom), legend (bottom), amounts (top) 
 
        widthOfBar = parseInt(widthOfContainer/options.dataset.length) - 2, 
 
        widthOfBarPer = (widthOfBar/widthOfContainer) *100, 
 
        bar; 
 

 
       $this.bind('draw', function(e) { 
 
        $this.empty(); 
 

 
        var maxValueInDataset = Math.max.apply(Math, dataset.map(function(o){return o.a;})), 
 
         heightPerUnit = parseInt(heightOfContainer/maxValueInDataset); 
 
        for (var i = 0; i < dataset.length; i++) { 
 
        \t \t var dataVal = dataset[i].a; 
 
         bar = $(document.createElement('div')); 
 
         bar.addClass('bar'); 
 
         bar.css({ 
 
          'height': parseInt(dataVal * heightPerUnit) + 'px', 
 
          'width': widthOfBarPer + '%', // percentages to make more responsive? 
 
          'margin-left': (i + i * widthOfBarPer) + '%', // no need to parseInt as you have already on widthOfBar. now your chart stretches with the width . 
 
          'bottom': 2 * (fontSize + 4) 
 
         }); 
 
         bar.append('<p class="count">'+ i +'</p>'); \t // defines the bar count, this could be dataset[i].label but if you just use i then you don't need to type it out for each bar? 
 
         bar.append('<p class="value">'+ dataVal +'</p>'); \t // defines the bar value 
 
         $this.append(bar); // adds the bar count 
 
        } 
 
        var chartHeight = $this.height(); 
 
        $('.bar .count').css({ bottom: fontSize - chartHeight * 0.5 }); 
 
        $('.bar .value').css({ bottom: chartHeight * 0.5 - fontSize }); 
 
        if(legend){ 
 
\t \t \t \t \t \t \t \t \t \t \t \t legend = '<p class="legend">'+legend+'</p>'; 
 
\t \t \t \t \t \t \t \t \t \t \t $this.append(legend); 
 
        //  $this.css({ border: '1px solid #f90'}); // temp to see the current chart size 
 
         $this.find('.legend').css({ top: chartHeight - fontSize }); 
 
        } 
 
       }); 
 

 
       $this.trigger('draw'); 
 
      }); 
 
     }, 
 
     draw : function(n) { 
 
      $(this).trigger('draw'); 
 
     } 
 
    }; 
 

 
    $.fn.chart = function(methodOrOptions) { 
 
     if (methods[methodOrOptions]) { 
 
      return methods[ methodOrOptions ].apply(this, Array.prototype.slice.call(arguments, 1)); 
 
     } else if (typeof methodOrOptions === 'object' || ! methodOrOptions) { 
 
      // Default to "init" 
 
      return methods.init.apply(this, arguments); 
 
     } else { 
 
      $.error('Method ' + methodOrOptions + ' does not exist on jQuery.tooltip'); 
 
     } 
 
    }; 
 

 
    $(document).ready(function(){ 
 
     $('div.barchart').chart({ 
 
      // Add font-size? 
 
      fontSize: 14, 
 
      name: 'mana cost', 
 
      dataset: [ 
 
       {a: 2, label: '0'}, 
 
       {a: 8, label: '1'}, 
 
       {a: 9, label: '2'}, 
 
       {a: 4, label: '3'}, 
 
       {a: 7, label: '4'}, 
 
       {a: 3, label: '5'}, 
 
       {a: 1, label: '6'}, 
 
       {a: 1, label: '7'}, 
 
       {a: 2, label: '8'}, 
 
       {a: 5, label: '9'} 
 
      ] 
 
     }); 
 
    }); 
 
}(jQuery));
/* Barchart 
 
    ========================================================================== */ 
 

 
.barchart { 
 
    color: black; 
 
} 
 

 
/* Bar 
 
    ========================================================================== */ 
 

 
.bar { 
 
    position: absolute; 
 
    height: 0px; 
 
    width: 0px; 
 
    margin-left: 0px; 
 
    bottom: 0px; 
 
    background: black; 
 
} 
 

 
.count, .value{ 
 
    z-index: 7; 
 
    position: absolute; 
 
    text-align: center; 
 
    width: 100%; 
 
} 
 

 
.legend{ 
 
    position: relative; 
 
    text-align: center; 
 
    width: 100%; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div style="padding: 20px;"> 
 
      <div class="barchart" style="height: 100px; position: relative"></div> 
 
     </div>

2

Thumbs up để tránh một lượng không cần thiết của mã — một barchart sạch là một ví dụ hoàn hảo của việc không cần một thư viện khổng lồ.

Nếu bạn sử dụng một <table> như cấu trúc cơ bản để tạo ra barchart của bạn từ, bạn sẽ dễ dàng truy cập vào các tùy chọn định dạng bạn muốn — kết quả là mã ít:

  • Một hàng cho các giá trị, một hàng cho các nhãn
  • Bars có thể được thực hiện bằng styling border-bottom của mỗi tế bào giá trị
  • văn bản có thể được tập trung trong tế bào bảng
  • Thêm một <caption> cho huyền thoại, trong đó tập trung b y mặc định và có thể dễ dàng đặt bên dưới bảng với thuộc tính caption-side
  • Tạo kiểu vertical-align thuộc tính của ô giá trị cho phép định vị trực tiếp trên các thanh (như trong bản trình bày bên dưới) hoặc xếp hàng trên đầu hình minh họa) — điều này được kiểm soát trong dòng 20 trong mã trình diễn js bên dưới.

Sau khi tất cả, một barchart chỉ là một hóa đơn của dữ liệu dạng bảng, do đó, sử dụng một bảng có ý nghĩa.

Một bản demo làm việc (trong khoảng 30 dòng js vani và một vài dòng css, mà bạn có thể dễ dàng thích ứng với cách tiếp cận jquery của bạn nếu cần):

function barchart(containerId, options) { 
 
    var i, 
 
     html, 
 
     valueRow = '', 
 
     labelRow = '', 
 
     data = options.dataset, 
 
     maxBarHeight = 60, /* in px, could be set from options */ 
 
     barWidth = 20,  /* in px, could be set from options */ 
 
     maxValue = Math.max.apply(
 
     Math, 
 
     data.map(function(o) { 
 
      return o.a; 
 
     }) 
 
    ); 
 
    for(i = 0; i < data.length; i++){ 
 
    labelRow += '<td>' + data[i].label + '</td>'; 
 
    valueRow += '<td style="border-bottom:' + 
 
     (data[i].a * maxBarHeight/maxValue) + 
 
     'px solid black;vertical-align:' + 
 
     'bottom' + /* set to 'top' to get value labels lined up */ 
 
     ';width: ' + 
 
     barWidth + 'px">' + 
 
     data[i].a + '</td>'; 
 
    } 
 
    html = '<table class="barchart" ' + 
 
    'style="font-size:' + options.fontSize + 'px">' + 
 
    '<caption>' + options.name + '</caption>' + 
 
    '<tr>' + valueRow + '</tr>' + 
 
    '<tr>' + labelRow + '</tr>' + 
 
    '</table>'; 
 
    document.getElementById(containerId) 
 
    .innerHTML = html; 
 
} 
 

 
/* create a barchart */ 
 

 
barchart('testdiv', { 
 
    fontSize: 14, 
 
    name: 'mana cost', 
 
    dataset: [ 
 
    {a: 2, label: '0'}, 
 
    {a: 8, label: '1'}, 
 
    {a: 9, label: '2'}, 
 
    {a: 4, label: '3'}, 
 
    {a: 7, label: '4'}, 
 
    {a: 3, label: '5'}, 
 
    {a: 1, label: '6'}, 
 
    {a: 1, label: '7'}, 
 
    {a: 2, label: '8'}, 
 
    {a: 5, label: '9'} 
 
    ] 
 
});
.barchart td{ 
 
    text-align: center; 
 
} 
 

 
.barchart{ 
 
    font-family: 'arial narrow', sans-serif; 
 
    caption-side: bottom; 
 
}
<div id="testdiv"></div>

+0

isn này' t xấu của một câu trả lời hoặc! cảm ơn, sẽ xem xét nó. – Goowik

Các vấn đề liên quan