2012-11-06 12 views
5

W poniższym kodzie extjs 4.1.1a znajduje się przykładowy wykres liniowy. Teraz muszę podświetlić część tego wykresu na danym min i max timestamp.Wyróżnij część wykresu liniowego extjs4

{'xtype' : 'chart', 
'store' : 'ChartData', 
'height' : '100%', 
'width' : '100%', 
'legend' : {'position' : top}, 
'axes': [{ 
    'title': 'Power', 
    'type': 'Numeric', 
    'position': 'left', 
    'fields': ['power'] 
},{ 
    'title': 'Timestamp', 
    'type': 'Numeric', 
    'position': 'bottom', 
    'fields': ['timestamp'], 
    'minorTickSteps': 3 
}], 
'series': [{ 
    'type': 'line', 
    'fill': true, 
    'axis' : 'left', 
    'xField': 'timestamp', 
    'yField': 'power' 
}]} 

Przeszukałem forum sencha i nie znalazłem nic szczególnego, co spełnia moje wymagania. Na razie udało mi się zmienić kolor punktów na wykresie liniowym z niestandardowym rendererem.

'renderer': function(sprite, record, attr, index, store) { 
var item = store.getAt(index); 
if(item != undefined && (item.get('timestamp') < startdate || item.get('timestamp') > enddate)){ 
    return Ext.apply(attr, {'fill': '#00cc00', 'stroke-width': 3, 'radius': 4}); 
}else{ 
    return Ext.apply(attr, {'fill': '#ff0000', 'stroke-width': 3, 'radius': 4}); 
}} 

Ale nie znalazłem sposobu na zmianę koloru pod linią. Jakieś sugestie na ten temat?

AKTUALIZACJA - Praca w porządku teraz

wdrożyć rozwiązanie oparte na odpowiedź udzieloną przez Colombo.

doCustomDrawing: function() {: function (p){ 
var me = this, chart = me.chart; 
if(chart.rendered){ 
    var series = chart.series.items[0]; 
    if (me.groupChain != null) { 
     me.groupChain.destroy(); 
     me.groupChain = null; 
    } 
    me.groupChain = Ext.create('Ext.draw.CompositeSprite', { 
     surface: chart.surface 
    }); 
    if(series != null && series.items != null){ 
     var surface = chart.surface; 
     var pathV = 'M'; 
     var first = true; 
     // need first and last x cooridnate 
     var mX = 0,hX = 0; 
     Ext.each(series.items, function(item){ 
      var storeItem = item.storeItem, 
        pointX = item.point[0], 
        pointY = item.point[1]; 
      // based on given startdate and enddate start collection path coordinates 
      if(!(storeItem.get('timestamp') < startdate || storeItem.get('timestamp') > enddate)){ 
       if(hX<pointX){ 
        hX = pointX; 
       } 
       if(first){ 
        first = false; 
        mX = pointX; 
        pathV+= + pointX + ' ' + pointY; 
       }else{ 
        pathV+= ' L' + pointX + ' ' + pointY; 
       } 
      } 
     }); 
     var sprite = Ext.create('Ext.draw.Sprite', { 
      type: 'path', 
      fill: '#f00', 
      surface: surface, 
      // to draw a sprite with the area below the line we need the y coordinate of the x axe which is in my case items[1] 
      path : pathV + ' L'+ hX + ' ' + chart.axes.items[1].y + ' L'+ mX + ' ' + chart.axes.items[1].y + 'z' 
     }); 
     me.groupChain.add(sprite); 
     me.groupChain.show(true); 
    } 
}} 

To wygląda naprawdę dobrze i ma efekt miałem nadzieję i w przypadku zmiany rozmiaru kontenera nowe ikonki jest usunięte z wykresu. Po raz kolejny do Colombo.

+1

Trzeba zachować odniesienie do ikonki i zniszczyć je przed utworzeniem go ponownie. Sprawdź mój kod ponownie. – jorel

Odpowiedz

1

Można to zaimplementować. Oto, jak bym to zrobił.

1. Dodawanie słuchacza do afterrender imprezy dla series.

listeners: { 
       afterrender: function (p) { 
        this.doCustomDrawing(); 
       }, 
       scope: me 
} 

2. Tworzenie CompositeSprite

doCustomDrawing: function() { 
    var me = this, chart = me.chart; 

    if (chart.rendered) { 
     var series = chart.series.items[0]; 
     if (me.groupChain != null) { 
      me.groupChain.destroy(); 
      me.groupChain = null; 
     } 

     me.groupChain = Ext.create('Ext.draw.CompositeSprite', { 
      surface: chart.surface 
     }); 

     // Draw hilight here 
     Ext.each(series.items, function (item) { 
      var storeItem = item.storeItem, 
       pointX = item.point[0], 
       pointY = item.point[1]; 

      //TODO: Create your new line sprite using pointX and pointY 
      // and add it to CompositeSprite me.groupChain 


     }); 

     me.groupChain.show(true); 
    } 
}, 
+0

Rozwiązanie działa dobrze dla mnie.Jedynym problemem jest to, że w przypadku zmiany rozmiaru pojemnika, ikonka nie jest usuwana z wykresu i pozostaje w tym samym miejscu i zostanie przerysowana jako nowa ikonka we właściwej pozycji. Czy znasz sposób na obejście tego? – everald

+1

Upewnij się, że stary element CompositeSprite został zniszczony przed utworzeniem nowego. – jorel

+0

Tak po kilku próbach i błędach zauważyłem różnicę między moim pierwszym rozwiązaniem a twoją odpowiedzią. Teraz wszystko wydaje się działać. dzięki – everald

0

Nie ma "wbudowanego" sposobu, aby to osiągnąć. Prawdopodobnie napotykasz na pewne trudności, ponieważ "podświetlenie" wykresu liniowego oznacza obecnie coś zupełnie innego w interfejsie API ExtJS. Zwykle odnosi się to do odznaczania linii i znaczników pogrubieniem, gdy najedziesz myszą na serię danych.

Jednak twój pomysł brzmi interesująco, może będę potrzebował tego użyć w projekcie, który wymyśliłem.

Nie mam teraz czasu, aby opracować dokładny kod, ale można to zrobić, tworząc prostokątny sprite i dodając go do wykresu surface property.

Możesz to zrobić nawet po tym, jak wszystkie wykresy zostały wyrenderowane przy użyciu metody , zgodnie z opisem w dokumentach w dokumencie here.

Będziesz musiał wymyślić logikę określającą szerokość i położenie, jeśli dobrze zapamiętam interfejs API wykresu, powinieneś być w stanie wyodrębnić współrzędne x (położenie poziome) poszczególnych rekordów przez łowienie w obrębie właściwości itemsExt.chart.series.Line Obiekt wewnątrz wykresu.

Wysokość podświetlenia powinna być prosta - wystarczy odczytać wysokość wykresu.

Powiązane problemy