Chartjs различный цвет заливки для области перекрытия - PullRequest
0 голосов
/ 01 ноября 2018

Я использую ChartJS V2 для создания графика. Chartjs V2 поддерживает функцию цвета заливки. Но я бы хотел заполнить область перекрытия другим цветом. Пожалуйста, смотрите скриншот ниже. У меня две линии. A представляет область перекрытия для двух линий.

How the chart should look like

Я хотел бы заполнить 3 разными цветами для 2 строк. Когда Line1 и Line2 перекрываются, цвет заливки должен быть A Если Line1 не перекрывает Line2, цвет заливки должен быть B Если Line2 не перекрывает Line1, цвет заливки должен быть C

Я добавил скрипку для этого. Смотри Скрипку http://jsfiddle.net/qcs1t9ag/

Спасибо!

        var lineChartData = {
        labels: ["January", "February", "March", "April", "May", "June", "July"],
        datasets: [{
            label: "My First dataset",
            data: [50, 85, 56, 50, 60, 70, 80],
            yAxisID: "y-axis-1",
            borderColor: "#0ad4e6"
        }, {
            label: "My Second dataset",
            data: [35, 45, 75, 40, 55, 50, 62],
            yAxisID: "y-axis-2",
            borderColor: "#f6c63e"
        }]
    };


        var ctx = document.getElementById("canvas").getContext("2d");
        window.myLine = Chart.Line(ctx, {
            data: lineChartData,
            options: {
                responsive: true,
                hoverMode: 'label',
                stacked: false,
                title: {
                    display: false,
                    text: 'Chart.js Line Chart - Multi Axis'
                },
                animation: {
                    duration: 0
                },
                legend: {
                    display: false,
                    position: 'top',
                },
                scales: {
                    xAxes: [{
                        display: true,
                        gridLines: {
                            offsetGridLines: false
                        }
                    }],
                    yAxes: [{
                        type: "linear", // only linear but allow scale type registration. This allows extensions to exist solely for log scale for instance
                        display: true,
                        position: "left",
                        id: "y-axis-1",
                        scaleLabel: {
                            display: true,
                            labelString: "Cost"
                        }
                    }, {
                        type: "linear", // only linear but allow scale type registration. This allows extensions to exist solely for log scale for instance
                        display: true,
                        position: "right",
                        id: "y-axis-2",
                        scaleLabel: {
                            display: true,
                            labelString: "Students",
                        },
                        // grid line settings
                        gridLines: {
                            drawOnChartArea: false, // only want the grid lines for one axis to show up
                        },
                    }],
                }
            }
        });

1 Ответ

0 голосов
/ 06 ноября 2018

JueDoe, вот пример ниже, как вы могли бы сделать это.

Fiddle: Пример пересечения диаграмм

    var ORDER_STATS = {
    "2016": [10, 181, 194, -56, 130, 181, 179, 189, 30, 60, 193, 154],
    "2015": [124, -50, 152, 187, 10, 164, 129, -16, 115, 119, 129, 171],
    "2014": [-90, 80, 30, 59, 100, -30, 60, 116, 191, 181, -60, 106]
};
var colors = ['206,191,26', '119,206,26', '26,200,206', '236,124,98', '206,26,140', '26,77,206'];

// Definning X
var ordersChartData = {
    labels: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
    datasets: []
}

Object.keys(ORDER_STATS).forEach(function(key) {
    color = colors.shift();
    ordersChartData.datasets.push({
        label: key,
        lineTension: 0,
        type: 'line',
        backgroundColor: "rgba(" + color + ",0.1)",
        borderColor: "rgba(" + color + ",1)",
        borderWidth: 2,
        pointBackgroundColor: "rgba(" + color + ",1)",
        pointBorderColor: "#fff",
        pointBorderWidth: 1,
        pointRadius: 4,
        pointHoverBackgroundColor: "#fff",
        pointHoverBorderColor: "rgba(" + color + ",1)",
        pointHoverBorderWidth: 1,
        data: ORDER_STATS[key]
    });
});

var ctx = document.getElementById("myChart").getContext("2d");

Chart.defaults.global.defaultFontColor = 'grey';
Chart.defaults.global.defaultFontFamily = "Tahoma";
Chart.defaults.global.defaultFontSize = 11;
Chart.defaults.global.defaultFontStyle = 'normal';

