D3线图显示正数和负数
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了D3线图显示正数和负数相关的知识,希望对你有一定的参考价值。
所以我正在使用D3创建一个线图。这张图可以在这里找到jsfiddle。我正在尝试手动绘制线条来表示某些数据点值。我试图在代码中的大多数行添加注释,所以希望你可以继续。
我的问题是我似乎无法以一种好的方式绘制负数,如果我这样做,那么图形数据线就会错位。所以我的问题是:我如何扩展我的图表,以便我可以显示负数和正数?在这种情况下,图表应该基于我设置的最大/最小值来自2 to -2
。
目前。我正在像这样缩放我的图表
//
// Setup y scale
//
var y = d3.scale.linear()
.domain([0, max])
.range([height, 0]);
//
// Setup x scale
//
var x = d3.time.scale()
.domain(d3.extent(data, dateFn))
.range([0, width]);
在我看来,做.domain([-2,max])
就足够了,但这似乎会让事情变得更糟。
此外,我的线条似乎与数据线所说的不匹配。在jsfiddle中,绿线设置在1
。但是价值为1
的数据线不在绿线上。
所以,这是我猜的一个规模问题。
视觉(picasso-esc)表示图形应该如何工作。
正如您希望您的y域为[-2,2]而不是由数据驱动,您可以从drawGraph
函数中删除许多设置和辅助函数。
在绘制图形之后,您可以简单地遍历yLines
数组,并根据您的yScale在指定的color
处为每个指定的val
绘制一条线。
更新:编辑:因为您将从端点提供nominal, upperTolerance, lowerTolerance, innerUpperTolerance, innerLowerTolerance
的值(并且不需要从客户端的数据计算),只需将这些值提供给数据驱动的yScale以绘制彩色线条。
下面我刚刚使用了值1, 1.8, -1.8
,但您将收到与您的数据更有意义的值。
// Setup
const yLines = [{
val: 1,
color: 'green'
},
{
val: 1.8,
color: 'yellow'
},
{
val: -1.8,
color: 'red'
}
]
const margin = {
top: 10,
right: 80,
bottom: 60,
left: 20
};
const strokeWidth = 3;
const pointRadius = 4;
const svgWidth = 600;
const svgHeight = 600;
const width = svgWidth - margin.left - margin.right;
const height = svgHeight - margin.top - margin.bottom;
const stroke = '#2990ea'; // blue
const areaFill = 'rgba(41,144,234,0.1)'; // lighter blue
const format = d3.time.format("%b %e %Y");
const valueFn = function(d) {
return d.value
};
const dateFn = function(d) {
return format.parse(d.name)
};
// select the div and append svg to it
const graph = d3.select('#chart').append('svg')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.style('overflow', 'visible');
const transformGroup = graph.append('g')
.attr('tranform', `translate(${margin.left}, ${margin.right})`)
// Make a group for yLines
const extraLines = transformGroup.append('g')
.attr('class', 'extra-lines')
// Generate some dummy data
const getData = function() {
let JSONData = [];
for (var i = 0; i < 30; i++) {
JSONData.push({
"name": moment().add(i, 'days').format('MMM D YYYY'),
"value": Math.floor(Math.random() * (Math.floor(Math.random() * 20))) - 10
})
}
return JSONData.slice()
}
const drawGraph = function(data) {
console.log(data)
// Setup y scale
const y = d3.scale.linear()
.domain(d3.extent(data.map((d) => d.value)))
.range([height, 0]);
// Setup y axis
const yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(10)
.tickSize(0, 0, 0)
// append group & call yAxis
transformGroup.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + margin.left + ",0)")
.call(yAxis);
// Draw extra coloured lines from yLines array
extraLines.selectAll('.extra-line')
.data(yLines)
.enter()
.append('line')
.attr('class', 'extra-line')
.attr('x1', margin.left)
.attr('x2', svgWidth - margin.right)
.attr('stroke', d => d.color)
.attr('y1', d => y(+d.val))
.attr('y2', d => y(+d.val))
.attr('stroke-width', strokeWidth)
.attr('opacity', 0.5)
// Setup x scale
const x = d3.time.scale()
.domain(d3.extent(data, dateFn))
.range([0, width])
// function for filling area under chart
const area = d3.svg.area()
.x(d => x(format.parse(d.name)))
.y0(height)
.y1(d => y(d.value))
// function for drawing line
const line = d3.svg.line()
.x(d => x(format.parse(d.name)))
.y(d => y(d.value))
const lineStart = d3.svg.line()
.x(d => x(format.parse(d.name)))
.y(d => y(0))
// make the line
transformGroup.append('path')
.attr('stroke', stroke)
.attr('stroke-width', strokeWidth)
.attr('fill', 'none')
.attr('transform', `translate(${margin.left}, ${margin.top})`)
.attr('d', lineStart(data))
.attr('d', line(data))
// fill area under the graph
transformGroup.append("path")
.datum(data)
.attr("class", "area")
.attr('fill', areaFill)
.attr('transform', `translate(${margin.left}, ${margin.top})`)
.attr('d', lineStart(data))
.attr("d", area)
}
drawGraph(getData())
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.min.js"></script>
<div id="chart" style="margin: 0 auto;"></div>
以上是关于D3线图显示正数和负数的主要内容,如果未能解决你的问题,请参考以下文章