【问题标题】:Stacked Area Amchart passing dynamic dataStacked Area Amchart 传递动态数据
【发布时间】:2019-11-14 10:20:38
【问题描述】:

**参考 - https://www.amcharts.com/demos/stacked-area/ 它只在 y 轴上绘制一个用户,而我希望所有用户数据都在堆叠线区域中。

我想我需要在数据系列上创建一个函数,但真的不知道该怎么做。 我希望 X 轴为 Date ,Y 轴为显示多行用户 [A,B,C,D] 的值刻度 **

< script >
  var df = [{
    "User": "A",
    "Date": 1570492800000,
    "value_act": 3.4
  }, {
    "User": "B",
    "Date": 1570492800000,
    "value_act": 1.6
  }, {
    "User": "C",
    "Date": 1570492800000,
    "value_act": 4.7
  }, {
    "User": "D",
    "Date": 1570492800000,
    "value_act": 0.0
  }, {
    "User": "A",
    "Date": 1570579200000,
    "value_act": 3.4
  }, {
    "User": "B",
    "Date": 1570579200000,
    "value_act": 1.6
  }, {
    "User": "C",
    "Date": 1570579200000,
    "value_act": 4.7
  }, {
    "User": "D",
    "Date": 1570579200000,
    "value_act": 0.0
  }, {
    "User": "A",
    "Date": 1570838400000,
    "value_act": 3.4
  }, {
    "User": "B",
    "Date": 1570838400000,
    "value_act": 1.6
  }, {
    "User": "C",
    "Date": 1570838400000,
    "value_act": 4.7
  }, {
    "User": "D",
    "Date": 1570838400000,
    "value_act": 0.0
  }]


console.log(df);

am4core.ready(function() {

  // Themes begin
  am4core.useTheme(am4themes_animated);
  // Themes end

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

  chart.data = df;

  chart.dateFormatter.inputDateFormat = "yyyy";
  var dateAxis = chart.xAxes.push(new am4charts.DateAxis());
  dateAxis.renderer.minGridDistance = 60;
  dateAxis.startLocation = 0.5;
  dateAxis.endLocation = 0.5;
  dateAxis.baseInterval = {
    timeUnit: "Date",
    count: 1
  }

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


  var series = chart.series.push(new am4charts.LineSeries());
  series.dataFields.dateX = "Date";
  series.name = "User";
  series.dataFields.valueY = "value_act";
  series.tooltipText = "[#000]{valueY.value}[/]";
  series.tooltip.background.fill = am4core.color("#FFF");
  series.tooltip.getStrokeFromObject = true;
  series.tooltip.background.strokeWidth = 3;
  series.tooltip.getFillFromObject = false;
  series.fillOpacity = 0.6;
  series.strokeWidth = 2;
  series.stacked = true;

  chart.cursor = new am4charts.XYCursor();
  chart.cursor.xAxis = dateAxis;
  chart.scrollbarX = new am4core.Scrollbar();

  // Add a legend
  chart.legend = new am4charts.Legend();
  chart.legend.position = "top";

});
// end am4core.ready()
<
/script>
<script src="https://www.amcharts.com/lib/4/core.js"></script>
<script src="https://www.amcharts.com/lib/4/charts.js"></script>
<script src="https://www.amcharts.com/lib/4/themes/animated.js"></script>
<div id="lines1"></div>

