
在写 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 如果一定要按你的思路来可以这样 // 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); } |