实现上述方法
组织数据:function createAllAttr()
createAllAttr () {
const { padding, axis, width, barWidth, ...otherParams } = this.$props
const currentWidth = width - padding.left - padding.right // 统计图实际占用宽度
const barStep = currentWidth / axis.xAxisData.length // 把整个统计图分成横坐标数量那么多等分
/**
getTrueNum() 方法的作用是获取当前元素的实际宽度
getTrueNum (father, percent) {
if (typeof percent === 'number') {
return percent > father ? father : percent
} else {
return father * this.percentToPoint(percent)
}
}
percentToPoint (percent) {
let point = percent.replace('%', '').replace(' ', '')
point = point / 100
return point
}
根据父级宽度与子元素百分比单位的宽度,计算子元素实际所占的宽度
*/
const myBarWidth = Tools.prototype.getTrueNum(barStep, barWidth)
const spacing = (barStep - myBarWidth) // 根据紧挨着的每等分的宽度,与条形实际宽度,计算相邻的条形之间的间距
// 返回加工好的数据
return {
width,
padding,
axis,
...otherParams,
contentWidth: currentWidth,
barWidth: myBarWidth,
spacing: spacing
}
}
创建画布:function createSvg()
createSvg (data, bar) {
const { width, height } = bar
const svg = d3.select('#barGraph')
.append('svg')
.attr('width', width)
.attr('height', height)
return svg
}
绘制坐标轴: function addScale()
addScale (svg, data, bar) {
const {contentWidth, height, axis, padding} = bar
/**
建立x轴的比例尺
scaleBand() 与 scaleLinear() 是d3中比例尺的类型,其他的可以自行了解
scaleLinear: 线性比例尺
scaleBand:非连续性比例尺
range:输出域
domain:输入域
将domain中的数据集映射到range数据集中
*/
const xScale = d3.scaleBand().range([0, contentWidth]).domain(axis.xAxisData)
// 定义x轴
const xAxis = d3.axisBottom(xScale)
// 建立y轴的比例尺
const yScale = d3.scaleLinear().range([height - padding.top - padding.bottom, 0]).domain([0, d3.max(data)])
// 定义y轴
const yAxis = d3.axisLeft(yScale)
// 将x轴添加到svg元素中
svg.append('g')
.classed('axis-x', true)
.attr('transform', `translate(${padding.left}, ${height - padding.bottom})`)
.call(xAxis)
// 将y轴添加到svg元素中
svg.append('g')
.classed('axis-y', true)
.attr('transform', `translate(${padding.left}, ${padding.bottom})`)
.call(yAxis)
// 返回比例尺,在绘制条形等情况时有用
return {
xScale,
yScale
}
}
d3比例尺大全
绘制条形:function addRect()
// 每一个rect是通过左上角坐标定位的
addRect (svg, data, bar, xScale, yScale) {
const { barWidth, height, axis, color, padding, spacing } = bar
const rect = svg.selectAll('rect')
.data(data)
.enter()
.append('rect')
// 添加背景色与样式
.attr('fill', color)
.attr('class', 'my-rect')
// 整个统计图相对于外层svg元素的位置,在此为左偏移padding.left上偏移padding.top
.attr('transform', `translate(${padding.left},${padding.top})`)
// 左上角横坐标
.attr('x', (d, i) => { return xScale(axis.xAxisData[i]) + spacing })
// rect 的宽
.attr('width', barWidth)
// 左上角纵坐标
rect.attr('y', d => { return yScale(d) })
// rect 的高
.attr('height', d => { return height - padding.top - padding.bottom - yScale(d) })
}
... ...
.my-rect {
cursor: pointer;
}
部分同学可能没有安装sass-loader依赖,会导致webpack无法打包scss类型样式
解决方案是: npm i sass-loader node-sass -S