gpt4 book ai didi

javascript - Protovis 比例交互线图示例

转载 作者:行者123 更新时间:2023-12-02 20:12:51 25 4
gpt4 key购买 nike

我正在关注规模交互示例@http://mbostock.github.com/protovis/docs/invert.html我正在尝试绘制 2 条线系列图表。

我的JSON文件如下:

var psSeriesData =
[{"Dates":["1-10","2-10","3-10","4-10","5-10","6-10","7-10","8-10"],"ScoresForA":
[78.78,79.79,78.78,78.78,78.78,79.79,79.79,76.92],"ScoresForB":
[78.78,79.79,78.78,78.78,78.78,79.79,79.79,76.92]}]

我打算使用日期绘制 x 轴,并分别使用 ScoresForA 和 ScoresForB 绘制 2 折线图,但在经过多次调整后我很困惑如何做到这一点。

我的代码如下:

                var data = pv.range(2).map(function(i) {
return pv.range(0, 10, .1).map(function(x) {
return {x: psSeriesData.Dates, y: psSeriesData.ScoresForA,ScoresForB };
});
});

/* Chart dimensions and scales. */
var w = 400,
h = 200,
x = pv.Scale.linear(0, 9.9).range(0, w),
y = pv.Scale.linear(0, 10).range(0, h),
i = -1;

/* The root panel. */
var vis = new pv.Panel()
.width(w)
.height(h)
.bottom(20)
.left(20)
.right(10)
.top(5);

/* Y-ticks. */
vis.add(pv.Rule)
.data(pv.range(100))
.visible(function() !(this.index % 2))
.bottom(function(d) Math.round(y(d)) - .5)
.strokeStyle(function(d) d ? "#eee" : "#000")
.anchor("left").add(pv.Label)
.text(function(d) (d * 10).toFixed(0) );

/* X-ticks. */
vis.add(pv.Rule)
.data(x.ticks())
.visible(function(d) d > 0)
.left(function(d) Math.round(x(d)) - .5)
.strokeStyle(function(d) d ? "#eee" : "#000")
.anchor("bottom").add(pv.Label)
.text(function(d) d.toFixed());

/* A panel for each data series. */
var panel = vis.add(pv.Panel)
.data(data);

/* The line. */
var line = panel.add(pv.Line)
.data(function(d) d)
.left(function(d) x(d.x))
.bottom(function(d) y(d.y))
.lineWidth(3);

/* The mouseover dots and label. */
line.add(pv.Dot)
.visible(function() i >= 0)
.data(function(d) [d[i]])
.fillStyle(function() line.strokeStyle())
.strokeStyle("#000")
.size(20)
.lineWidth(1)
.add(pv.Dot)
.left(10)
.bottom(function() this.parent.index * 12 + 10)
.anchor("right").add(pv.Label)
.text(function(d) (d.y * 10).toFixed(5));

/* An invisible bar to capture events (without flickering). */
vis.add(pv.Bar)
.fillStyle("rgba(0,0,0,.001)")
.event("mouseout", function() {
i = -1;
return vis;
})
.event("mousemove", function() {
var mx = x.invert(vis.mouse().x);
i = pv.search(data[0].map(function(d) d.x), mx);
i = i < 0 ? (-i - 2) : i;
return vis;
});



vis.render();

我做错了什么?

nrabinowitz 给出输入后:

     var psSeriesData = {
"Dates": ["1/10","2/10","3/10","4/10","5/10","6/10","7/10","8/10"],
"ScoresForA": [78.78,79.79,78.78,78.78,78.78,79.79,79.79,76.92],
"ScoresForB": [78.78,79.79,78.78,78.78,78.78,79.79,79.79,76.92]
};

// start by iterating over the two keys for your time series data
var data = ["ScoresForA","ScoresForB"].map(function(seriesKey) {
// use pv.range to walk through the indexes of the
// date array (basically the same as a for loop)
return pv.range(0, psSeriesData.Dates.length)
// map these indexes to an array of objects
.map(function(dateIndex) {
// now return an object with the date index
// and series value for that index
return {
x: dateIndex,
y: psSeriesData[seriesKey][dateIndex]
}
});
});


/* Chart dimensions and scales. */
var w = 400,
h = 200,
x = pv.Scale.linear(0, 9.9).range(0, w),
y = pv.Scale.linear(0, 10).range(0, h),
i = -1;

/* The root panel. */
var vis = new pv.Panel()
.width(w)
.height(h)
.bottom(20)
.left(20)
.right(10)
.top(5);

/* Y-ticks. */
vis.add(pv.Rule)
.data(pv.range(100))
.visible(function() !(this.index % 2))
.bottom(function(d) Math.round(y(d)) - .5)
.strokeStyle(function(d) d ? "#eee" : "#000")
.anchor("left").add(pv.Label)
.text(function(d) (d * 10).toFixed(0) );

