我正在尝试使用 CodeMirror 编辑器构建 D3.js,但是 D3.js 无法正确显示我在其中输入的任何内容。我错过了什么?
I'm trying to build D3.js by using CodeMirror editor, but anything I input in there can't be properly visualized by D3.js. What am I missing?
我是 D3.js 和 CodeMirror(还有 Whosebug,请原谅我的错误)的新手,我想为我的最新项目尝试一些很酷的东西,所以这两个是我最好的选择,但是我遇到了一些问题。请帮助我注意我做错了什么,以及使这个程序运行的最佳解决方案是什么。很高兴我们这里有很好的论坛。
所以,长话短说,我正在尝试使用 D3.js 和 CodeMirror 作为我的编辑器来构建可视化工具。例如,this is what I try to visualize, but instead of reading the morley.csv
data (hard-coded),我想从我的 CodeMirror 编辑器中输入数据。所以这就是我为编辑写的:
<textarea id="values"></textarea>
<script>
var editor = CodeMirror.fromTextArea(values, {
lineNumbers: true,
matchBrackets: true,
theme : '3024-day'
});
</script>
<a id="gen" class="btn btn-primary btn-block" role="button">Generate Visualization</a>
对于可视化生成器来说:
<div class="row" id="chart">
<script>
d3.select("#gen").on("click", function(){
d3.event.preventDefault();
d3.select("#chart svg").remove();
var dataset = editor.getValue();
var margin = {top: 10, right: 50, bottom: 20, left: 50},
width = 120 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var min = Infinity,
max = -Infinity;
var chart = d3.box()
.whiskers(iqr(1.5))
.width(width)
.height(height);
d3.csv(dataset, function(error, csv) {
if (error) throw error;
var data = [];
csv.forEach(function(x) {
var e = Math.floor(x.Expt - 1),
r = Math.floor(x.Run - 1),
s = Math.floor(x.Speed),
d = data[e];
if (!d) d = data[e] = [s];
else d.push(s);
if (s > max) max = s;
if (s < min) min = s;
});
chart.domain([min, max]);
var svg = d3.select("#chart").selectAll("svg")
.data(data)
.enter().append("svg")
.attr("class", "box")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.bottom + margin.top)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.call(chart);
setInterval(function() {
svg.datum(randomize).call(chart.duration(1000));
}, 2000);
});
function randomize(d) {
if (!d.randomizer) d.randomizer = randomizer(d);
return d.map(d.randomizer);
}
function randomizer(d) {
var k = d3.max(d) * .02;
return function(d) {
return Math.max(min, Math.min(max, d + k * (Math.random() - .5)));
};
}
function iqr(k) {
return function(d, i) {
var q1 = d.quartiles[0],
q3 = d.quartiles[2],
iqr = (q3 - q1) * k,
i = -1,
j = d.length;
while (d[++i] < q1 - iqr);
while (d[--j] > q3 + iqr);
return [i, j];
};
}
});
</script>
</div>
让我们假设我对输入数据使用了相同的 morley.csv
。
不知怎么的,它没有按我的计划工作。我不明白我在这里遗漏了什么,但我猜它一定与 d3.csv
无法解析我从 textarea values
的输入有关。输出 div chart
总是什么都不显示..
感谢您的帮助,虽然我是新来的。非常感谢任何帮助。
1。
在较新的版本中将 d3.csv()
更改为 d3.csv.parse()
或 d3.csvParse()
。前者只接受一个文件名,后者接受一串CSV数据。
调试并确保您的数据集变量确实是逗号分隔的字符串。
2。
另外,如果您只需要像 [1,2,3] 这样的平面数组,我认为您需要将所有代码从回调函数中取出,然后执行以下操作:
data = d3.csv.parse(dataset);
然后继续您现有的代码。
在csv.parse调用中有回调函数的原因只是构造返回的数组;例如如果您的数组元素是其中包含多个值的对象,您可以在回调函数中进行设置。
我是 D3.js 和 CodeMirror(还有 Whosebug,请原谅我的错误)的新手,我想为我的最新项目尝试一些很酷的东西,所以这两个是我最好的选择,但是我遇到了一些问题。请帮助我注意我做错了什么,以及使这个程序运行的最佳解决方案是什么。很高兴我们这里有很好的论坛。
所以,长话短说,我正在尝试使用 D3.js 和 CodeMirror 作为我的编辑器来构建可视化工具。例如,this is what I try to visualize, but instead of reading the morley.csv
data (hard-coded),我想从我的 CodeMirror 编辑器中输入数据。所以这就是我为编辑写的:
<textarea id="values"></textarea>
<script>
var editor = CodeMirror.fromTextArea(values, {
lineNumbers: true,
matchBrackets: true,
theme : '3024-day'
});
</script>
<a id="gen" class="btn btn-primary btn-block" role="button">Generate Visualization</a>
对于可视化生成器来说:
<div class="row" id="chart">
<script>
d3.select("#gen").on("click", function(){
d3.event.preventDefault();
d3.select("#chart svg").remove();
var dataset = editor.getValue();
var margin = {top: 10, right: 50, bottom: 20, left: 50},
width = 120 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var min = Infinity,
max = -Infinity;
var chart = d3.box()
.whiskers(iqr(1.5))
.width(width)
.height(height);
d3.csv(dataset, function(error, csv) {
if (error) throw error;
var data = [];
csv.forEach(function(x) {
var e = Math.floor(x.Expt - 1),
r = Math.floor(x.Run - 1),
s = Math.floor(x.Speed),
d = data[e];
if (!d) d = data[e] = [s];
else d.push(s);
if (s > max) max = s;
if (s < min) min = s;
});
chart.domain([min, max]);
var svg = d3.select("#chart").selectAll("svg")
.data(data)
.enter().append("svg")
.attr("class", "box")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.bottom + margin.top)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.call(chart);
setInterval(function() {
svg.datum(randomize).call(chart.duration(1000));
}, 2000);
});
function randomize(d) {
if (!d.randomizer) d.randomizer = randomizer(d);
return d.map(d.randomizer);
}
function randomizer(d) {
var k = d3.max(d) * .02;
return function(d) {
return Math.max(min, Math.min(max, d + k * (Math.random() - .5)));
};
}
function iqr(k) {
return function(d, i) {
var q1 = d.quartiles[0],
q3 = d.quartiles[2],
iqr = (q3 - q1) * k,
i = -1,
j = d.length;
while (d[++i] < q1 - iqr);
while (d[--j] > q3 + iqr);
return [i, j];
};
}
});
</script>
</div>
让我们假设我对输入数据使用了相同的 morley.csv
。
不知怎么的,它没有按我的计划工作。我不明白我在这里遗漏了什么,但我猜它一定与 d3.csv
无法解析我从 textarea values
的输入有关。输出 div chart
总是什么都不显示..
感谢您的帮助,虽然我是新来的。非常感谢任何帮助。
1。
在较新的版本中将 d3.csv()
更改为 d3.csv.parse()
或 d3.csvParse()
。前者只接受一个文件名,后者接受一串CSV数据。
调试并确保您的数据集变量确实是逗号分隔的字符串。
2。 另外,如果您只需要像 [1,2,3] 这样的平面数组,我认为您需要将所有代码从回调函数中取出,然后执行以下操作:
data = d3.csv.parse(dataset);
然后继续您现有的代码。
在csv.parse调用中有回调函数的原因只是构造返回的数组;例如如果您的数组元素是其中包含多个值的对象,您可以在回调函数中进行设置。