2017-12-19 10 views
1

Ich habe eine Scatter-Serie mit einer Reihe von Punkten, wie die hier gezeigte. https://developers.google.com/chart/interactive/docs/gallery/scatterchartWie zeichne ich ein benutzerdefiniertes Polygon über ein Google-Diagramm der Scatter-Serie?

Die Punkte sind gruppiert und jede Gruppe wird in einer anderen Farbe angezeigt. Ich möchte ein Polygon um jede Gruppe zeichnen (konvexe Hülle). Sieht so aus, als ob es keine direkte Möglichkeit gibt, Polygone mit jeweils n Randpunkten zum Diagramm hinzuzufügen.

Antwort

1

, wenn Sie einen Algorithmus haben die Grenzpunkte zu finden,
können Sie eine ComboChart verwenden, um sowohl die Streuung und Line-Serie zu zeichnen ...
Verwendung Option seriesTypeseries den Standardtyp
Verwendung Option setzen anpassen der Typ für eine bestimmte Serie

im folgenden Arbeits Schnipsel,
der Algorithmus verwendet, um aus gezogen wurde ->Convex Hull | Set 1 (Jarvis’s Algorithm or Wrapping)
(aus der Java-Version konvertiert)

google.charts.load('current', { 
 
    packages: ['corechart'] 
 
}).then(function() { 
 
    var groupA = [ 
 
    [0,3],[2,3],[1,1],[2,1],[3,0],[0,0],[3,3],[2,2] 
 
    ]; 
 

 
    var groupB = [ 
 
    [11,11],[12,12],[12,10],[12,14],[13,13],[14,12],[15,12],[16,12] 
 
    ]; 
 

 
    var data = new google.visualization.DataTable(); 
 
    data.addColumn('number', 'x'); 
 
    data.addColumn('number', 'y'); 
 
    data.addRows(groupA); 
 
    data.addRows(groupB); 
 

 
    addGroup('A', data, groupA) 
 
    addGroup('B', data, groupB) 
 

 
    var options = { 
 
    chartArea: { 
 
     bottom: 48, 
 
     height: '100%', 
 
     left: 36, 
 
     right: 24, 
 
     top: 36, 
 
     width: '100%' 
 
    }, 
 
    height: '100%', 
 
    seriesType: 'line', 
 
    series: { 
 
     0: { 
 
     type: 'scatter' 
 
     } 
 
    }, 
 
    width: '100%' 
 
    }; 
 

 
    var chart = new google.visualization.ComboChart(document.getElementById('chart_div')); 
 

 
    drawChart(); 
 
    window.addEventListener('resize', drawChart, false); 
 

 
    function drawChart() { 
 
    chart.draw(data, options); 
 
    } 
 

 
    function addGroup(group, dataTable, points) { 
 
    var polygon = convexHull(points); 
 
    var colIndex = dataTable.addColumn('number', group); 
 
    for (var i = 0; i < polygon.length; i++) { 
 
     var rowIndex = dataTable.addRow(); 
 
     dataTable.setValue(rowIndex, 0, polygon[i][0]); 
 
     dataTable.setValue(rowIndex, colIndex, polygon[i][1]); 
 
    } 
 
    } 
 

 
    function orientation(p, q, r) { 
 
    var val = (q[1] - p[1]) * (r[0] - q[0]) - 
 
       (q[0] - p[0]) * (r[1] - q[1]); 
 

 
    if (val == 0) { 
 
     return 0; // collinear 
 
    } else if (val > 0) { 
 
     return 1; // clock wise 
 
    } else { 
 
     return 2; // counterclock wise 
 
    } 
 
    } 
 

 
    function convexHull(points) { 
 
    // must be at least 3 rows 
 
    if (points.length < 3) { 
 
     return; 
 
    } 
 

 
    // init 
 
    var l = 0; 
 
    var p = l; 
 
    var q; 
 
    var hull = []; 
 

 
    // find leftmost point 
 
    for (var i = 1; i < points.length; i++) { 
 
     if (points[i][0] < points[l][0]) { 
 
     l = i; 
 
     } 
 
    } 
 

 
    // move counterclockwise until start is reached 
 
    do { 
 
     // add current point to result 
 
     hull.push(points[p]); 
 

 
     // check orientation (p, x, q) of each point 
 
     q = (p + 1) % points.length; 
 
     for (var i = 0; i < points.length; i++) { 
 
     if (orientation(points[p], points[i], points[q]) === 2) { 
 
      q = i; 
 
     } 
 
     } 
 

 
     // set p as q for next iteration 
 
     p = q; 
 
    } while (p !== l); 
 

 
    // add back first hull point to complete line 
 
    hull.push(hull[0]); 
 

 
    // set return value 
 
    return hull; 
 
    } 
 
});
html, body, #chart_div { 
 
    height: 100%; 
 
}
<script src="https://www.gstatic.com/charts/loader.js"></script> 
 
<div id="chart_div"></div>

Verwandte Themen