【问题标题】:ES6/TypeScript way to generate a polyline from an arrayES6/TypeScript 从数组生成折线的方法
【发布时间】:2017-06-12 10:01:09
【问题描述】:

我想从我拥有的结构中生成几条 SVG 折线:

data = [item0, item1, ...., item50]
item0 = {y1: 10, y2: 100, ...[other properties]...}
item1 = {y1: 1000, y2: 50, ...}
item2 = {y1: 500, y2: 40, ...}

所以结构是一个项目数组,其中一个项目有多个 Y 值。 x 值是通过迭代结构 (x*10) 来确定的。

每个“y”的输出应该是一个字符串,像这样:“x0,y1[0] x1,y1[1] x2,y1[2]...”

polyLine1 = "0,10 10,100 20,500..."
polyLine2 = "0,1000 10,50 20,40 ..."

我可以使用 underscore.js 或类似的东西来做到这一点:

polyLine1 = "";
_.each (data, function(item, index){
    polyLine1 += "" + index*10 + "," + item.y1
}
polyLine2 = "";
_.each (data, function(item, index){
    polyLine2 += "" + index*10 + "," + item.y2
}

我正在寻找一种更智能的方法来使用 lambda/箭头语法初始化完整的输出结构:

this.polyLines = {
    polyLine1 = ...,// iterate data, pick y1 property, map x and y, reduce/join to a string
    polyLine2 = ...,
}

作为参考,我将 TypeScript 与 Ionic2 (Angular2) 一起使用。 我知道我可以使用模板绑定来做到这一点(这可能会更慢且可读性更低),但我只是想学习。

【问题讨论】:

  • 有什么方法可以显示一些真实数据吗?我会期待更像data = [{y1: 10, y2: 100}, {y1: 11, y2: 101}] 的东西,然后它到底应该产生什么,因为你一开始说你想要一个字符串,但后来你有了这个lines 结构......
  • 我每秒左右通过串行从板上获取一些 ADC 值。这些范围从 0 到 1024。我想在图表上显示最后 50 个。 Lines 表示折线,每个 ADC 输入一条。
  • 这里是元数据,但我不明白为什么有人会反对这个。这是将一些“旧”的 underscore.js 代码样式转换为新的基于 lambda 的样式的问题。 svg 和 polylines 标签是我批准的建议编辑。
  • 顺便说一句,我在这个问题上没有看到任何反对意见。我有足够的代表能够看到分裂,它说 0 upvotes 和 0 downvotes。好吧,现在它表示赞成,因为您已包含有关输入和输出的更多信息:)。
  • 对不起,我认为最初所有问题都以 1 票开始,可能会将 SO 与其他网站混淆 :)

标签: svg typescript polyline


【解决方案1】:

这会产生我认为您正在寻找的东西。基本上,reduce(来自 ES5.1)就是你想要的。我正在使用来自 ES6 的 lambdas (arrow functions) 和 template literals,以及来自 ES5.1 的 String.prototype.trim()Object.keys()

let data = [{
  y1: 10,
  y2: 100
}, {
  y1: 1000,
  y2: 50
}]
let keyReduction = (b) => Object.keys(b).reduce((c, d, x) => c += `${x*10} ${b[d]} `, "");
let polyLines = data.reduce((a, b, i) => {
  a[`polyLine${i+1}`] = keyReduction(b).trim();
  return a;
}, {});
console.log(JSON.stringify(polyLines))

我不确定这些是否适用于折线,因为我没有做过任何 SVG,但我相信您可以对其进行调整以满足您的需求。

看来您需要逗号。您可以执行相同的代码,但使用逗号:

let data = [{
  y1: 10,
  y2: 100
}, {
  y1: 1000,
  y2: 50
}]
let keyReduction = (b) => Object.keys(b).reduce((c, d, x) => c += `${x*10},${b[d]} `, "");
let polyLines = data.reduce((a, b, i) => {
  a[`polyLine${i+1}`] = keyReduction(b).trim();
  return a;
}, {});
console.log(JSON.stringify(polyLines))

这是另一个示例,将每个属性名称分解为最终输出的单独属性:

let data = [{
  y1: 10,
  y2: 100
}, {
  y1: 1000,
  y2: 50
}]
let polyLines = data.reduce((a, b, i) => {
  Object.keys(b).forEach((k) => {
    a[k] = (a[k] || "") + (i * 10) + "," + b[k] + " ";
    });
  return a;
}, {});
console.log(JSON.stringify(polyLines))

【讨论】:

  • 哇,太好了,超出了我的要求。我并不希望自动处理所有子字段,但这是一个很好的技巧。
  • 我编辑了这个问题,而不是在这里提供评论。您提供的代码很好,但没有做我想要的,这是我的错误,要求是如何制定的。如果您愿意提供替代答案,我将不胜感激。我在这里创建了一个 jsfiddle:jsfiddle.net/42b8uown,其中包含一些真实数据,但在那里实现打字稿的方式可能存在问题。
  • 是的,我不知道那里的 TypeScript 是怎么回事。如果您查看呈现的 JavaScript,就好像它完成了一半:acc[(``polyLine${ + line)] = i + },${ + item.sensorValue;
  • 我添加了一个没有模板文字的示例,并在这里添加了你的小提琴的一个分支:jsfiddle.net/6cw9ee4k/1 这似乎有效。
  • 谢谢。请参阅我的第 3 次修订 (jsfiddle.net/42b8uown/3) 以及最后的评论和 OP 中的编辑。
猜你喜欢
  • 2017-05-16
  • 2015-04-16
  • 2017-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-25
  • 2017-02-16
  • 1970-01-01
相关资源
最近更新 更多