如何在amchart中创建分组瀑布图?

时间:2018-11-08 07:51:51

标签: javascript d3.js amcharts

我想使用AmCharts创建分组的瀑布图。 我的数据将为类别提供两个维度,为值提供一个维度。 例如,假设我将“人口”作为我的categoryPath,将“值”作为我的valuePath。我希望“人口”字段显示为该年的总价值。然后,我还有一个称为“状态”的字段,该字段将是递增/递减值(浮动列)。我将如何实现这一目标?

这是我的数据:`{

"Population 1":[
      {
         "waterfallData.PopulationName":"Population 1",
         "waterfallData.Value":-2333,
         "waterfallData.State":"State 2"
      },
      {
         "waterfallData.PopulationName":"Population 1",
         "waterfallData.Value":8786,
         "waterfallData.State":"State 1"
      }
   ],
   "Population 2":[
      {
         "waterfallData.PopulationName":"Population 2",
         "waterfallData.Value":-1000,
         "waterfallData.State":"State 2"
      },
      {
         "waterfallData.PopulationName":"Population 2",
         "waterfallData.Value":5000,
         "waterfallData.State":"State 1"
      }
   ],
   "Population 3":[
      {
         "waterfallData.PopulationName":"Population 3",
         "waterfallData.Value":-2000,
         "waterfallData.State":"State 2"
      },
      {
         "waterfallData.PopulationName":"Population 3",
         "waterfallData.Value":3000,
         "waterfallData.State":"State 1"
      }
   ]
}

我正在使用amCharts版本3。Amchart设置:

var settings = {
      type: "serial",
      theme: "light",
      dataProvider: transformedData,
      legend: {
        data: [{ title: "Increasing", color: "#54cb6a" }, { title: "Decreasing", color: "#cc4b48" }]
      },
      valueAxes: valueAxe,
      startDuration: 1,
      graphs: [
        {
          balloonText: "<span style='color:[[color]]'>[[category]]</span><br><b>$[[balloonValue]]</b>",
          colorField: "color",
          fillAlphas: 0.8,
          labelText: "$[[balloonValue]]",
          lineColor: "#BBBBBB",
          openField: "open",
          type: "column",
          valueField: "close",
          adaptiveLabelPosition: true
        }
      ],
      trendLines: xPath ? trendLines : [{
        "dashLength": 3,
        "finalCategory": "Income B",
        "finalValue": 11.13,
        "initialCategory": "Income A",
        "initialValue": 11.13,
        "lineColor": "#888888"
      }, {
        "dashLength": 3,
        "finalCategory": "Expenses A",
        "finalValue": 15.81,
        "initialCategory": "Income B",
        "initialValue": 15.81,
        "lineColor": "#888888"
      }, {
        "dashLength": 3,
        "finalCategory": "Expenses B",
        "finalValue": 12.92,
        "initialCategory": "Expenses A",
        "initialValue": 12.92,
        "lineColor": "#888888"
      }, {
        "dashLength": 3,
        "finalCategory": "Revenue",
        "finalValue": 8.64,
        "initialCategory": "Expenses B",
        "initialValue": 8.64,
        "lineColor": "#888888"
      }],
      columnWidth: 0.6,
      categoryField: xPath,
      categoryAxis: {
        gridPosition: "start",
        axisAlpha: 0,
        gridAlpha: 0.1,
        title: categoryLabel,
        labelRotation: 45
      },
      export: {
        enabled: true
      }
    };

因此,从此分组数据开始。如何分配打开和关闭值以匹配预期的输出?


示例输出如下:

enter image description here

1 个答案:

答案 0 :(得分:0)

开放值为0的数据项将从底部开始。您可以将它们用作每个组(人口)的基础,并相应地计算后续数据项。这是amcharts 4的示例: https://codepen.io/asif-rahman-the-reactor/pen/yLLwZzp

var chart = am4core.create("chartdiv", am4charts.XYChart);

// using math in the data instead of final values just to illustrate the idea of Waterfall chart
// a separate data field for step series is added because we don't need last step (notice, the last data item doesn't have stepValue)
chart.data = [{
    category: "Net revenue",
    value: 8786,
    open: 0,
    stepValue: 8786,
    color: am4core.color("#c3dc67")
}, {
    category: "Cost of sales",
    value: 8786 - 2786,
    open: 8786,
    stepValue: 8786 - 2786,
    color: am4core.color("#dc6788")
}, {
    category: "Operating expenses",
    value: 8786 - 2786 - 1786,
    open: 8786 - 2786,
    stepValue: 8786 - 2786 - 1786,
    color: am4core.color("#dc6967")
}, {
    category: "Income from equity",
    value: 8786 - 2786 - 1786  + 1465,
    open: 8786 - 2786 - 1786 ,
    stepValue: 8786 - 2786 - 1786  + 1465,
    color: am4core.color("#67dc75")
}, {
    category: "Operating income",
    value: 8786 - 2786 - 1786  + 1465,
    open: 0,
  stepValue: 8786 - 2786 - 1786  + 1465,
    color: am4core.color("#67dc98")
}
, {
    category: "Expense 1",
    value: 8786 - 2786 - 1786  + 1465-1200,
    open: 8786 - 2786 - 1786  + 1465,
    stepValue: 8786 - 2786 - 1786  + 1465-1200,
    color: am4core.color("red")
}, {
    category: "Gain 2",
    value: 8786 - 2786 - 1786  + 1465-1200+2500,
    open: 8786 - 2786 - 1786  + 1465-1200,
    stepValue: 8786 - 2786 - 1786  + 1465-1200+2500,
    color: am4core.color("green")
}, {
    category: "Net Profit",
    value: 8786 - 2786 - 1786 + 1465-1200+2500,
    open: 0,
    color: am4core.color("orange")
}];

var categoryAxis = chart.xAxes.push(new am4charts.CategoryAxis());
categoryAxis.dataFields.category = "category";
categoryAxis.renderer.minGridDistance = 50;

var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());

var columnSeries = chart.series.push(new am4charts.ColumnSeries());
columnSeries.dataFields.categoryX = "category";
columnSeries.dataFields.valueY = "value";
columnSeries.dataFields.openValueY = "open";

var columnTemplate = columnSeries.columns.template;
columnTemplate.strokeOpacity = 0;
columnTemplate.propertyFields.fill = "color";

var label = columnTemplate.createChild(am4core.Label);
label.align = "center";
label.valign = "middle";
label.adapter.add("text", function(text, target) {
  if (!target.dataItem) {
    return text;
  }
  var value = Math.abs(target.dataItem.dataContext.value - target.dataItem.dataContext.open);
  return target.numberFormatter.format(value, "$#,## a");
});

var stepSeries = chart.series.push(new am4charts.StepLineSeries());
stepSeries.dataFields.categoryX = "category";
stepSeries.dataFields.valueY = "stepValue";
stepSeries.noRisers = true;
stepSeries.stroke = am4core.color("#000");
stepSeries.strokeDasharray = "3,3";

// because column width is 80%, we modify start/end locations so that step would start with column and end with next column
stepSeries.startLocation = 0.1;
stepSeries.endLocation = 1.1;