我一直在学习JS (主要是使用D3),我想将应用于其中。我编写了一个简单的脚本,允许您用更容易读的代码构建条形图。
canvas.initialise()
canvas.margin(20, 100, 60, 20)
canvas.width(500)
canvas.height(400)
canvas.finalise()
svg = canvas.get_canvas()
my_data = [["A", 10], ["B", -3], ["C", 4]]
bar_chart.data(my_data)
bar_chart.x_scale([0, canvas.get_width()], .1, 1)
bar_chart.y_scale([canvas.get_height(), 0])
bar_chart.formatting(".2f")
bar_chart.add_to(svg)的库代码
var canvas = (function ()
{
// private
var svg;
var margin, width, height, x_pos, y_pos;
var initialise = function () { svg = d3.select("body").append("svg") }
var set_position = function (x, y) { x_pos = x; y_pos = y;}
var set_margins = function (top, bottom, left, right) { margin = { top: top, bottom: bottom, left: left, right: right }; }
var set_width = function (val) { width = val - margin.left - margin.right; svg.attr("width", val + margin.left + margin.right); }
var set_height = function (val) { height = val - margin.top - margin.bottom; svg.attr("height", val + margin.top + margin.bottom); }
var finalise = function ()
{
svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.attr("x", x_pos)
.attr("y", y_pos)
}
return {
initialise: initialise,
position: set_position,
margin: set_margins,
width: set_width,
height: set_height,
finalise: finalise,
get_canvas: function () { return svg },
get_margin: function () { return margin },
get_width: function () { return width },
get_height: function () { return height }
}
}());
var bar_chart = (function ()
{
var data,
x, y,
xAxis, yAxis,
formatting;
var set_data = function(data_input)
{
data = data_input;
}
var set_x_scale = function (interval, padding, outer_padding)
{
x = d3.scale.ordinal()
.rangeRoundBands(interval, padding, outer_padding)
}
var set_y_scale = function (interval)
{
y = d3.scale.linear()
.range(interval)
}
var set_formatting = function (fmt)
{
formatting = d3.format(fmt);
}
var add_to = function(svg)
{
console.log(data)
xAxis = d3.svg.axis()
.scale(x) // call ticks?
yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.tickFormat(formatting)
x.domain(data.map(function (d) { return d[0] }))
y.domain([-5, 15]) //make general
// Put the axes on the canvas
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(" + canvas.get_margin().left + "," + canvas.get_height() + ")")
.call(xAxis)
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + canvas.get_margin().left + ",0)")
.call(yAxis)
// Put the data in rectangle elements and put on canvas
var bars = svg.selectAll(".bar")
.data(data)
.enter()
.append("rect")
.attr("class", "bar")
.attr("width", x.rangeBand())
.attr("x", function (d) { return x(d[0]) + canvas.get_margin().left }) // hmm...
.attr("y", function (d)
{
if (d[1] < 0)
{
return y(0);
}
else
return y(d[1])
})
.attr("height", function (d) { return y(0) - y(Math.abs(d[1])) });
}
return {
data: set_data,
formatting: set_formatting,
x_scale: set_x_scale,
y_scale: set_y_scale,
add_to: add_to
}
}());我所关切的是:
发布于 2016-06-02 11:13:13
你在你的关注列表中提出了一些非常好的观点,特别是你的第一个问题及其背后的原因:
模块背后的想法是创建自包含的、单一用途的代码。canvas模块取决于用户调用函数的顺序。您的bar_chart特别需要,因为它的addTo方法要求直接访问canvas模块。好的模块简单明了。他们将一些复杂的任务封装在一个黑匣子里,让用户不知道引擎盖下面发生了什么。这使得用户可以专注于使用模块,而不是担心可能的副作用。
下面是用户更友好的制作条形图的方法:
var canvas = createCanvas({
margins: {
top: 20,
left: 60,
right: 20,
bottom: 100
},
width: 420, // 500 - 60 - 20, maybe the 500 totalWidth is more intuitive
height: 280 // 400 - 20 - 100
});
drawBarChart({
canvas: canvas,
data: [["A", 10], ["B", -3], ["C", 4]],
range: [-5, 15],
numberFormat: ".2f", // optional parameter
barInnerPadding: 0.1, // optional parameter
barOuterPadding: 1 // optional parameter
});这为开发人员提供了一个用于创建图表的CSS-esque界面。不必担心按错误的顺序调用函数,所有属性都是命名的,这使您可以轻松地使任何属性都是可选的。
下面是我对提供上述用户界面的代码所做的一个重构的JSFiddle。
我重新分析了一些事情以及原因:
createSVG函数,因为我觉得画布做了两件事:存储格式化数据和构建/格式化/存储svg。(而且,与OOP相比,我更喜欢函数式编程范式)bar_chart模块浓缩为单个drawBarChart函数,因为将所有逻辑拆分以创建图表会增加必须按特定顺序调用函数的依赖性。(不过,我认为在我的drawBarChart中应该有一些内联函数。强调内联;如果我们没有重复的代码,而且函数没有在其他地方调用,那么使函数只在其他地方取代代码,而不是实际执行它的地方)drawBarChart函数做特定的格式化工作,那么他们可以,但如果他们不想这样做,那么他们就不必担心它。x和y在canvas中的位置不为您的程序提供任何功能。考虑把它们移走。(如果你最终想在以后添加它们,那么你可以在以后添加它们,目前它们只是分散注意力)。
只要你的风格不妨碍你的可读性,就去做吧。我提出这个问题的唯一原因是因为您的一些代码行变得非常非常长。例如:
var set_height = function (val) { height = val - margin.top - margin.bottom; svg.attr("height", val + margin.top + margin.bottom); }这个函数可以在多行上更容易读懂。
我对你的d3印象深刻!前一段时间我学到了一些东西,但没有充分的理由坚持下去。保持良好的工作状态!
https://codereview.stackexchange.com/questions/129351
复制相似问题