在写 d3 的相关内容,不过我 JS 掌握不是很多。 题目要求组块化,我就想把画矩形的函数给封装起来,当做一个方法,以后画矩形的话只要调用一下就行了。以前学过一些 sql,考虑用 sql 的方式拼装,结果好像不太行,不知道有谁能指导一下怎么做么,或者有什么好的方法。
这里是原来我写的代码
var rect = svg.selectAll("rect")
.data(dataset) // 绑定数据
.enter() // 获取 enter
.append("rect") // 添加 rect 元素,绑定和数组长度一致
.attr("fill", "steelblue") // 设置填充颜色
.attr("x", function(d, i){ // x
return padding.left + i * rectStep;
})
.attr("y", function(d){ //y
return height - padding.bottom - d;
})
.attr("width", rectWidth) // 设置矩形的高度
.attr("height", function(d){
return d;
})
这里开始是我封装的代码,但是封装的方式不对,我是想把自己固定想要传的参数写清楚,其他不固定的参数,就放在一个数组里传进来,最后的参数[["attr",["fill", "blue"]],["attr",["fill","pink"]] 放进来以后,可以在 svg 最后执行的位置,执行 .attr("fill", "blue").attr("fill", "pink") 如果是其他的方法当然执行的不同,不过自己试了一下,根本行不通啊!!!原来的代码不难,就是封装没思路,请指教一下谢谢!
另外补充一点,我知道可以 attr({key1: value1}, {key2, value2})的方式设置多个属性,但是这种方法的思路有局限性,就比如说要给它添加一个 mouseover 事件,没办法添加,类似这里结尾
svg.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) { return x(d.city); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.money); })
.attr("height", function(d) { return height - y(d.money); })
.on('mouseover', tip.show)
.on('mouseout', tip.hide)
封装代码:
function Rect(svg, data, width, height, x, y, argsarray ){
var length = argsarray.length;
var co ='';
for (var i = 0; i < argsarray.length; i++) {
co += '.' +argsarray[i][0] + '("' + argsarray[i][1][0] + '","' +argsarray[i][1][1] +'")';
console.log(co);
// 这里输出 .attr("fill","blue").attr("fill","pink")
}
svg.selectAll("rect")
.data(data) // 绑定数据
.enter() // 获取 enter
.append("rect") // 添加 rect 元素,绑定和数组长度一致
.attr("x", x)
.attr("y", y)
.attr("width", width) // 设置矩形的高度
.attr("height", height)
//.(eval(co));
}
var getRectx = function(d, i){ return padding.left + i * rectStep};
var getRecty = function(d){ return height - padding.bottom - d};
var getHeight = function(d){ return d};
Rect(svg, dataset, rectWidth, getHeight, getRectx, getRecty, [["attr",["fill", "blue"]],["attr",["fill","pink"]]]);
这里设置成蓝色又设置成粉色就是看看数组中多属性能不能使用。
1
dingz 2018-08-29 08:45:41 +08:00
先把你的默认参数都封装到一个对象里, 就比如叫作 defaultOptions 吧,放到全局变量。
然后这个函数接受一个新的 options 对象作为参数, 函数里把 options 继承 defaultOptions。 然后函数后续就对这个参数对象要干嘛干嘛的用即可。 .attr("fill", options.fill) .attr("x", options.x) .attr("y", options.y) .attr("width", options.width) // 设置矩形的高度 .attr("height", options.height) |
2
murmur 2018-08-29 08:49:50 +08:00
如果我是用户 我希望我要的最终东西就和网上一大堆各种 chart 一样 如果只是到 rect 级别的封装还远远不够
你现在做什么东西 面试题么 |
4
dingz 2018-08-29 09:38:32 +08:00 1
如果一定要按你的思路来可以这样
// argsObj 是个对象,他的属性对应 attr 或者 on, //其下的属性也是个对象对应属性名或事件, //最终叶子属性可以是数组或者不是 var argsObj = { attr: { fill: ['red', 'blue'], height: 1213 }, on: { mouseover: tip.show, mouseout: tip.hide } }; function Rect(svg, data, width, height, x, y, argsObj ){ for (var i in argsObj) { if (argsObj[i] && typeof argsObj[i] === 'object') { for (var j in argsObj[i]) { if (Array.isArray(argsObj[i][j])) for (var k = 0; k < argsObj[i][j].length; k++) svg[i](j, argsObj[i][j][k]); else svg[i](j, argsObj[i][j]); } } } } |
5
dingz 2018-08-29 09:39:14 +08:00
或者把不固定参数交给一个回调函数做
function afterDraw(svg) { svg.attr("fill", "steelblue").attr("fill", "red").on('mouseover', tip.show); } function Rect(svg, data, width, height, x, y, afterDraw) { ...... if (afterDraw) afterDraw(svg); } |