Creating multi-segmented line graph

Martynas Majeris -

So, you need to color parts of the same graph differently?

Unfortunately, graph object can contain only one color.

Fortunately, we're not limited to just one graph. The workaround is to create a separate graph for each unique color that you will need to have segments in.

Let's say we need to divide our line graph into 5 different segments that use the a variety of three colors.

The trick is to structure our data so it contains values for each graph for only those categories that this segment touches.

var chartData = [
    { year: 1994, color1: 1587, balloon1: 1587},
    { year: 1995, color1: 1567, balloon1: 1567},
    { year: 1996, color1: 691, color2: 691, balloon2: 691}, /* we're corrsing over to color2 segment */
    { year: 1997, color2: 1630, color3: 1630, balloon3: 1630}, /* and emmediatelly after that to color3 */
    { year: 1998, color3: 1660, balloon3: 1660},
    { year: 1999, color3: 1683, balloon3: 1683},
    { year: 2000, color3: 1691, balloon3: 1691},
    { year: 2001, color1: 1298, color3: 1298, balloon1: 1298}, /* back to color1 */
    { year: 2002, color1: 1275, balloon1: 1587},
    { year: 2003, color1: 1246, balloon1: 1246},
    { year: 2004, color1: 1218, balloon1: 1218},
    { year: 2005, color1: 1213, balloon1: 1213},
    { year: 2006, color1: 1199, color3: 1199, balloon1: 1587}, /* and to color3 again */
    { year: 2007, color3: 1110, balloon3: 1110},
    { year: 2008, color3: 1165, balloon3: 1165},
    { year: 2009, color3: 1145, balloon3: 1145},
    { year: 2010, color3: 1163, balloon3: 1163},
    { year: 2011, color3: 1180, balloon3: 1180},
    { year: 2012, color3: 1159, balloon3: 1159}];

 

We also need to define each graph:

 

// first graph
var graph = new AmCharts.AmGraph();
graph.type = "line";
graph.valueField = "color1";
graph.balloonText = "[[balloon1]]";
graph.lineThickness = 3;
graph.connect = false;
chart.addGraph(graph);

// second graph
graph = new AmCharts.AmGraph();
graph.type = "line";
graph.valueField = "color2";
graph.balloonText = "[[balloon2]]";
graph.lineThickness = 3;
graph.connect = false;
chart.addGraph(graph);

// third graph
graph = new AmCharts.AmGraph();
graph.type = "line";
graph.valueField = "color3";
graph.balloonText = "[[balloon3]]";
graph.lineThickness = 3;
graph.connect = false;
chart.addGraph(graph);

 

Note #1: Notice we're using [[balloon1/2/3]] netacode for ballooText. This is to ensure that on intersection points, cursor would not display two rollover balloons with the same value.

Note #2: We also set "connect = false" for each graph so that the chart does not fill in the gaps between sections.

 

OK, let's see how this baby looks:

Screenshot-2013-05-22_19.52.23.png

And as usually, here's the live demo: http://jsfiddle.net/amcharts/5Lt9C/

Have more questions? Submit a request

