目标是做条形图,要带排序功能。
一开始看的 demo 全都是原生 JS 写出来的,所以就用原生 JS 写出来了效果,但是题目要求用 OOP 的思想,再加上本来就要 webpack 打包,就开始重新写,但是发现了一些问题,不知道怎么解决
原生 JS 代码内容
构建 d3 参数
构建比例尺(但没有定义域)——>坐标轴
取 csv 数据{
给比例尺添加定义域
根据 比例尺定义域坐标 添加矩形形成条形图
给 checkbox 添加排序事件
事件方法{
修改构建比例尺的定义域降序排列添加动画
}
}
我的解决思路是这样的,之前看到一个写彩票的 demo,是把所有功能都写成类,最后一个 Lottery 类继承自所有功能类,生成实例就能运行,我也开始封装,封装一个 Makegraph 类,里面三个方法
Base Calculate Interface Time
继承上面 Lottery new xxx = Lottery(); It works!
但是发现这样的思路存在问题,修改原来已经画好的内容要获取定义域,进行修改,我这样封装似乎从 3.事件里获取不到 1.画图 里面的定义域,更别提修改了,而且肯定只能改动构建成坐标轴的定义域,用 selector 获取也没用啊
所以想请教一下应该用什么样的思想来构造,这个问题想了大半天解决不出来。
附上 demo 的代码,写原生的思路是按它的来的 https://bl.ocks.org/mbostock/3885705
自己写半天写不出来的
import * as d3 from "d3";
class Makegraph{
// initSort(){
// d3.select("input").on("change", change);
// }
draw_bar(){
let margin = {top:40, right:40, bottom:40, left:40};
let drawarea = {width: 550, height: 500};
let width = drawarea.width - margin.left - margin.right;
let height = drawarea.height - margin.top - margin.bottom;
let svg = d3.selectAll(".draw-left")
.append('svg')
.attr('width', drawarea.width)
.attr('height', drawarea.height)
.append("g")
.attr("transform", `translate(${margin.left}, ${margin.top})`);
d3.csv("./public/data.csv").then(function(data) {
data.forEach((d)=>{
d.money = +d.money;
return d;
});
let xdomain = (data.map(function(d) { return d.city; }))
let ydomain = [0, d3.max(data, function(d) { return d.money; })]
let xScale = d3.scaleBand()
.domain(xdomain)
.rangeRound([0, width]).padding(0.1);
let yScale = d3.scaleLinear()
.domain(ydomain)
.range([height, 0]);
let xAxis = d3.axisBottom(xScale);
let yAxis = d3.axisLeft(yScale);
svg.append("g")
.attr("class", "x_axis")
.attr("transform", `translate(0, ${height})`)
.call(xAxis);
svg.append("g")
.attr("class", "axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", "0.71em")
.attr("text-anchor", "end")
.text("money");
svg.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", (d) => xScale(d.city))
.attr("y", (d) => yScale(d.money))
.attr("width", xScale.bandwidth())
.attr("height", (d)=> (height - yScale(d.money)))
.attr("fill","steelblue");
});
}
}
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.