About
RGraph is a JavaScript charts library based on HTML5 SVG and canvas. RGraph is mature (over 15 years old) and has a wealth of features making it an ideal choice to show charts on your website.

More »

 

Download
Get the latest version of RGraph (version 6.17) from the download page. There's also older versions available, minified files and links to cdnjs.com hosted libraries.

More »

 

License
RGraph can be used for free under the GPL or if that doesn't suit your situation there's an inexpensive (£129) commercial license available.

More »

New dual-color trendline demo pages

Written by Richard Heyes, RGraph author, on 6th May 2024

I've recently added two new demo pages to the download archive that show trendlines on the Line chart and Scatter chart where the line/points above the trendline are one color and another color where they're below the trendline. This is not just an option that can be turned on or off - it does need some configuration. However, it's not difficult to understand what's happening and it's fully commented in the source code of the demo pages. There are two images below that show the two charts and these demo pages will be a part of the version 6.18 release.

Line chart
Scatter chart

This is the source code for the Line chart:

<script>
    // The data for the Line chart
    DATA   = [1,3,2,5,4,4,7,8,8,6,7,9];

    // The configuration options that are used for both of the Line charts
    CONFIG = {
        trendline: true,
        trendlineMargin: 15,
        trendlineDashed: true,
        xaxisLabels: RGraph.MONTHS_SHORT,
        linewidth: 1,
        spline: true,
        shadow: false,
        marginInner: 25,
        tickmarksStyle: 'cross',
        tickmarksStyle: 'dot',
        tickmarksSize: 6,
        backgroundGridVlines: false,
        backgroundGridBorder: false,
        backgroundColor: 'white',
        xaxisLinewidth: 2,
        yaxisLinewidth: 2,
        xaxisTickmarksLength: 5,
        yaxisTickmarksLength: 5,
        yaxisTickmarksLastBottom: true,
        xaxisTickmarksLastLeft: true,
        textSize: 16,
        animationTraceCenter: true,
        colors: ['black']
    };

    // Create the first line chart
    line1 = new RGraph.Line({
        id: 'cvs',
        
        // By adding the data this way (ie by using the spread operator) it effectively clones
        // the data - so there are no reference issues)
        data: [...DATA],
        options: {
            ...CONFIG
        }
    }).draw();


    // The coordinates of the first (and only) trendline
    var coords = line1.coordsTrendline[0];


    // 
    // Calculate the coordinates for the top part of the chart (above the trendline).
    // This shape will be clipped to and then the Line chart redrawn
    // 
    coords_top = [
        [0,coords[0][1]],
        ...coords, // The coordinates of the trendline
        [line1.canvas.width,coords[1][1]],
        [line1.canvas.width, 0],
        [0,0]
    ];

    //
    // Calculate the coordinates for the bottom part of the chart
    // (below the trendline)
    //
    coords_bottom = [
        [0,coords[0][1]],
        ...coords, // The coordinates of the trendline
        [line1.canvas.width,coords[1][1]],
        [line1.canvas.width, line1.canvas.height],
        [0,line1.canvas.height]
    ];


    //
    // Now that we have the coordinates clipping can be
    // installed on the chart that's already been drawn
    // (the top part of the chart).
    //
    line1.set('clip', coords_top);







    //
    // Now create the second Line chart which shows the red part of the line.
    // The clipping coordinates have already been created above so they can be used straight away.
    //
    line2 = new RGraph.Line({
        id: 'cvs',
        data: [...DATA],
        options: {
            ...CONFIG,
            colors: ['red'],
            clip: coords_bottom
        }
    }).draw();
    
    

    //
    // Now draw both of the charts using the RGraph.redraw
    // API function
    //
    RGraph.redraw();
</script>

And this is the source code for the Scatter chart:

