且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何在 Vizframe 图表中实现线性回归线?

更新时间:2023-11-22 22:36:46

不幸的是,您有一些可视化图表固有的限制.即:

Unfortunately, you have some limitations inherent to the viz charts. Namely:

  • 您不能向图表添加倾斜"参考线(= 趋势线).您只能通过 参考线 功能.查看关于此的(非直观)文档:可视化图表文档(查看 plotArea.referenceLine.line;它只是一个数字 = 将是水平/垂直线,具体取决于您的图表类型或方向).
  • 您不能将散点图与折线图结合使用.如果您查看相同的 Viz Charts Documentation,你会看到在左侧的组合章节"中,没有线 - 散点"组合.
  • You cannot add "oblique" reference lines (= the trend line) to the chart. You can only add vertical / horizontal ones via the Reference Line feature. Check out the (non-intuitive) documentation on this: Viz Charts Documentation (look at the plotArea.referenceLine.line; it is just a number = will be a horizontal / vertical line depending on your chart type or orientation).
  • You cannot combine a scatter plot with a line chart. If you look in the same Viz Charts Documentation, you will see that in the Combination "chapter" on the left hand side, there is no "Line - Scatter" combination.

此外,您的 X 值 (AwDate) 是 字符串 形式的 ABAP 样式日期.使用日期/时间图表来正确显示它们更合适.无论如何,当您使用日期时,回归更有意义.否则,您的数据是分类的",您可以进行回归的唯一方法是对它们进行排序并考虑它们在 X 轴上等距 - 如果您拥有非等距数据(例如您的示例中的数据),则通常不需要.

Also, your X values (AwDate) are ABAP-style dates as string. It is more appropriate to use a date / time chart to correctly display them. Anyway, regression makes a lot more sense when you use dates. Otherwise your data is "categorical" and the only way you can make regression is by sorting them and considering them equidistant on the X axis - not what you would normally want if you have non-equidistant data (like the one in your example).

我的建议是:

  • 使用折线图代替散点图(这样您还可以显示趋势线).
  • 将 ABAP 样式的字符串转换为日期,以便您可以使用时间序列图表.顺便说一下,您的示例数据中有一些错误"日期:201600401".
  • 根据您的需要进行回归并将其添加为单独的趋势"系列.您需要为其他系列的每个点计算趋势"系列上的一个点(基本上,您必须为 ProductCollection 中的每一行添加趋势"属性).如果您使用的是 OData 模型,那么您将需要切换到 JSON 客户端模型或使用格式化程序执行一些难看的解决方法.

根据要求,我在这里做了一个示例实现:https://jsfiddle.net/93mx0yvt/23/.我从这里借用的回归算法:https://dracoblue.net/dev/linear-least-squares-in-javascript/.代码的要点是:

As requested, I made an example implementation here: https://jsfiddle.net/93mx0yvt/23/. The regression algorithm I borrowed from here: https://dracoblue.net/dev/linear-least-squares-in-javascript/. The main points of the code are:

// format for parsing the ABAP-style dates
var oFormat = DateFormat.getDateInstance({
  pattern: "yyyyMMdd"
});

// maps an ProductCollection entry to a new object
// which has the parsed date (and only the needed attributes)
var fnMapData = function(oEntry) {
  return {
    date: oFormat.parse(oEntry.AwdDate),
    current: oEntry.Current,
    historical: oEntry.Hist
  };
};

var fnProcessData = function(oD) {
  var aEntries = oD.ProductCollection.map(fnMapData),
    aXs = aEntries.map(function(oE) { // get the Xs
      // we take the millis to be able to do arithmetics
      return oE.date.getTime(); 
    }),
    aYs = aEntries.map(function(oE) { // get the Ys (hist)
      return oE.historical;
    }),
    //changed the function to only return only result Ys
    aRs = findLineByLeastSquares(aXs, aYs);

  //save the Ys into the result
  for (var i = 0; i < aEntries.length; ++i) {
    aEntries[i].trend = aRs[i];
  }
  return {
    data: aEntries
  };
};

然后您可以在 JSONModel 中使用 fnProcessData 函数返回的数据,然后基于它构建一个简单的多系列日期/时间折线图.

You can use then the data returned by the fnProcessData function inside a JSONModel and then build a simple multi-series date/time line chart based on it.