Chartjs-How to create RRG (Relative Rotation Graph) using chartJs or D3 with tooltip?

0👍

You can create something similar using chart.js; almost anything can be charted with it, as it is an open system with strong support for customization. Still, how much effort it would take to implement a type of chart that is not natively supported may vary.

For the type of chart you describe in your image, I’d go with the following:

Here’s an example that can get you started, containing all those ingredients as a proof of concept – there’s still a lot to do to achieve something useful in production. In particular, the tooltip is just the standard version, so you’ll need to configure it using the extensive set of options available in the library (see the docs).

Chart.register(ChartDataLabels)
const xMin = 90, xMax = 110;
const yMin = 90, yMax = 110;

const xHalf = (xMin+xMax)/2, xHalfPlus = xHalf + 1e-6,
    yHalf = (yMin + yMax)/2, yHalfDist = (yMax - yMin)/2;
new Chart(document.getElementById('chart'), {
    type: "line",
    data: {
        datasets: [{
            data: [
                {x: xMin, y: yHalf},
                {x: xHalf, y:yHalf},
                {x: xHalfPlus, y: null},
                {x: xMax, y: null}
            ],
            fill: true,
            backgroundColor: "rgba(255, 160, 0, 0.5)",
            pointRadius: 0,
            showLine: false,
            stacked: true,
            order: 1
        }, {
            data: [
                {x: xMin, y: yHalfDist},
                {x: xHalf, y:yHalfDist},
                {x: xHalfPlus, y: null},
                {x: xMax, y: null}
            ],
            fill: "-1",
            backgroundColor: "rgba(0, 255, 255, 0.5)",
            pointRadius: 0,
            showLine: false,
            stacked: true,
            order: 2
        },
            {
            data: [
                {x: xMin, y: null},
                {x: xHalf, y: null},
                {x: xHalfPlus, y: yHalf},
                {x: xMax, y:yHalf}
            ],
            fill: true,
            backgroundColor: "rgba(255, 255, 0, 0.5)",
            pointRadius: 0,
            showLine: false,
            order: 1
        },
        {
            data: [
                {x: xMin, y: null},
                {x: xHalf, y: null},
                {x: xHalfPlus, y: yHalfDist},
                {x: xMax, y:yHalfDist}
            ],
            fill: "-1",
            backgroundColor: "rgba(0, 192, 160, 0.5)",
            pointRadius: 0,
            showLine: false,
            order: 2
        },
        {
            type: "bubble",
            data: [
                {x: 101, y: 97.2, r: 18, label: "ABCD"},
                {x: 102, y: 103.4, r: 11, label: "WEDW"},
                {x: 103, y: 102.2, r: 11, label: "CESA"},
                {x: 98, y: 101.4, r: 11, label: "QWEX"}
            ],
            backgroundColor: 'rgba(64, 64, 128, 0.7)',
            order: 0,
            label: "my data"
        }
    ]},
    options: {
        scales: {
            x: {
                type: "linear",
                min: xMin,
                max: xMax,
            },
            y: {
                min: yMin,
                max: yMax,
                stacked: true,
            }
        },
        plugins:{
            legend:{
                labels:{
                    filter(ctx){
                        // no legend for the four quadrants
                        if(ctx.datasetIndex < 4) return false;
                        return true;
                    }
                }
            },
            datalabels:{
                anchor:'center',
                align: 'center',
                color: '#000',
                clamp: true,
                font: {
                    weight: 'bold'
                },
                formatter: function(value) {
                    //console.log(value)
                    return value.label || ''
                },
            },
            annotation: {
                annotations: {
                    label1: {
                        type: 'label',
                        content: 'Lagging',
                        xValue: xMin,
                        yValue: yMin,
                        position:{x: "start", y: "end"},
                        color: 'rgba(0,0,0,0.6)',
                    },
                    label2: {
                        type: 'label',
                        content: 'Weakening',
                        xValue: xMax,
                        yValue: yMin,
                        position:{x: "end", y: "end"},
                        color: 'rgba(0,0,0,0.6)'
                    },
                    label3: {
                        type: 'label',
                        content: 'Improving',
                        xValue: xMin,
                        yValue: yMax,
                        position:{x: "start", y: "start"},
                        color: 'rgba(0,0,0,0.6)'
                    },
                    label4: {
                        type: 'label',
                        content: 'Leading',
                        xValue: xMax,
                        yValue: yMax,
                        position:{x: "end", y: "start"},
                        color: 'rgba(0,0,0,0.6)'
                    }
                },
                font: {
                    size: 22
                }
            }
        }
    }
});
<div style="width:900px; height: 700px">
    <canvas id="chart"></canvas>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.3.0/chart.umd.js" integrity="sha512-CMF3tQtjOoOJoOKlsS7/2loJlkyctwzSoDK/S40iAB+MqWSaf50uObGQSk5Ny/gfRhRCjNLvoxuCvdnERU4WGg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-datalabels/2.2.0/chartjs-plugin-datalabels.min.js" integrity="sha512-JPcRR8yFa8mmCsfrw4TNte1ZvF1e3+1SdGMslZvmrzDYxS69J7J49vkFL8u6u8PlPJK+H3voElBtUCzaXj+6ig==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-annotation/2.2.1/chartjs-plugin-annotation.min.js" integrity="sha512-qF3T5CaMgSRNrxzu69V3ZrYGnrbRMIqrkE+OrE01DDsYDNo8R1VrtYL8pk+fqhKxUBXQ2z+yV/irk+AbbHtBAg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

Leave a comment