【问题讨论】:

    标签: javascript charts amcharts4


    【解决方案1】:

    要有多条线,需要在图表中添加多个系列

    每个系列都需要数据中的特定键

    所以,不是所有人都拥有"User" 的密钥,
    我们需要 4 个单独的键 --> "UserA", "UserB", "UserC", "UserD"

    var df = [{
      "UserA": "A",
      "Date": 1570492800000,
      "value_act": 3.4
    }, {
      "UserB": "B",
      "Date": 1570492800000,
      "value_act": 1.6
    }, {
      "UserC": "C",
      "Date": 1570492800000,
      "value_act": 4.7
    }, {
      "UserD": "D",
      "Date": 1570492800000,
      "value_act": 0.0
    }, {
    

    请参阅以下工作 sn-p...

    am4core.ready(function() {
    
    // Themes begin
    am4core.useTheme(am4themes_animated);
    // Themes end
    
      var df = [{
        "UserA": "A",
        "Date": 1570492800000,
        "value_act": 3.4
      }, {
        "UserB": "B",
        "Date": 1570492800000,
        "value_act": 1.6
      }, {
        "UserC": "C",
        "Date": 1570492800000,
        "value_act": 4.7
      }, {
        "UserD": "D",
        "Date": 1570492800000,
        "value_act": 0.0
      }, {
        "UserA": "A",
        "Date": 1570579200000,
        "value_act": 3.4
      }, {
        "UserB": "B",
        "Date": 1570579200000,
        "value_act": 1.6
      }, {
        "UserC": "C",
        "Date": 1570579200000,
        "value_act": 4.7
      }, {
        "UserD": "D",
        "Date": 1570579200000,
        "value_act": 0.0
      }, {
        "UserA": "A",
        "Date": 1570838400000,
        "value_act": 3.4
      }, {
        "UserB": "B",
        "Date": 1570838400000,
        "value_act": 1.6
      }, {
        "UserC": "C",
        "Date": 1570838400000,
        "value_act": 4.7
      }, {
        "UserD": "D",
        "Date": 1570838400000,
        "value_act": 0.0
      }]
    
    am4core.ready(function() {
    
      // Themes begin
      am4core.useTheme(am4themes_animated);
      // Themes end
    
      var chart = am4core.create("lines1", am4charts.XYChart);
    
      chart.data = df;
    
      chart.dateFormatter.inputDateFormat = "yyyy";
      var dateAxis = chart.xAxes.push(new am4charts.DateAxis());
      dateAxis.renderer.minGridDistance = 60;
      dateAxis.startLocation = 0.5;
      dateAxis.endLocation = 0.5;
      dateAxis.baseInterval = {
        timeUnit: "Date",
        count: 1
      }
    
      var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
      valueAxis.tooltip.disabled = true;
    
    
      var series = chart.series.push(new am4charts.LineSeries());
      series.dataFields.dateX = "Date";
      series.name = "UserA";
      series.dataFields.valueY = "value_act";
      series.tooltipText = "[#000]{valueY.value}[/]";
      series.tooltip.background.fill = am4core.color("#FFF");
      series.tooltip.getStrokeFromObject = true;
      series.tooltip.background.strokeWidth = 3;
      series.tooltip.getFillFromObject = false;
      series.fillOpacity = 0.6;
      series.strokeWidth = 2;
      series.stacked = true;
    
      var series = chart.series.push(new am4charts.LineSeries());
      series.dataFields.dateX = "Date";
      series.name = "UserB";
      series.dataFields.valueY = "value_act";
      series.tooltipText = "[#000]{valueY.value}[/]";
      series.tooltip.background.fill = am4core.color("#FFF");
      series.tooltip.getStrokeFromObject = true;
      series.tooltip.background.strokeWidth = 3;
      series.tooltip.getFillFromObject = false;
      series.fillOpacity = 0.6;
      series.strokeWidth = 2;
      series.stacked = true;
    
      var series = chart.series.push(new am4charts.LineSeries());
      series.dataFields.dateX = "Date";
      series.name = "UserC";
      series.dataFields.valueY = "value_act";
      series.tooltipText = "[#000]{valueY.value}[/]";
      series.tooltip.background.fill = am4core.color("#FFF");
      series.tooltip.getStrokeFromObject = true;
      series.tooltip.background.strokeWidth = 3;
      series.tooltip.getFillFromObject = false;
      series.fillOpacity = 0.6;
      series.strokeWidth = 2;
      series.stacked = true;
    
      var series = chart.series.push(new am4charts.LineSeries());
      series.dataFields.dateX = "Date";
      series.name = "UserD";
      series.dataFields.valueY = "value_act";
      series.tooltipText = "[#000]{valueY.value}[/]";
      series.tooltip.background.fill = am4core.color("#FFF");
      series.tooltip.getStrokeFromObject = true;
      series.tooltip.background.strokeWidth = 3;
      series.tooltip.getFillFromObject = false;
      series.fillOpacity = 0.6;
      series.strokeWidth = 2;
      series.stacked = true;
    
      chart.cursor = new am4charts.XYCursor();
      chart.cursor.xAxis = dateAxis;
      chart.scrollbarX = new am4core.Scrollbar();
    
      // Add a legend
      chart.legend = new am4charts.Legend();
      chart.legend.position = "top";
    
    });
    
    });
    #lines1 {
      width: 100%;
      height: 500px;
    }
    <script src="https://www.amcharts.com/lib/4/core.js"></script>
    <script src="https://www.amcharts.com/lib/4/charts.js"></script>
    <script src="https://www.amcharts.com/lib/4/themes/animated.js"></script>
    <div id="lines1"></div>

    编辑

    动态构建单独的系列,
    让我们先恢复到原始数据集,
    其中每一行具有相同的 "User" 键,但值不同。

    var df = [{
      "User": "A",
      "Date": 1570492800000,
      "value_act": 3.4
    }, {
      "User": "B",
      "Date": 1570492800000,
      "value_act": 1.6
    }, {
      "User": "C",
      "Date": 1570492800000,
      "value_act": 4.7
    }, {
    ...
    

    首先,我们使用一个数组来查找不同的用户值。 (A, B, C, D, etc...)
    在这个例程中,我们还修改数据,为每个系列创建我们需要的单独键。
    换句话说,我们通过附加值来创建一个新键 --> "UserA"
    并删除原来的"User" 键(尽管这可能不是必需的)。

    var distinctUsers = [];
    df.forEach(function (row, index) {
      // find distinct user values
      if (distinctUsers.indexOf(row.User) === -1) {
        distinctUsers.push(row.User);
      }
    
      // create new key
      df[index]['User' + row.User] = row.User;
    
      // delete old key
      delete df[index].User;
    });
    

    接下来,我们需要合并行,使得每个日期只有一行,
    如下...

    var df = [{
      "UserA": 3.4,
      "UserB": 1.6,
      "UserC": 4.7,
      "UserD": 0.0,
      "Date": 1570492800000,
    }, {
      "UserA": 3.4,
      "UserB": 1.6,
      "UserC": 4.7,
      "UserD": 0.0,
      "Date": 1570579200000,
    }, {
      "UserA": 3.4,
      "UserB": 1.6,
      "UserC": 4.7,
      "UserD": 0.0,
      "Date": 1570838400000,
    }];
    

    我们可以使用 map 方法...

    // combine date rows
    df = distinctDates.map(function (date) {
      // build new combined row
      var combinedRow = {
        Date: date
      };
    
      // add user values for date
      distinctUsers.forEach(function (user) {
        df.forEach(function (row) {
          if ((row.hasOwnProperty("User" + user)) && (row.Date === date)) {
            combinedRow["User" + user] = row["User" + user];
          }
        });
      });
    
      return combinedRow;
    });
    

    然后我们使用不同值的数组,
    创造每个独特的系列。

    // create unique series
    distinctUsers.forEach(function (user) {
      var series = chart.series.push(new am4charts.LineSeries());
      series.dataFields.dateX = "Date";
      series.name = "User" + user;  // <-- use new key for series
      series.dataFields.valueY = "value_act";
      series.tooltipText = "[#000]{valueY.value}[/]";
      series.tooltip.background.fill = am4core.color("#FFF");
      series.tooltip.getStrokeFromObject = true;
      series.tooltip.background.strokeWidth = 3;
      series.tooltip.getFillFromObject = false;
      series.fillOpacity = 0.6;
      series.strokeWidth = 2;
      series.stacked = true;
    });
    

    请参阅以下工作 sn-p...

    am4core.ready(function() {
    
    // Themes begin
    am4core.useTheme(am4themes_animated);
    // Themes end
      var df = [{
        "User": "A",
        "Date": 1570492800000,
        "value_act": 3.4
      }, {
        "User": "B",
        "Date": 1570492800000,
        "value_act": 1.6
      }, {
        "User": "C",
        "Date": 1570492800000,
        "value_act": 4.7
      }, {
        "User": "D",
        "Date": 1570492800000,
        "value_act": 0.0
      }, {
        "User": "A",
        "Date": 1570579200000,
        "value_act": 3.4
      }, {
        "User": "B",
        "Date": 1570579200000,
        "value_act": 1.6
      }, {
        "User": "C",
        "Date": 1570579200000,
        "value_act": 4.7
      }, {
        "User": "D",
        "Date": 1570579200000,
        "value_act": 0.0
      }, {
        "User": "A",
        "Date": 1570838400000,
        "value_act": 3.4
      }, {
        "User": "B",
        "Date": 1570838400000,
        "value_act": 1.6
      }, {
        "User": "C",
        "Date": 1570838400000,
        "value_act": 4.7
      }, {
        "User": "D",
        "Date": 1570838400000,
        "value_act": 0.0
      }];
    
      // find distinct users & dates, apply value to user key
      var distinctUsers = [];
      var distinctDates = [];
      df.forEach(function (row, index) {
        // find distinct user values
        if (distinctUsers.indexOf(row.User) === -1) {
          distinctUsers.push(row.User);
        }
    
        // find distinct date values
        if (distinctDates.indexOf(row.Date) === -1) {
          distinctDates.push(row.Date);
        }
    
        // create new key
        df[index]['User' + row.User] = row.value_act;
    
        // delete old key
        delete df[index].User;
      });
    
      // combine date rows
      df = distinctDates.map(function (date) {
        // build new combined row
        var combinedRow = {
          Date: date
        };
    
        // add user values for date
        distinctUsers.forEach(function (user) {
          df.forEach(function (row) {
            if ((row.hasOwnProperty("User" + user)) && (row.Date === date)) {
              combinedRow["User" + user] = row["User" + user];
            }
          });
        });
    
        return combinedRow;
      });
    
    
    am4core.ready(function() {
    
      // Themes begin
      am4core.useTheme(am4themes_animated);
      // Themes end
    
      var chart = am4core.create("lines1", am4charts.XYChart);
    
      chart.data = df;
    
      chart.dateFormatter.inputDateFormat = "yyyy";
      var dateAxis = chart.xAxes.push(new am4charts.DateAxis());
      dateAxis.renderer.minGridDistance = 60;
      dateAxis.startLocation = 0.5;
      dateAxis.endLocation = 0.5;
      dateAxis.baseInterval = {
        timeUnit: "Date",
        count: 1
      }
    
      var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
      valueAxis.tooltip.disabled = true;
    
      // create unique series
      distinctUsers.forEach(function (user) {
        var series = chart.series.push(new am4charts.LineSeries());
        series.dataFields.dateX = "Date";
        series.name = "User" + user;
        series.dataFields.valueY = "User" + user;
        series.tooltipText = "[#000]{valueY.value}[/]";
        series.tooltip.background.fill = am4core.color("#FFF");
        series.tooltip.getStrokeFromObject = true;
        series.tooltip.background.strokeWidth = 3;
        series.tooltip.getFillFromObject = false;
        series.fillOpacity = 0.6;
        series.strokeWidth = 2;
        series.stacked = true;
      });
    
      chart.cursor = new am4charts.XYCursor();
      chart.cursor.xAxis = dateAxis;
      chart.scrollbarX = new am4core.Scrollbar();
    
      // Add a legend
      chart.legend = new am4charts.Legend();
      chart.legend.position = "top";
    
    });
    
    });
    #lines1 {
      width: 100%;
      height: 500px;
    }
    <script src="https://www.amcharts.com/lib/4/core.js"></script>
    <script src="https://www.amcharts.com/lib/4/charts.js"></script>
    <script src="https://www.amcharts.com/lib/4/themes/animated.js"></script>
    <div id="lines1"></div>

    【讨论】:

    • 感谢您帮助我。但问题是用户数据将是动态的。因此,JS 不会知道是否要传递 4 个或 8 个用户。我们如何手动处理?这才是真正的挑战。
    • 嘿伙计。很大的帮助。只是最后一个查询!为什么 y 轴和值不同步?日期或数据格式有问题吗? @WhiteHat
    • 我觉得是因为每个日期都有多行,上面改了EDIT...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-10
    • 1970-01-01
    • 2021-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-31
    相关资源
    最近更新 更多