<script>
    //
    // The data for the Scatter chart points - lots of it
    //
    DATA = [
        [6347.82,0.69],
        [8956,0.51],    [5620,0.34],    [8092,0.34],    [5069,0.8],
        [5924,0.05],    [7851,0.2],     [2065,0.72],    [3872,0.29],
        [6521.73,0.50], [28501,0.37],   [18344,0.37],   [26561,0.39],
        [21391.30,0.33],[24628,0.4],    [24670,0.46],   [15689,0.76],
        [8000,0.70],    [23921,0.43],   [30434.78,0.56],[18809,0.96],
        [24695.65,0.18],[16000,0.33],   [27445,0.59],   [11926,0.21],
        [16819,0.78],   [21739.13,0.69],[8956.52,0.74], [28059,0.61],
        [20458,0.19],   [23079,0.2],    [20762,0.48],   [17547,0.54],
        [28706,0.72],   [22361,0.48],   [8956.52,0.79], [21696,0.59],
        [17026,0.65],   [12766,0.67],   [22618,0.5],    [23902,0.59],
        [24539,0.54],   [23700,0.6],    [22334,0.29],   [24830,0.66],
        [10086.95,0.39],[12263,0.4],    [26057,0.22],   [28744,0.94],
        [12151,0.16],   [22528,0.37],   [18521.73,0.22],[32173.91,0.36],
        [29355,0.87],   [17036,0.52],   [32000,0.44],   [24312,0.58],
        [29227,0.71],   [24173,0.29],   [18070,0.66],   [13321,0.34],
        [25660,0.47],   [23860,0.26],   [17391.30,0.16],[25217.39,0.74],
        [20115,0.53],   [18988,0.19],   [28591,0.68],   [8956.52,0.26],
        [26695.65,0.78],[13234,0.18],   [20197,0.73],   [20187,0.77],
        [20888,0.29],   [21652.17,0.22],[29348,0.77],   [14869.56,0.63],
        [10909,0.55],   [18173.91,0.30],[12372,0.5],    [24173.91,0.8],
        [28173.91,0.28],[16521,0.22],   [16905,0.87],   [24099,0.36],
        [15210,0.18],   [24069,0.44],   [15062,0.49],   [22162,0.17],
        [30521.73,0.37],[24838,0.42],   [19236,0.2],    [12402,0.51],
        [29949,0.88],   [24314,0.3],    [29584,0.84],   [21705,0.6],
        [11651,0.32],   [15174,0.85],   [26007,0.92],   [26603,0.22],
        [21484,0.87],   [24855,0.37],   [15524,0.91],   [16521.73,0.37],
        [28304,0.82],   [17427,0.45],   [27818,0.81],   [17215,0.75],
        [11935,0.79],   [12761,0.51],   [11185,0.31],   [12103,0.62],
        [17421,0.63],   [21176,0.77],   [17941,0.4],    [18080,0.84],
        [32173.91,0.51],[22556,0.85],   [22592,0.24],   [29128,0.79],
        [32260.86,0.76],[26192,0.28],   [22912,0.34],   [18429,0.54],
        [23469,0.36],   [19356,0.38],   [15321,0.43],   [23020,0.73],
        [17212,0.23],   [28172,0.49],   [24610,0.26],   [28472,0.59],
        [19744,0.66],   [15460,0.5],    [28877,0.37],   [29870,0.39],
        [23475,0.47],   [25629,0.7],    [10521.73,0.14],[27358,0.75],
        [28036,0.97],   [19552,0.86],   [25319,0.6],    [29466,0.95],
        [18861,0.88],   [29852,0.88],   [28877,0.89],   [27523,0.56],
        [13435,0.12],   [29399,0.58],   [21698,0.9],    [14347.82,0.26],
        [28909,0.36],   [20870,0.25],   [26751,0.76],   [24434.78,0.87],
        [12079,0.15],   [16765,0.1],    [11674,0.6],    [11058,0.78],
        [11844,0.3],    [14777,0.36],   [20823,0.91],   [15992,0.23],
        [26171,0.85],   [19652.17,0.11],[22841,0.62],   [21527,0.52],
        [27084,0.32],   [28173.91,0.87],[20249,0.95],   [12818,0.24],
        [13924,0.14],   [22007,0.4],    [12560,0.71],   [17194,0.75],
        [14173.91,0.70],[11808,0.34],   [29015,0.82],   [10000,0.23],
        [23854,0.76],   [10260.86,0.65],[25037,0.29],   [17254,0.25],
        [20473,0.85],   [23831,0.3],    [19478.26,0.28],[15871,0.81],
        [21073,0.15],   [8869.56,0.16], [13192,0.8],    [24882,0.56],
        [27202,0.68],   [24327,0.29],   [7826.08,0.63], [29565.21,0.473],
        [17058,0.82],   [19212,0.53],   [16224,0.6],    [11975,0.85],
        [18575,0.8],    [26226,0.58],   [17591,0.1],    [23667,0.63],
        [18782.60,0.14],[16372,0.77],   [30173.91,0.26],[21435,0.84],
        [25027,0.31],   [36356,0.5],    [36284,0.53],   [44203,0.76],
        [44869.56,0.86],[33485,0.73],   [38798,0.75],   [34666,0.85],
        [39210,0.63],   [45565.21,0.63],[42947,0.91]
    ];

    //
    // The configuration that's used for both of the charts.
    //
    CONF = {
        textSize: 16,
        
        marginLeft: 75,
        marginRight: 45,
        marginBottom: 75,

        xaxisScaleMax: 50000,
        xaxisScale:true,
        xaxisTitle: 'Income',
        xaxisTitleBold: true,
        xaxisLinewidth: 2,
        xaxisTickmarksLength: 5,
        xaxisTickmarksLastLeft: true,
        
        yaxisScaleDecimals: 1,
        yaxisTitle: 'Metro health index',
        yaxisTitleBold: true,
        yaxisLinewidth: 2,
        yaxisTickmarks: true,
        yaxisTickmarksLength: 5,
        yaxisTickmarksLastBottom: true,
        
        trendline: true,
        trendlineColors: ['#600'],
        trendlineDashed: false,
        trendlineMargin: 0,
        trendlineClipping: false,
        
        backgroundGridVlines: false,
        backgroundColor: 'white',
        
        tickmarksStyle: 'circle',
        tickmarksSize: 7
    };




    //
    // Draw the red part of the Scatter chart (the bottom
    // half)
    //
    scatter = new RGraph.Scatter({
        id: 'cvs',
        data: RGraph.arrayClone(DATA, true),
        options: RGraph.arrayClone(CONF, true)
    }).draw();
    
    
    
    // The coordinates of the first (and only) trendline
    var coords = scatter.coordsTrendline[0];



    //
    // Calculate the coordinates for the top part of the chart
    // (above the trendline)
    //
    coords_top = [
        [0,coords[0][1]],
        ...coords,
        [scatter.canvas.width,coords[1][1]],
        [scatter.canvas.width, 0],
        [0,0]
    ];


    //
    // Calculate the coordinates for the bottom part of the chart
    // (below the trendline)
    //
    coords_bottom = [
        [0,coords[0][1]],
        ...coords,
        [scatter.canvas.width,coords[1][1]],
        [scatter.canvas.width, scatter.canvas.height],
        [0,scatter.canvas.height]
    ];

    //
    // Now that we have the coordinates clipping can be
    // installed on the chart that's already been drawn
    // (the bottom part of the chart) and the default
    // color for the tickmarks is set to red.
    //
    scatter.set('clip', coords_bottom);
    scatter.set('colorsDefault', ['red']);



    //
    // Create a new chart that's clipped to the top
    // part of the canvas (the black tickmarks). The
    // clipping is set to the coordinates that were
    // generated earlier and the default color is set
    // to black.
    //
    scatter2 = new RGraph.Scatter({
        id: 'cvs',

        // Make a copy of the data and use that
        data: RGraph.arrayClone(DATA, true),

        options: {

            // Reuse the configuration
            ...RGraph.arrayClone(CONF, true),

            clip: coords_top, //  Clip to the part of the canvas
                              //  that's above the trendline
            colorsDefault: 'black'
        }
    }).draw();

    //
    // Now draw both of the charts using the RGraph.redraw
    // API function
    //
    RGraph.redraw();
</script>