Search code examples
javascriptamcharts

Amcharts v3 multiple category step chart


I am trying to produce 2 graphs (step lines) on the same chart with independent X-axis (category) values. As close as I have been able to get is:

AmCharts.makeChart("price-level-compare",
        {
            type: "serial",
            dataProvider:
                [
                    {qty1: 1,   price1: 2.3, qty2: 1, price2: 3.6},
                    {qty1: 2,   price1: 2.2, qty2: 5, price2: 3.3},
                    {qty1: 10,  price1: 1.97,qty2: 10, price2: 3.1},
                    {qty1: 100, price1: 1.54,qty2: 200,price2: 1.1},
                    {qty1: 500, price1: 1.2, qty2: 300,price2: 1.0}
                ],
            graphs: [{
                "id":"g1",
                "type": "step",
                "lineThickness": 2,
                "bullet":"square",
                "bulletAlpha":0,
                "bulletSize":4,
                "bulletBorderAlpha":0,
                "valueField": "price1"
            },{
                "id":"g2",
                "type": "step",
                "lineThickness": 2,
                "bullet":"square",
                "bulletAlpha":0,
                "bulletSize":4,
                "bulletBorderAlpha":0,
                "valueField": "price2"
            }],
            "categoryField": "qty1"

        }
    );

which produces this incorrect graph:

Graph image

I don't see how to specify another "categoryField" that names "qty2" as the X-axis values for the "price2" values.


Solution

  • Serial charts don't support multiple categoryFields.

    Given that your data is numeric, an XY chart is a better fit. Just set each graph's xField and yField to point to the appropriate values in your data.

      graphs: [
        {
          id: "g1",
          type: "step",
          lineThickness: 2,
          bullet: "square",
          bulletAlpha: 0,
          bulletSize: 4,
          bulletBorderAlpha: 0,
          xField: "qty1",
          yField: "price1"
        },
        {
          id: "g2",
          type: "step",
          lineThickness: 2,
          bullet: "square",
          bulletAlpha: 0,
          bulletSize: 4,
          bulletBorderAlpha: 0,
          xField: "qty2",
          yField: "price2"
        }
    

    Demo below.

     AmCharts.makeChart("chartdiv", {
      type: "xy",
      dataProvider: [
        { qty1: 1, price1: 2.3, qty2: 1, price2: 3.6 },
        { qty1: 2, price1: 2.2, qty2: 5, price2: 3.3 },
        { qty1: 10, price1: 1.97, qty2: 10, price2: 3.1 },
        { qty1: 100, price1: 1.54, qty2: 200, price2: 1.1 },
        { qty1: 500, price1: 1.2, qty2: 300, price2: 1.0 }
      ],
      graphs: [
        {
          id: "g1",
          type: "step",
          lineThickness: 2,
          bullet: "square",
          bulletAlpha: 0,
          bulletSize: 4,
          bulletBorderAlpha: 0,
          xField: "qty1",
          yField: "price1"
        },
        {
          id: "g2",
          type: "step",
          lineThickness: 2,
          bullet: "square",
          bulletAlpha: 0,
          bulletSize: 4,
          bulletBorderAlpha: 0,
          xField: "qty2",
          yField: "price2"
        }
      ]
    });
    html, body {
      width: 100%;
      height: 100%;
      margin: 0px;
    }
    
    #chartdiv {
    	width: 100%;
    	height: 100%;
    }
    <script src="//www.amcharts.com/lib/3/amcharts.js"></script>
    <script src="//www.amcharts.com/lib/3/xy.js"></script>
    <script src="//www.amcharts.com/lib/3/themes/light.js"></script>
    <div id="chartdiv"></div>

    Unfortunately step lines aren't supported, so this is the best you can do in v3.

    v4's XY charts can handle step lines with XY numeric values. You can create a StepLineSeries and set the valueY and valueX properties for your X and Y values

    // Create series
    var series1 = chart.series.push(new am4charts.StepLineSeries());
    series1.dataFields.valueX = "qty1";
    series1.dataFields.valueY = "price1";
    series1.strokeWidth = 2;
    
    var bullet1 = series1.bullets.push(new am4charts.Bullet());
    var square = bullet1.createChild(am4core.Rectangle);
    square.width = 10;
    square.height = 10;
    square.horizontalCenter = "middle";
    square.verticalCenter = "middle";
    
    bullet1.tooltipText = "Price: {valueX}\nQty: {valueY}";
    //repeat for your second series
    

    Full demo below:

    // Create chart instance
    var chart = am4core.create("chartdiv", am4charts.XYChart);
    
    // Add data
    chart.data = [
            { qty1: 1, price1: 2.3, qty2: 1, price2: 3.6 },
            { qty1: 2, price1: 2.2, qty2: 5, price2: 3.3 },
            { qty1: 10, price1: 1.97, qty2: 10, price2: 3.1 },
            { qty1: 100, price1: 1.54, qty2: 200, price2: 1.1 },
            { qty1: 500, price1: 1.2, qty2: 300, price2: 1.0 }
      ];
    
    // Create axes
    var xAxis = chart.xAxes.push(new am4charts.ValueAxis());
    xAxis.renderer.minGridDistance = 40;
    
    // Create value axis
    var yAxis = chart.yAxes.push(new am4charts.ValueAxis());
    
    // Create series
    var series1 = chart.series.push(new am4charts.StepLineSeries());
    series1.dataFields.valueX = "qty1";
    series1.dataFields.valueY = "price1";
    series1.strokeWidth = 2;
    
    var bullet1 = series1.bullets.push(new am4charts.Bullet());
    var square = bullet1.createChild(am4core.Rectangle);
    square.width = 10;
    square.height = 10;
    square.horizontalCenter = "middle";
    square.verticalCenter = "middle";
    
    bullet1.tooltipText = "Price: {valueX}\nQty: {valueY}";
    
    var series2 = chart.series.push(new am4charts.StepLineSeries());
    series2.dataFields.valueX = "qty2";
    series2.dataFields.valueY = "price2";
    
    var bullet2 = series2.bullets.push(new am4charts.CircleBullet());
    var square2 = bullet2.createChild(am4core.Rectangle);
    square2.width = 10;
    square2.height = 10;
    square2.horizontalCenter = "middle";
    square2.verticalCenter = "middle";
    
    bullet2.tooltipText = "Price: {valueX}\nQty: {valueY}";
    html, body {
    width: 100%;
    height: 100%;
    margin: 0;
    }
    
    #chartdiv {
      width: 100%;
      height: 100%;
    }
    <script src="https://www.amcharts.com/lib/4/core.js"></script>
    <script src="https://www.amcharts.com/lib/4/charts.js"></script>
    <div id="chartdiv"></div>

    More information on v4 XY charts can be found here.