【问题标题】:Amcharts: stacked columns with multiple seriesAmcharts:具有多个系列的堆叠列
【发布时间】:2019-12-15 18:09:36
【问题描述】:

我在一个图表中有多个系列,例如在这个 codepen 中看到的:

let chart = am4core.create("chartdiv", am4charts.XYChart);
      chart.leftAxesContainer.layout = "vertical";
      chart.numberFormatter.numberFormat = '# €';

      chart.data = [
        {name: "2011\nLorient", transport: 56, stay: 200, costByNight: 29, costByKm: 14},
        {name: "2015\nPoitiers\nLa Rochelle", transport: 96, stay: 54, costByNight: 9, costByKm: 23},
        {name: "2016\nRoyaume-Uni", transport: 160, stay: 332, costByNight: 47, costByKm: 62},
        {name: "2016\nBiarritz", transport: 185, stay: 516, costByNight: 74, costByKm: 27},
        {name: "2017\nRoyaume-Uni", transport: 258, stay: 355, costByNight: 36, costByKm: 24},
        {name: "2018\nSingapour\nVietnam\nTaïwan", transport: 1020, stay: 622, costByNight: 41, costByKm: 8},
        {name: "2018\nVietnam", transport: 753, stay: 294, costByNight: 49, costByKm: 8},
        {name: "2019\nCanada", transport: 1074, stay: 342, costByNight: 38, costByKm: 13},
        {name: "2019\nLorient\nGroix", transport: 77, stay: 190, costByNight: 27, costByKm: 20}
      ];

      chart.padding(20, 5, 2, 5);

      // Cities/countries names
      let categoryAxis = chart.xAxes.push(new am4charts.CategoryAxis());
      categoryAxis.renderer.grid.template.location = 0;
      categoryAxis.dataFields.category = "name";
      categoryAxis.renderer.ticks.template.disabled = false;
      categoryAxis.renderer.minGridDistance = 1;
      categoryAxis.renderer.labels.template.wrap = true;
      categoryAxis.renderer.labels.template.maxWidth = 100;
      categoryAxis.renderer.labels.template.fontSize = ".75em";
      categoryAxis.renderer.labels.template.textAlign = "middle";

      /* FIRST CHART */

      // First Y axis
      let valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
      valueAxis.tooltip.disabled = true;
      valueAxis.zIndex = 1;
      valueAxis.renderer.baseGrid.disabled = true;
      valueAxis.renderer.fontSize = "0.8em";

      // Transport
      let series = chart.series.push(new am4charts.ColumnSeries());
      series.name = "Transport";
      series.dataFields.valueY = "transport";
      series.dataFields.categoryX = "name";
      series.yAxis = valueAxis;
      // Configure columns
      series.columns.template.width = am4core.percent(100);
      series.columns.template.tooltipText = "[font-size:13px]Transport : {valueY}";
      series.columns.template.fillOpacity = .8;

      // Logement
      series = chart.series.push(new am4charts.ColumnSeries());
      series.name = "Logement";
      series.dataFields.valueY = "stay";
      series.dataFields.categoryX = "name";
      series.yAxis = valueAxis;
      // Make it stacked
      series.stacked = true;
      // Configure columns
      series.columns.template.width = am4core.percent(100);
      series.columns.template.tooltipText = "[font-size:13px]Logement : {valueY}";
      series.columns.template.fillOpacity = .8;

      /* SECOND CHART */

      let valueAxis2 = chart.yAxes.push(new am4charts.ValueAxis());
      valueAxis2.marginTop = 50;
      valueAxis2.tooltip.disabled = true;
      valueAxis2.renderer.baseGrid.disabled = true;
      valueAxis2.zIndex = 3;
      valueAxis2.renderer.fontSize = "0.8em";

      series = chart.series.push(new am4charts.ColumnSeries());
      series.name = "Prix par 200km";
      series.dataFields.valueY = "costByKm";
      series.dataFields.categoryX = "name";
      series.yAxis = valueAxis2;
      series.stacked = true;
      // Configure columns
      series.columns.template.width = am4core.percent(40);
      series.columns.template.tooltipText = "[font-size:13px]Prix pour 200km : {valueY}";
      series.columns.template.fillOpacity = .8;

      series = chart.series.push(new am4charts.ColumnSeries());
      series.name = "Prix par nuitée";
      series.dataFields.valueY = "costByNight";
      series.dataFields.categoryX = "name";
      series.yAxis = valueAxis2;
      // Configure columns
      series.columns.template.width = am4core.percent(40);
      series.columns.template.tooltipText = "[font-size:13px]Prix par nuit : {valueY}";
      series.columns.template.fillOpacity = .8;
