How to make a dual color Line chart

This HOWTO document shows you how to get a dual color Line chart where the X axis is in the center and there's one color for positive numbers and another for negative. You could use this on a financial chart and use red/black as the colors (as shown below).

Introduction

This is a chart that I've created before using the <canvas> tag but is using the SVG chart to render it instead. If you're using the SVG libraries this is obviously vey useful since you don't have to mix-and-match and stick to just using SVG.

You might also be already familiar and comfortable working with the SVG tag and unwilling to learn <canvas> as well.

Add the <div> tags to the document

The first thing to do is add the <div> tags to the document. This is where the chart will be rendered. There are two tags used - one for the top half and one for the bottom. All the CSS that's necessary is inlined for clarity but you can place this elsewhere if you prefer.

<div style="float: right; position: relative; width: 650px; height: 250px">
    <div style="position: absolute; top: 0; left: 0; width: 650px; height: 250px" id="cc1"></div>
    <div style="position: absolute; top: 0; left: 0; width: 650px; height: 250px" id="cc2"></div>
</div>

Draw both of the Line charts

Now we draw both of the Line charts - one to each of the <div> tags. Initially since we haven't made any changes to the clipping yet the charts will be positioned one on top of the other. It's when the clipping is added that the chart begins to take shape. Note that the labels are only added to the chart that will become the bottom half of the chart - since the chart that becomes the top half is clipped there's no point adding them.

// The data for BOTH of the charts and some things that we want to
// make easy to change if necessary
data          = [4,8,6,5,-3,-2,-1,-5,-6,8,9,4,6,7,5,1,3,5,6,-8,-4,-5,-2,3];
fills         = ['rgba(0,192,0,0.25)', 'rgba(255,0,0,0.25)' ];
marginLeft    = 50;
yaxisScaleMin = -10;
yaxisScaleMax = 10;
linewidth     = 3;


// Create the green part of the line
line = new RGraph.SVG.Line({
    id: 'cc1',
    data: data,
    options: {
        marginLeft: marginLeft,
        colors: ['#0c0'],
        linewidth: linewidth,
        filled: true,
        filledColors: [fills[0]],
        yaxisScaleMax: yaxisScaleMax,
        yaxisScaleMin: yaxisScaleMin,
        xaxisTickmarks: false,
        backgroundGridBorder: false,
        backgroundGridVlines: false,
        yaxis: false,
        spline: true
    }
}).draw();

// Create the red part of the line
line2 = new RGraph.SVG.Line({
    id: 'cc2',
    data: data,
    options: {
        yaxis: false,
        yaxisScaleMax: yaxisScaleMax,
        yaxisScaleMin: yaxisScaleMin,
        marginLeft: marginLeft,
        linewidth: linewidth,
        filled: true,
        filledColors: [fills[1]],
        xaxisTickmarks: false,
        
        // Labels only need to be shown on the bottom chart
        xaxisLabels: [
            '', 'Jan', '',
            '', 'Feb', '',
            '', 'Mar', '',
            '', 'Apr', '',
            '', 'May', '',
            '', 'Jun', '',
            '', 'Jul', '',
            '', 'Aug', '',
            '', 'Sep', '',
            '', 'Oct', '',
            '', 'Nov', '',
            '', 'Dec', ''
        ],
        backgroundGridBorder: false,
        backgroundGridVlines: false,
        spline: true
    }
}).draw();

Add the clipping to the black chart

Now that the charts have been drawn we can start adding the clipping. The first element that's added is the <clipPath> element. Then a <rect> element is added that defines the shape of the clipped area. Finally the relevant attribute is set on the all-elements group so that it uses the clip. This is the code that creates the clipping for the top half of the chart.

// Create the  clipPath element that sits inside the <def> tag
clip = RGraph.SVG.create({
    svg: line.svg,
    type: 'clipPath', // This is case sensitive!
    parent: line.svg.defs,
    attr: {
        id: 'myClip'
    }
});

// Create the shape element for the clip area
RGraph.SVG.create({
    svg: line.svg,
    parent: clip,
    type: 'rect',
    attr: {
        // These coordinates create a rect that is the same size as the top half of the SVG tag
        x: 0,
        y: 0,
        width: 650,
        height: 125
    }
});

// Now set the clip-path attribute on the first Line charts all-elements group
line.svg.all.setAttribute(
    'clip-path',
    'url(#myClip)'
);

Add the clipping to the red chart

Now that the clipping has veen added to the black chart that restricts it to the top half of the SVG tag clipping can also be added to the red charts SVG tag to restrict it to the bottom half of the SVG tag.

// Create the  clipPath element that sits inside the <def> tag *** for the bottom half of the chart ***
clip2 = RGraph.SVG.create({
    svg: line2.svg,
    type: 'clipPath', // This is case sensitive!
    parent: line2.svg.defs,
    attr: {
        id: 'myClip2'
    }
});

// Create the shape element for the clip area
RGraph.SVG.create({
    svg: line2.svg,
    parent: clip2,
    type: 'rect',
    attr: {
        // These coordinates create a rect that is the same size as the bottom half of the SVG tag
        x: 0,
        y: 150,
        width: 900,
        height: 150
    }
});

// Now set the clip-path attribute on the second Line charts all-elements group
line2.svg.all.setAttribute(
    'clip-path',
    'url(#myClip2)'
);

A demo file of this technique

A demo file that's included in the download zip file that you can run on your computer is here.