2017-01-25 1 views
2

Es ist mir gelungen, herauszufinden, wie ich die hier im Stackoverflow gefundenen Lösungen verbessern kann, um vertikale und horizontale Linien zu einem Liniendiagramm in ChartJS v2 + hinzuzufügen, um sie auf ein Blasendiagramm anzuwenden (Ich rate dazu, zu meinem Update zu wechseln Ende für einen besseren Ansatz)Wie schattiere ich einen Teil des Hintergrunds von ChartJS Bubble Chart?

var originalBubbleDraw = Chart.controllers.bubble.prototype.draw; 
    Chart.helpers.extend(Chart.controllers.bubble.prototype, { 
    draw: function() { 
     originalBubbleDraw.apply(this, arguments); 

     var chart = this.chart; 
     var ctx = chart.chart.ctx; 
     var xaxis = chart.scales['x-axis-0']; 
     var yaxis = chart.scales['y-axis-0']; 

     var xvalue = chart.config.data.queryLimits['x']; 
     var yvalue = chart.config.data.queryLimits['y']; 
     var xcolor = chart.config.data.queryLimits['xcolor']; 
     var ycolor = chart.config.data.queryLimits['ycolor']; 
     var lineThickness = 3; 

     function drawLine(x1,y1,x2,y2,color) { 
     console.log("color="+color+", x1="+x1+", x2="+x2+", y1="+y1+", y2="+y2); 
     ctx.save(); 
     ctx.beginPath(); 
     ctx.moveTo(x1, y1); 
     ctx.strokeStyle = color; 
     ctx.lineWidth=lineThickness; 
     ctx.lineTo(x2, y2); 
     ctx.stroke(); 
     ctx.restore(); 
     } 

     // draw vertical line 
     if (xvalue) { 
     x1 = xaxis.getPixelForValue(xvalue); 
     x2 = xaxis.getPixelForValue(xvalue); 
     y1 = yaxis.top; 
     y2 = yaxis.bottom; 
     drawLine(x1,y1,x2,y2,xcolor); 
     } 

     // draw horizontal line 
     if (yvalue) { 
     x1 = xaxis.left; 
     x2 = xaxis.right; 
     y1 = yaxis.getPixelForValue(yvalue); 
     y2 = yaxis.getPixelForValue(yvalue); 
     drawLine(x1,y1,x2,y2,ycolor); 
     } 
    } 
    }); 

var config = { 
    type: 'bubble', 
    data: { 
    queryLimits: {x: 42, y: 21, xcolor: '#00FF00', ycolor: '#0000ff'}, 
    datasets: [ 
     { 
      label: '', 
      data: [ 
       {x: 20, y: 30, r: 15}, 
       {x: 40, y: 10, r: 10}, 
       {x: 100, y: 15, r: 10}, 
       {x: 50, y: 22, r: 5}, 
       {x: 80, y: 26, r: 3}, 
       {x: 63, y: 28, r: 10}, 
       {x: 71, y: 18, r: 12} 
      ], 
      backgroundColor:"#FF6384", 
      hoverBackgroundColor: "#FF6384", 
     }] 
    } 
}; 

var ctx = document.getElementById("myChart").getContext("2d"); 
new Chart(ctx, config); 

I noch einen Schritt weiter gehen müssen und Schatten auf den Bereich/Hintergrund des Diagramms auf einer Seite der vertikalen Linie und oberhalb oder unterhalb der horizontalen Linie einer anderen Farbe (wie ein Licht grau oder etwas subtil).

Ich bin mir nicht sicher, ob der Ansatz versucht, einen Teil des Hintergrunds zu ändern oder Rechtecke hinzuzufügen, die so groß und positioniert sind, dass sie die Hintergrundschattierung simulieren.

Ideen?

Hier ist ein Beispiel Mockup des Ziel ist:

für diejenigen, sehen dies in der Zukunft Bubble/Scatter With Horizontal & Vertical Lines & Shaded Area

aktualisieren

Für was es wert ist, landete ich einen besseren Weg zu entdecken bis zu Nähern Sie sich sowohl dem Zeichnen von Linien als auch von Rechtecken, indem Sie das Annotations-Plugin für Chartjs verwenden, das Sie hier finden: https://github.com/chartjs/chartjs-plugin-annotation. Es ist viel einfacher zu arbeiten und hat nicht zur Folge, dass der Code zum Zeichnen der Linien und Rechtecke mehr als nötig abgefeuert wird. Außerdem konnte ich ein anderes Plugin https://github.com/compwright/chartjs-plugin-draggable zum Ziehen von Anmerkungen verwenden, die von diesem ersten Plugin erstellt wurden. Ich lasse die akzeptierte Antwort so, wie sie ist, weil sie die Frage beantwortet, die ich aus dem Kontext hatte, wie man den rechteckigen schattierten Bereich nach dem ursprünglichen Erweiterungs-Ansatz löst, aber ich empfehle den Plugin-Ansatz gegenüber dem, nachdem ich mehr darüber gelernt habe.