body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
}

#chartdiv {
  width: 100%;
  height: 350px;
}
<script src="//www.amcharts.com/lib/4/core.js"></script>
<script src="//www.amcharts.com/lib/4/charts.js"></script>
<script src="//www.amcharts.com/lib/4/themes/animated.js"></script>
<div id="chartdiv"></div>

我想做但不知道怎么做: - 使顶部列获得两个相应底部列的宽度(如某种 colspan) - 使底部系列相反,具有某种对称性(我尝试了相反 = true,但它让一切都崩溃了) - 两个图表之间有共同的 x 轴

预期的结果是这样的: Expected result

您能帮助实现这些目标中的至少一个吗?谢谢!

【问题讨论】:

    标签: javascript typescript amcharts amcharts4


    【解决方案1】:

    使用您使用的堆叠值轴方法,您可以从三个中得到两个。

    列系列将始终为其他列保留空间,无论是否存在值,因此您不能强制顶部图表的列完全展开。解决方法是创建第二个不可见的类别轴(禁用标签和网格)并将底部系列的xAxis 分配给第二个类别轴:

    let categoryAxis2 = chart.xAxes.push(new am4charts.CategoryAxis());
    categoryAxis2.renderer.grid.template.location = 0;
    categoryAxis2.dataFields.category = "name";
    categoryAxis2.renderer.ticks.template.disabled = true;
    categoryAxis2.renderer.minGridDistance = 1;
    categoryAxis2.renderer.labels.template.disabled = true;
    
    // ...
    series.xAxis = categoryAxis2; //repeat for both bottom chart's series
    // ...
    

    这将使顶部图表的列扩展到整个宽度,因为其他列完全与不同的轴相关联。

    要将底部图表反转为从顶部停止,请在值轴的渲染器对象中将 inversed 设置为 true:

    valueAxis2.renderer.inversed = true;
    

    但是,类别轴不能放在中间。

    下面的演示:

    let chart = am4core.create("chartdiv", am4charts.XYChart);
    chart.leftAxesContainer.layout = "vertical";
    chart.numberFormatter.numberFormat = '# €';
    
    chart.data = [
      {name: "2011\nLorient", transport: 56, stay: 200, costByNight: 29, costByKm: 14},
      {name: "2015\nPoitiers\nLa Rochelle", transport: 96, stay: 54, costByNight: 9, costByKm: 23},
      {name: "2016\nRoyaume-Uni", transport: 160, stay: 332, costByNight: 47, costByKm: 62},
      {name: "2016\nBiarritz", transport: 185, stay: 516, costByNight: 74, costByKm: 27},
      {name: "2017\nRoyaume-Uni", transport: 258, stay: 355, costByNight: 36, costByKm: 24},
      {name: "2018\nSingapour\nVietnam\nTaïwan", transport: 1020, stay: 622, costByNight: 41, costByKm: 8},
      {name: "2018\nVietnam", transport: 753, stay: 294, costByNight: 49, costByKm: 8},
      {name: "2019\nCanada", transport: 1074, stay: 342, costByNight: 38, costByKm: 13},
      {name: "2019\nLorient\nGroix", transport: 77, stay: 190, costByNight: 27, costByKm: 20}
    ];
    
    chart.padding(20, 5, 2, 5);
    
    // Cities/countries names
    let categoryAxis = chart.xAxes.push(new am4charts.CategoryAxis());
    categoryAxis.renderer.grid.template.location = 0;
    categoryAxis.dataFields.category = "name";
    categoryAxis.renderer.ticks.template.disabled = false;
    categoryAxis.renderer.minGridDistance = 1;
    categoryAxis.renderer.labels.template.wrap = true;
    categoryAxis.renderer.labels.template.maxWidth = 100;
    categoryAxis.renderer.labels.template.fontSize = ".75em";
    categoryAxis.renderer.labels.template.textAlign = "middle";
    
    /* FIRST CHART */
    
    // First Y axis
    let valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
    valueAxis.tooltip.disabled = true;
    valueAxis.zIndex = 1;
    valueAxis.renderer.baseGrid.disabled = true;
    valueAxis.renderer.fontSize = "0.8em";
    
    // Transport
    let series = chart.series.push(new am4charts.ColumnSeries());
    series.name = "Transport";
    series.dataFields.valueY = "transport";
    series.dataFields.categoryX = "name";
    series.yAxis = valueAxis;
    // Configure columns
    series.columns.template.width = am4core.percent(100);
    series.columns.template.tooltipText = "[font-size:13px]Transport : {valueY}";
    series.columns.template.fillOpacity = .8;
    
    // Logement
    series = chart.series.push(new am4charts.ColumnSeries());
    series.name = "Logement";
    series.dataFields.valueY = "stay";
    series.dataFields.categoryX = "name";
    series.yAxis = valueAxis;
    // Make it stacked
    series.stacked = true;
    // Configure columns
    series.columns.template.width = am4core.percent(100);
    series.columns.template.tooltipText = "[font-size:13px]Logement : {valueY}";
    series.columns.template.fillOpacity = .8;
    
    /* SECOND CHART */
    
    let valueAxis2 = chart.yAxes.push(new am4charts.ValueAxis());
    valueAxis2.marginTop = 50;
    valueAxis2.renderer.inversed = true;
    valueAxis2.tooltip.disabled = true;
    valueAxis2.renderer.baseGrid.disabled = true;
    valueAxis2.zIndex = 3;
    valueAxis2.renderer.fontSize = "0.8em";
    
    let categoryAxis2 = chart.xAxes.push(new am4charts.CategoryAxis());
    categoryAxis2.renderer.grid.template.location = 0;
    categoryAxis2.dataFields.category = "name";
    categoryAxis2.renderer.ticks.template.disabled = true;
    categoryAxis2.renderer.minGridDistance = 1;
    categoryAxis2.renderer.labels.template.disabled = true;
    
    
    series = chart.series.push(new am4charts.ColumnSeries());
    series.name = "Prix par 200km";
    series.dataFields.valueY = "costByKm";
    series.dataFields.categoryX = "name";
    series.yAxis = valueAxis2;
    series.stacked = true;
    // Configure columns
    series.columns.template.width = am4core.percent(40);
    series.columns.template.tooltipText = "[font-size:13px]Prix pour 200km : {valueY}";
    series.columns.template.fillOpacity = .8;
    series.xAxis = categoryAxis2;
    
    series = chart.series.push(new am4charts.ColumnSeries());
    series.name = "Prix par nuitée";
    series.dataFields.valueY = "costByNight";
    series.dataFields.categoryX = "name";
    series.yAxis = valueAxis2;
    series.xAxis = categoryAxis2;
    // Configure columns
    series.columns.template.width = am4core.percent(40);
    series.columns.template.tooltipText = "[font-size:13px]Prix par nuit : {valueY}";
    series.columns.template.fillOpacity = .8;
    body {
      font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
    }
    
    #chartdiv {
      width: 100%;
      height: 350px;
    }
    <script src="//www.amcharts.com/lib/4/core.js"></script>
    <script src="//www.amcharts.com/lib/4/charts.js"></script>
    <script src="//www.amcharts.com/lib/4/themes/animated.js"></script>
    <div id="chartdiv"></div>

    【讨论】:

    • 谢谢!我不知道“反转”属性,我玩“相反”没有成功。为了实现将 x 轴放在中间,我考虑过使用容器和 2 个图表而不是一个……你怎么看?
    • 这可行,但如果您希望图表/轴对齐,则需要手动设置图表/轴边距,这可能很挑剔。不过绝对可行。
    • 那我试试。感谢您提供的所有信息!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多