2016-09-12 31 views
5

Muhtemelen kendine özgü barchart'ı merak ettiğinizi biliyor musunuz? Neden mevcut bir kütüphane değil? Ben sadece 500 gerekli iken 20000 satır kod ile dosyaları kullanmaktan nefret ediyorum.Kendi oluşturduğunuz barchart'a efsaneler ekleme

Oh ve eğlenceliydi :) Ana hedef, Phonegap kullanarak yapacağım bir uygulama için bu senaryoyu kullanacağım. Böylece boyut ne kadar düşükse o kadar iyidir. enter image description here

Ben ebeveynin yüksekliğine bağlıdır onlar eşit genişliktedir emin olun, barlar çizmek mümkün ve onların yüksekliğe sahip ettik:

Yani fikri şu elde etmektir bir kap. Aşağıdaki kodda göreceğiniz gibi, seçeneklere yazı tipi boyutu da ekledim. Bazı grafikler 300px'lik bir yükseklik kadar genişleyeceğinden (örneğin varsayılan 16px'i kullanacaklardır). Ve sadece 12 veya daha az font boyutuna sahip 50px. Bu yüzden üst için yeterli alan (miktarlar) & alt (efsaneler + başlık)

Şimdi nasıl ekleneceği tamamen emin değilim olduğundan emin olmak için 3 x fontSize (+ dinlenme) tarafından çubuk ChartContainer azaltılmış ve miktarları ortalayın. Tüm bunların nasıl oluşturulduğunu kontrol etmek için varolan grafik kitaplıklarını aramayı denedim, ne yazık ki hepsi kundakçıları veya SVG kaplarını kullanıyorlar. Baska öneri?

/* 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>

cevap

2

Güzel grafik! Temiz görünüyor. Ne demek istediğini biliyorum. Ayları bxSlider'ın düzenini değiştirmeye çalışarak geçirdim, sonra kendi yazmam için daha az kod olduğunu fark ettim. İşte, sorgunuzu cevaplama girişimi. Yüzdeleri kullanarak yanıtı genişlettim (endişelenmeyin; geri dönüşü kolay), lejant, değerler ve sayım için ekstra bir css sınıfı eklediniz ve adınızı eklemek için eklentinizi değiştirdiler (efsane olarak adlandırılır) . Bu bitler daha sonra sadece biçimlendirilmiş ve eklenmiştir. Bu yardımcı olur umarım.

/* 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

Başparmak yukarı kod — gereksiz miktarda önlemek için temiz bir barchart büyük kütüphanesi gerek duyulmayan mükemmel bir örneğidir. Eğer adresinin barchart oluşturmak için temel yapı olarak bir <table> kullanırsanız

, size — az kod ile sonuçlanan istediğiniz biçimlendirme seçeneklerine kolayca erişebilirsiniz: değerler için

  • Bir satır, bir satır için
  • bar b ortalanır gösterge için bir <caption> ekleme her değer hücre
  • Metin tablo hücreler içinde merkezlenebilir
  • ait border-bottom şekillendirme yapılabilir etiketler y varsayılan ve caption-side özelliği
  • ile tablonun altına kolayca yerleştirilir. Değer hücrelerinin vertical-align özelliğinin stilize edilmesi, değerlerin doğrudan çubukların üzerine yerleştirilmesine izin verir (aşağıdaki demoda olduğu gibi) veya üstte dizilmiş olarak resim) — bu, aşağıdaki js demo kodunda hat 20'de kontrol edilir.

Sonuçta, bir çizelge tablo verilerinin yalnızca bir vizualizasyonudır, bu nedenle bir tablo kullanmak anlamlıdır.

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

Bu hiç: (yaklaşık 30 vanilya js hatları ve gerekirse kolayca jquery yaklaşımına uyum sağlayabilir css, birkaç satır içinde)

bir çalışma demo Bir cevap da yok! teşekkürler, bir göz atacağız. – Goowik