2012-04-02 3 views
2

두 줄 사이의 음영을 지원하는 JavaScript 차트 라이브러리를 찾고 있습니다. ChartDirector는 이것을 매우 잘 처리하지만 (자세한 내용은 http://www.advsofteng.com/gallery_line2.html - 겹침 색), 대화 형 차트 라이브러리가 더 필요합니다.두 줄 사이의 음영 영역을 처리하는 JavaScript 차트 라이브러리

다양한 JavaScript 라이브러리를 살펴 보았습니다. FLOT와 Highcharts 가까이 온,하지만 여전히 자신의 한계를 가지고 :

  • FLOT가 fillBetween 플러그인을 사용하여 두 선 사이 음영을 지원하지만 여러 색상 라인이 위로에 따라와 음영을 지원하지 않습니다.
  • 누적 영역 차트를 사용하여 하이 차트로 두 줄 사이의 음영을 얻을 수 있지만 두 선이 교차하는 경우는 처리하지 않습니다.

의견이 있으십니까?

+0

FusionCharts XT - http://fusioncharts.com/에서 살펴보십시오. 두 줄 사이의 음영을 제공하지는 않지만 대화 형 JavaScript 차트 라이브러리에 대한 요구 사항을 충족시킵니다. –

답변

1

하이 차트 사용이 끝났습니다. 이 예제를 ElementStacks으로 가져 와서 교차를 처리하도록 수정했습니다. Negative Area을 참조하십시오.

$(function() { 
var Intersection = function (d1, d2) { 
    var self = this; 

    this.init = function() { 
    this.d1 = this.sortLine(d1); 
    this.d2 = this.sortLine(d2); 

    if (this.d1.length != this.d2.length) { 
     throw 'd1 and d2 expected to be same size'; 
    } 

    this.dps = _.zip(d1, d2); 

    hasUnmatchedIndex = _.any(this.dps, function(dp_pair) { 
     return dp_pair[0][0] != dp_pair[1][0]; 
    }); 

    if (hasUnmatchedIndex) 
     throw 'd1 and d2 do not have same indices'; 
    }; 

    this.sortLine = function(line) { 
    return _.sortBy(line, function(dp) { return dp[0]; }); 
    }; 

    this.transitions = function() { 
    return _.map(this.dps, function(dp_pair) { 
     a = dp_pair[0]; 
     b = dp_pair[1]; 
     result = null; 
     if (a[1] < b[1]) 
     result = -1; 
     else if (a[1] > b[1]) 
     result = 1; 
     else 
     result = 0; 

     return [a[0], result]; 
    }); 
    }; 

    this.dropTransitions = function() { 
    prev = null; 
    drops = []; 

    _.each(this.transitions(), function(curr) { 
     if (prev && prev[1] != curr[1] && prev[1] != 0 && curr[1] != 0) 
     drops.push([prev, curr]) 
     prev = curr; 
    }); 

    return drops; 
    }; 

    this.data = function() { 
    //self = this; 
    _d1 = this.sortLine(this.d1.concat(this.intersections())); 
    _d2 = this.sortLine(this.d2.concat(this.intersections())); 
    d1_g = []; 
    d2_g = []; 
    d_min = []; 
    dps = _.zip(_d1, _d2); 
    _.each(dps, function(dp_pair,i) { 
     index = dp_pair[0][0]; 
     dpv1 = dp_pair[0][1]; 
     dpv2 = dp_pair[1][1]; 

     if (dpv1 == null || dpv2 == null) { 
     d1_g.push([index, null]); 
     d2_g.push([index, null]); 
     } else { 
     diff = Math.abs(dpv1 - dpv2); 
     if (dpv1 > dpv2) { 
      d1_g.push([index, diff]); 
      d2_g.push([index, 0]); 
     } else if (dpv2 > dpv1) { 
      d1_g.push([index, 0]); 
      d2_g.push([index, diff]); 
     } else { 
      d1_g.push([index, diff]); 
      d2_g.push([index, diff]); 
     } 
     } 
     d_min.push([index, Math.min(dpv1, dpv2)]); 
    }); 

    return [d1_g, d2_g, d_min]; 
    }; 

    this.intersections = function() { 
    //self = this; 

    return _.map(this.dropTransitions(), function(dt) { 
     line1 = _.filter(self.d1, function(dp) { 
     return dp[0] == dt[0][0] || dp[0] == dt[1][0]; 
     }); 

     line2 = _.filter(self.d2, function(dp) { 
     return dp[0] == dt[0][0] || dp[0] == dt[1][0]; 
     }); 

     return self.findIntersection(line1, line2); 
    }); 
    }; 

    this.findIntersection = function(line1, line2) { 
    eq1 = this.lineEquation(line1); 
    eq2 = this.lineEquation(line2); 

    m1 = eq1.m; 
    b1 = eq1.b; 

    m2 = eq2.m; 
    b2 = eq2.b; 

    x = (b2 - b1)/(m1 - m2) 
    y = (m1 * x) + b1 
    return [x,y]; 
    }; 

    this.lineEquation = function(line) { 
    p1 = _.map(line[0], function(n) { return parseFloat(n); }); 
    p2 = _.map(line[1], function(n) { return parseFloat(n); }); 

    x1 = p1[0]; 
    y1 = p1[1]; 

    x2 = p2[0]; 
    y2 = p2[1]; 

    m = (y1 - y2)/(x1 - x2); 
    b = y1 - (m*x1); 
    eq = {'m': m, 'b': b}; 
    return eq; 
    }; 

    this.print = function (obj) { alert(JSON.stringify(obj)); }; 
    this.init(d1, d2); 
}; 

var d1r = [10, 8, 7, 6, 5, 4, 3, 5, 3, 9, 10, 11, 2]; 
var d2r = [ 5, 6, 7, 8, 9, 10, 9, 8, 12, 3, 2, 1, 20]; 

var d1 = _.map(d1r, function(e,i) { return [i, e-10]; }); 
var d2 = _.map(d2r, function(e,i) { return [i, e-10]; }); 

var t = new Intersection(d1, d2); 
var data = t.data(); 
var values = _.map(data, function(dps) { 
    return _.map(dps, function(dp) { 
     return dp[1]; 
    });   
}); 
var minValue = _.min(_.flatten(values)); 
// Need to find threshold to handle negative stacking values 
var threshold = minValue < 0 ? minValue : 0; 


var dp1 = t.d1; 

var dp2 = t.d2; 

var dp1_g = data[0]; 

var dp2_g = data[1]; 

var dp_min = data[2]; 

var chart = new Highcharts.Chart({ 
    chart: { 
     renderTo: 'container', 
     type: 'area', 
     animation: false 
    }, 
    plotOptions: { 
     area: { 
      stacking: true, 
      lineWidth: 0, 
      shadow: false, 
      marker: { 
       enabled: false 
      }, 
      enableMouseTracking: false, 
      showInLegend: false   
     }, 
     line: { 
      zIndex: 5 
     }, 
     series: { 
      threshold: threshold 
     } 
    }, 
    series: [{ 
     type: 'line', 
     color: 'red', 
     data: dp1 

    },{ 
     type: 'line', 
     color: 'black', 
     data: dp2 

    },{ 
     color: 'orange', 
     data: dp1_g 

    },{ 
     color: 'grey', 
     data: dp2_g 

    },{ 
     id: 'transparent', 
     color: 'rgba(255,255,255,0.0)', 
     data: dp_min 

    }] 
}, function(chart){ 
    chart.get('transparent').area.hide(); 
}); 
}); 
관련 문제