Antwort

2

Wie Sie mit Ihrem Attribut queryLimits getan haben, können Sie auf die gleiche Weise ein Attribut ausführen, das den gewünschten Teil füllt.

Durch das Hinzufügen das folgende Attribut zu Ihrem Diagramm-Datensatz:

fillBackground: { 
    // In this porperty, add the string portion you want to fill 
    // Inputs are : "tr" for top-right 
    //    "tl" for top-left 
    //    "br" for bottom-right 
    //    "bl" for bottom-left 
    pos: ["tr", "bl", "br"], 

    // A single color will be used in all the portions 
    // But you can also set an array of colors which must have the same length as the pos 
    // i.e color: ["rgba(0, 0, 0, 0.1)", "rgba(30, 30, 30, 0.3)", "rgba(60, 60, 60, 0.5)"] 
    color: "rgba(30, 30, 30, 0.15)" 
} 

Dann in Ihrer draw() Funktion den folgenden Code hinzu:

function drawRect(x1, y1, x2, y2, color) { 
    ctx.save(); 
    ctx.fillStyle = color; 
    ctx.fillRect(x1, y1, x2, y2, color); 
    ctx.restore(); 
} 

// Checks if you have the attribute in your dataset 
if (chart.config.data.fillBackground) { 

    // Make sure you have portions in your chart 
    if (!xvalue || !yvalue) return; 

    var pos = chart.config.data.fillBackground.pos; 
    var color = chart.config.data.fillBackground.color; 

    // For every position in your array .. 
    for (p in pos) { 

     // Based on the string code, fills the right portion 
     switch (pos[p]) { 
      case "tl": 
       drawRect(xaxis.left, yaxis.top, xaxis.getPixelForValue(xvalue) - lineThickness/2 - xaxis.left, yaxis.getPixelForValue(yvalue) - lineThickness/2 - yaxis.top, (Array.isArray(color)) ? color[p] : color); 
       break; 
      case "tr": 
       drawRect(xaxis.getPixelForValue(xvalue) + lineThickness/2, yaxis.top, xaxis.right, yaxis.getPixelForValue(yvalue) - lineThickness/2 - yaxis.top, (Array.isArray(color)) ? color[p] : color); 
       break; 
      case "bl": 
       drawRect(xaxis.left, yaxis.getPixelForValue(yvalue) + lineThickness/2, xaxis.getPixelForValue(xvalue) - lineThickness/2 - xaxis.left, yaxis.bottom - (yaxis.getPixelForValue(yvalue) + lineThickness/2), (Array.isArray(color)) ? color[p] : color); 
       break 
      case "br": 
       drawRect(xaxis.getPixelForValue(xvalue) + lineThickness/2, yaxis.getPixelForValue(yvalue) + lineThickness/2, xaxis.right, yaxis.bottom - (yaxis.getPixelForValue(yvalue) + lineThickness/2), (Array.isArray(color)) ? color[p] : color); 
       break; 
     } 
    } 
} 

Dieses Ihr Problem lösen sollte.

Sie können beispielsweise das Arbeiten mit diesen Funktionen in this fiddle überprüfen, und hier ist das Ergebnis:

enter image description here

+0

Excellent! Danke für die detaillierte Antwort und flexible Lösung. Befinden sich diese Rechtecke standardmäßig oberhalb der Punkte und Linien im Diagramm oder darunter? Gibt es eine Z-Dimension, die Objekte darunter blockiert? Ich frage, weil die nächste Aufgabe sein wird, eine Interaktionshandhabung zu erstellen, so dass die Linien verschoben werden können (die Schattierung würde der Linienbewegung folgen) und die Punkte können angeklickt werden, um anderswo zu navigieren. – Streamline

+0

@Streamline Leider gibt es im Canvas keine eingebaute z-Eigenschaft. Das gleiche Problem gilt für Chart.js. Ich weiß nicht, wie du es schaffen würdest, ich wäre froh zu wissen, ob du es zufällig findest. – tektiv

+0

Für was es wert ist, entdeckte ich einen besseren Weg, um sowohl das Zeichnen von Linien und Rechtecke zu erreichen, indem Sie das Annotation-Plugin für Chartjs hier https://github.com/chartjs/chartjs-plugin-annotation verwenden. Es ist viel einfacher zu arbeiten und hat nicht zur Folge, dass der Code zum Zeichnen der Linien und Rechtecke mehr als nötig abgefeuert wird. Außerdem konnte ich ein anderes Plugin zum Ziehen von Anmerkungen verwenden, die mit diesem ersten Plugin erstellt wurden. Ich werde den ursprünglichen Beitrag auch für zukünftige Leute aktualisieren. – Streamline

Verwandte Themen