/* X-ticks. */
vis.add(pv.Rule)
//.data(function(d) [d[i].Dates])
.data(pv.range(0, psSeriesData.Dates.length).map(function(a) (psSeriesData[a].Dates)))
.visible(function(d) d > 0)
.left(function(d) Math.round(x(d)) - .5)
.strokeStyle(function(d) d ? "#eee" : "#000")
.anchor("bottom").add(pv.Label)
.text(function(d) (d).toFixed());

/* A panel for each data series. */
var panel = vis.add(pv.Panel)
.data(data);

/* The line. */
var line = panel.add(pv.Line)
.data(function(d) d)
.left(function(d) x(d.x))
.bottom(function(d) y(d.y))
.lineWidth(3);

/* The mouseover dots and label. */
line.add(pv.Dot)
.visible(function() i >= 0)
.data(function(d) [d[i]])
.fillStyle(function() line.strokeStyle())
.strokeStyle("#000")
.size(20)
.lineWidth(1)
.add(pv.Dot)
.left(10)
.bottom(function() this.parent.index * 12 + 10)
.anchor("right").add(pv.Label)
.text(function(d) (d.y ).toFixed(5));

/* An invisible bar to capture events (without flickering). */
vis.add(pv.Bar)
.fillStyle("rgba(0,0,0,.001)")
.event("mouseout", function() {
i = -1;
return vis;
})
.event("mousemove", function() {
var mx = x.invert(vis.mouse().x);
i = pv.search(data[0].map(function(d) d.x), mx);
i = i < 0 ? (-i - 2) : i;
return vis;
});



vis.render();

即使我使用了 map 函数和数组引用,日期仍然没有显示为 x 轴。读取“日期”属性似乎存在问题。任何建议

错误:类型错误:无法读取未定义的属性“日期”

最佳答案

在处理这样的可视化时(尤其是在遵循 Protovis 示例时)要做的第一件事是确保您的数据采用您需要的格式。我还没有经历过您的所有代码都在这里,但是您在前面的数据上遇到了一些明显的问题:

  • 为什么你的初始数据在数组中?是否有任何理由包含封闭的直大括号(即 psSeriesData = [{ ... }] 中的外括号)?我在您提供的代码中看不到任何原因,它只会让事情变得困惑(例如 psSeriesData.Dates 未定义 - 您需要引用 psSeriesData[0].日期)。

  • 我根本不清楚你在初始数据设置代码中做了什么,但我很确定它没有给你你想要的东西 - 它看起来像是盲目的剪切 -从示例中粘贴,即使它不适用。该示例使用 pv.range 生成假数据 - 您不需要这个,您有真实数据,您可以演练它。

从这里开始的最佳方法是了解数据应该是什么样子。在示例中,数据的生成方式如下:

data = pv.range(3).map(function(i) {
return pv.range(0, 10, .1).map(function(x) {
return {x: x, y: i + Math.sin(x) + Math.random() * .5 + 2};
});
});

在控制台中运行它,您将看到生成的数据如下所示:

[
[
{
x: 0.1,
y: 2.34
},
// ...
],
// ...
]

外部数组保存不同的时间序列;每个时间序列都是一个对象数组,例如 {x:0.1, y:2.34}。如果您的数据与此不同,则它不适用于示例代码。

您的初始数据应该可以正常工作,但您需要将其转换为正确的格式。这里的一个问题是日期列表 - 这些是字符串,而不是数字,除非您将它们转换为 Date 对象,否则您将无法将它们用作数据(这是一个真正的痛苦,如果可能的话,避免使用)或将它们映射到数字 - 后者在这里很容易,因为它们处于常规系列中。 (如果日期间隔不均匀,这一切都会更加复杂,但现在让我们忘记这一点。)您可以仅使用日期的索引作为x值,然后使用两个系列作为 y 值。

将这些放在一起,您可以像这样格式化数据:

// note - no enclosing array
var psSeriesData = {
"Dates": ["1-10","2-10","3-10","4-10","5-10","6-10","7-10", "8-10"],
"ScoresForA": [78.78,79.79,78.78,78.78,78.78,79.79,79.79,76.92],
"ScoresForB": [78.78,79.79,78.78,78.78,78.78,79.79,79.79,76.92]
};

// start by iterating over the two keys for your time series data
var data = ["ScoresForA","ScoresForB"].map(function(seriesKey) {
// use pv.range to walk through the indexes of the
// date array (basically the same as a for loop)
return pv.range(0, psSeriesData.Dates.length)
// map these indexes to an array of objects
.map(function(dateIndex) {
// now return an object with the date index
// and series value for that index
return {
x: dateIndex,
y: psSeriesData[seriesKey][dateIndex]
}
});
});

还有很多其他方法可以做到这一点,但要点是你可以得到一个像这样的数组:[[{x:0, y:79.79}, ...] ,...]。我还没有查看您的其余代码,但现在您的数据格式正确,您应该能够用代码中的真实数据替换示例中的假数据,并使整个过程正常工作预期(尽管您需要更改示例中有关 xy 预期最大值和最小值的任何假设)。

关于javascript - Protovis 比例交互线图示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6751180/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com