var myChart = new Chart(ctx, {
    type: 'line',
    data: ordersChartData,
    defaultFontSize: 11,
    options: {
        responsive: true,

        title: {
            display: true,
            text: 'Intersection realization',
            fontColor: "#444",
            fontFamily: 'Tahoma',
            padding: 0
        },

        legend: {
            display: true,
            labels: {
                fontColor: 'grey',
                usePointStyle: true
            }
        },
        tooltips: {
            mode: "index",
            intersect: true,
            position: 'nearest',
            bodySpacing: 4

        }
    }
});

Chart.plugins.register({
    afterDatasetsDraw: function(chartInstance, easing) {

        var intersects = findIntersects(ORDER_STATS['2015'], ORDER_STATS['2014']);
        var context = chartInstance.chart.ctx;

        var Y = chartInstance.scales['y-axis-0'];
        var X = chartInstance.scales['x-axis-0'];

        zeroPointY = Y.top + ((Y.bottom - Y.top) / (Y.ticks.length - 1) * Y.zeroLineIndex);
        zeroPointX = Y.right;
        yScale = (Y.bottom - Y.top) / (Y.end - Y.start);
        xScale = (X.right - X.left) / (X.ticks.length - 1);

        intersects.forEach(function(result, idx) {
            context.fillStyle = 'red';
            context.beginPath();
            context.arc((result.x * xScale) + zeroPointX, (Y.end - Y.start) - (result.y * yScale) - ((Y.end - Y.start) - zeroPointY), 3, 0, 2 * Math.PI, true);
            context.fill();
        });
    }
});


function findIntersects(line1, line2) {
    var intersects = [];

    line1.forEach(function(val, idx) {
        var line1StartX = idx;
        var line1StartY = line1[idx];
        var line1EndX = idx + 1;
        var line1EndY = line1[idx + 1];
        var line2StartX = idx;
        var line2StartY = line2[idx];
        var line2EndX = idx + 1;
        var line2EndY = line2[idx + 1];

        result = checkLineIntersection(line1StartX, line1StartY, line1EndX, line1EndY, line2StartX, line2StartY, line2EndX, line2EndY);

        if (result.onLine1 && result.onLine2) {
            intersects.push(result);
        }
    });

    return intersects;
}

function checkLineIntersection(line1StartX, line1StartY, line1EndX, line1EndY, line2StartX, line2StartY, line2EndX, line2EndY) {
    // if the lines intersect, the result contains the x and y of the intersection (treating the lines as infinite) and booleans for whether line segment 1 or line segment 2 contain the point
    var denominator, a, b, numerator1, numerator2, result = {
        x: null,
        y: null,
        onLine1: false,
        onLine2: false
    };
    denominator = ((line2EndY - line2StartY) * (line1EndX - line1StartX)) - ((line2EndX - line2StartX) * (line1EndY - line1StartY));
    if (denominator == 0) {
        return result;
    }
    a = line1StartY - line2StartY;
    b = line1StartX - line2StartX;
    numerator1 = ((line2EndX - line2StartX) * a) - ((line2EndY - line2StartY) * b);
    numerator2 = ((line1EndX - line1StartX) * a) - ((line1EndY - line1StartY) * b);
    a = numerator1 / denominator;
    b = numerator2 / denominator;

    // if we cast these lines infinitely in both directions, they intersect here:
    result.x = line1StartX + (a * (line1EndX - line1StartX));
    result.y = line1StartY + (a * (line1EndY - line1StartY));
    /*
            // it is worth noting that this should be the same as:
            x = line2StartX + (b * (line2EndX - line2StartX));
            y = line2StartX + (b * (line2EndY - line2StartY));
            */
    // if line1 is a segment and line2 is infinite, they intersect if:
    if (a > 0 && a < 1) {
        result.onLine1 = true;
    }
    // if line2 is a segment and line1 is infinite, they intersect if:
    if (b > 0 && b < 1) {
        result.onLine2 = true;
    }
    // if line1 and line2 are segments, they intersect if both of the above are true
    return result;
};

Если это не то, что вам нужно, я рекомендую вам нарисовать третью линию с разницей между первой и второй линией ... или нарисовать другой график только с третьей линией (вычислите разницу между линией A и линией B) ,

Скрипка: Третья строка

Официальная документация .

Здесь (официальный) у вас есть несколько примеров графиков.

...