Comments

  • Avatar
    Francisco Donayre

    Hi Martynas, 

    It's a good sample but I was trying to apply it mixing stock events and a stock chart without success. The requirements are:

    • Put an event when de line changes its tendence or direction (up or down)

    • Set a line color for each segment in depence on: if the values are increasing the line color must be green, other way, the line color must be red.

    If you execute the code below, you'll see that I've got to put the events, but I couldn't get coloring the lines as requirements says.

    Here's the code:

    [code]

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

    <html>

    <head>

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

    <title></title>

    <link rel="stylesheet" href="./amcharts/style.css" type="text/css">

    <script src="./amcharts/amstock.js" type="text/javascript"></script>

    <script type="text/javascript">

    var num = 25;

    var chartData = [];

    var signal = [-1, 0, 1];

    AmCharts.ready(function () {

    generateChartData();

    createStockChart();

    });

    /** Generando la data especial para este ejemplo */

    function generateChartData() {

    var signalChanged = false;

    var previousValue = 0;

    var signalItem, previousSignal = undefined;

    var firstDate = new Date(2012, 0, 1);

    firstDate.setDate(firstDate.getDate() - num)

    firstDate.setHours(0, 0, 0, 0);

    for (var i = 0; i < num; i++) {

    var newDate = new Date(firstDate);

    newDate.setDate(newDate.getDate() + i);

    var a = Math.round(Math.random() * (40 + i)) + 100 + i;

    // si la tendencia cambia a subida

    if (a != previousValue) {

    signalItem = a > previousValue ? signal[2] : signal[0];

    if ((a > previousValue && previousSignal == 1) ||

    (a < previousValue && previousSignal == -1)){

    signalItem = 0;

    signalChanged = false;

    }

    else {

    previousSignal = signalItem;

    signalChanged = true;

    }

    previousValue = a;

    }

    else {

    signalItem = signal[1];

    signalChanged = false;

    }

    // insertamos la data

    var strItem = "chartData.push({ date: newDate, ";

    if (signalChanged) {

    if (signalItem == 1) {

    strItem += "value0: a, value1: a, balloon1: a";

    }

    else {

    strItem += "value0: a, value1: a, balloon0: a";

    }

    }

    else {

    if (previousSignal == 1) {

    strItem += "value1: a, balloon1: a";

    }

    else {

    strItem += "value0: a, balloon0: a";

    }

    }

    strItem += ", signal: " + signalItem.toString() + " });";

    eval(strItem);

    }

    }

    var chart;

    function createStockChart() {

    chart = new AmCharts.AmStockChart();

    chart.pathToImages = "./amcharts/images/";

    // DATASETS //////////////////////////////////////////

    var dataSet = new AmCharts.DataSet();

    dataSet.fieldMappings = getFieldMappings();

    dataSet.dataProvider = chartData;

    dataSet.categoryField = "date";

    // set data sets to the chart

    chart.dataSets = [dataSet];

    // PANELS ///////////////////////////////////////////

    var stockPanel = new AmCharts.StockPanel();

    // graph of first stock panel

    var graph0 = new AmCharts.StockGraph();

    graph0.type = "line";

    graph0.valueField = "value0";

    graph0.balloonText = "[[balloon0]]";

    graph0.lineColor = "#FF0000";

    graph0.connect = false;

    graph0.lineThickness = 3;

    stockPanel.addStockGraph(graph0);

    var graph1 = new AmCharts.StockGraph();

    graph1.type = "line";

    graph1.valueField = "value1";

    graph1.balloonText = "[[balloon1]]";

    graph1.lineColor = "#00FF00";

    graph1.connect = false;

    graph1.lineThickness = 3;

    stockPanel.addStockGraph(graph1);

    // set panels to the chart

    chart.panels = [stockPanel];

    var cursorSettings = new AmCharts.ChartCursorSettings();

    cursorSettings.valueBalloonsEnabled = true;

    chart.chartCursorSettings = cursorSettings;

    var categoryAxesSettings = chart.categoryAxesSettings;

    categoryAxesSettings.startOnAxis = true;

    categoryAxesSettings.showLastLabel = false;

    var stockEvents = [];

    for (i = 0; i < chartData.length; i++) {

    if (chartData[i].signal != 0) {

    var eventDate = i == 0 ? chartData[0].date : chartData[i - 1].date;

    var eventSignal = chartData[i].signal;

    var eventGraph = eventSignal == 1 ? graph0 : graph1;

    var eventDescription = eventSignal == 1 ? "Model Getting Up" : "Model Getting Down";

    stockEvents.push(createStockEvent(eventDate, eventSignal, eventGraph, eventDescription));

    }

    }

    dataSet.stockEvents = stockEvents;

    chart.write('chartdiv');

    }

    function createStockEvent(eventDate, eventSignal, eventGraph, eventDescription) {

    var eventType = eventSignal == -1 ? "arrowDown" : "arrowUp";

    var eventBGColor = eventSignal == -1 ? "#FF0000" : "#00FF00";

    var stockEvent = {

    date: eventDate,

    type: eventType,

    backgroundColor: eventBGColor,

    graph: eventGraph,

    description: eventDescription

    };

    return stockEvent;

    }

    function getFieldMappings() {

    var map = [];

    var item;

    map.push({ fromField: "value0", toField: "value0" });

    map.push({ fromField: "value1", toField: "value1" });

    map.push({ fromField: "signal", toField: "signal" });

    map.push({ fromField: "balloon0", toField: "balloon0" });

    map.push({ fromField: "balloon1", toField: "balloon1" });

    return map;

    }

    </script>

    </head>

    <body style="background-color:#FFFFFF">

    <div id="chartdiv" style="width:100%; height:600px;"></div>

    </body>

    </html>

    [/code]

    Thanks in advance for your help

    Francisco

Powered by Zendesk