- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个 d3 时间刻度图表。目前,轴刻度为每个数据对象呈现一个日期。例如,数据的范围可以是 1 天的数据、1 个月内 2 周的数据、5 个月的数据甚至更多。
理想情况下,我们希望显示带有周数的刻度,基于数据 - 不是年或月的周数,如下所示:xAxis .tickFormat(d3.time.format('%W'))
例如,如果数据从 7 月 15 日开始,第一个刻度将表示“第 1 周”,然后是“第 2 周”,等等。
如何使用基于时间的 d3 折线图实现这样的轴刻度?我是 d3 的新手,几乎不知道如何实现这一目标。
我也在使用 moment.js,所以在 xAxis.tickFormat
中,我尝试使用一个带有一些逻辑的函数,该函数根据日期返回不同的值,但这看起来很脆弱并且不是“d3 方式”。还尝试使用自定义时间格式化程序 as seen here .
或者,我们可以使用更简单的刻度 - 仅使用 d3.time.format(%d-%b)
显示月份和/或日期,但是会有重复的刻度值,例如 'Feb ...Feb..Feb..Feb...Feb..Mar..Mar..Mar..`。有没有办法避免出现重复值?
我已经尝试限制滴答声的数量,但这并没有像预期的那样起作用。例如,如果我有 xAxis.ticks(5)
,则出现 3 个刻度;如果我有 xAxis.ticks(2)
,情况也一样。如果 ticks 定义为 1,则只显示 1 个 ticks。这是怎么回事?
任何帮助将不胜感激!下面的代码包含 2 个数据集示例
<!DOCTYPE html>
<body>
<style>
path { fill: #CCC; }
.line { fill: none; stroke: #000; stroke-width: 5px;}
</style>
<div id="chart-container">
<svg id="chart"></svg>
</div>
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.12.0/moment.min.js"></script>
<script src="//d3js.org/d3.v3.min.js"></script>
<script>
var now = moment();
var chartData = [
{ timestamp: moment(now).subtract(27, 'days').format('DD-MMM-YY'), value: 40 },
{ timestamp: moment(now).subtract(25, 'days').format('DD-MMM-YY'), value: 36 },
{ timestamp: moment(now).subtract(24, 'days').format('DD-MMM-YY'), value: 33 },
{ timestamp: moment(now).subtract(21, 'days').format('DD-MMM-YY'), value: 35 },
{ timestamp: moment(now).subtract(20, 'days').format('DD-MMM-YY'), value: 35 },
{ timestamp: moment(now).subtract(18, 'days').format('DD-MMM-YY'), value: 33 },
{ timestamp: moment(now).subtract(17, 'days').format('DD-MMM-YY'), value: 33 },
{ timestamp: moment(now).subtract(16, 'days').format('DD-MMM-YY'), value: 33 },
{ timestamp: moment(now).subtract(15, 'days').format('DD-MMM-YY'), value: 32 },
{ timestamp: moment(now).subtract(13, 'days').format('DD-MMM-YY'), value: 35 },
{ timestamp: moment(now).subtract(11, 'days').format('DD-MMM-YY'), value: 31 },
{ timestamp: moment(now).subtract(10, 'days').format('DD-MMM-YY'), value: 28 },
{ timestamp: moment(now).subtract(9, 'days').format('DD-MMM-YY'), value: 32 },
{ timestamp: moment(now).subtract(8, 'days').format('DD-MMM-YY'), value: 30 },
{ timestamp: moment(now).subtract(7, 'days').format('DD-MMM-YY'), value: 33 },
{ timestamp: moment(now).subtract(6, 'days').format('DD-MMM-YY'), value: 36 }
];
//data could have a shorter date range of eg, 1 or 2 weeks
//ideally we want to still display 'week 1, 2, 3, 4' etc in the axis.
//alternatively display dates instead
// var chartData = [
// { timestamp: moment(now).subtract(27, 'days').format('DD-MMM-YY'), value: 40 },
// { timestamp: moment(now).subtract(25, 'days').format('DD-MMM-YY'), value: 36 },
// { timestamp: moment(now).subtract(24, 'days').format('DD-MMM-YY'), value: 33 },
// { timestamp: moment(now).subtract(21, 'days').format('DD-MMM-YY'), value: 35 },
// { timestamp: moment(now).subtract(20, 'days').format('DD-MMM-YY'), value: 35 }
// ];
let lastObj = chartData[chartData.length - 1];
let lastObjTimestamp = lastObj.timestamp;
let lastAndNow = moment(lastObjTimestamp).diff(now, 'days');
console.log('difference between last entry ' + lastObjTimestamp + ' and today: ' + lastAndNow);
var chartWrapperDomId = 'chart-container';
var chartDomId = 'chart';
var chartWrapperWidth = document.getElementById(chartWrapperDomId).clientWidth;
var margin = 40;
var width = chartWrapperWidth - margin;
var height = 500 - margin * 2;
var xMin = d3.time.format('%d-%b-%y').parse(chartData[0].timestamp);
var xMax = d3.time.format('%d-%b-%y').parse(chartData[chartData.length-1].timestamp);
//set the scale for the x axis
var xScale = d3.time.scale();
xScale.domain([xMin, xMax]);
xScale.range([0, width]);
var yScale = d3.scale.linear()
.range([height, 0])
.nice();
console.log('no5 ', chartData[5].timestamp)
var xAxis = d3.svg.axis()
.scale(xScale)
.orient('bottom')
.tickFormat(d3.time.format('%d-%b'));
//.tickFormat(d3.time.format('%b'))
//tickFormat(d3.time.format('%W'));
//.ticks(5);
var yAxis = d3.svg.axis()
.scale(yScale)
.orient('left');
var line = d3.svg.line()
.x(function(d) {
return xScale(d.timestamp);
})
.y(function(d) {
return yScale(d.value);
});
var svg = d3.select('#' + chartDomId)
.attr('width', width + margin * 2)
.attr('height', height + margin * 2)
.append('g')
.attr('transform', 'translate(' + margin + ',' + margin + ')');
chartData.forEach(function(d) {
d.timestamp = d3.time.format('%d-%b-%y').parse(d.timestamp);
d.value = +d.value;
});
yScale.domain(d3.extent(chartData, function(d) {
return d.value;
}));
svg.append('g')
.attr('class', 'axis x-axis')
.attr('transform', 'translate(0,' + height + ')')
.call(xAxis);
svg.append('g')
.attr('class', 'axis y-axis')
.call(yAxis)
.append('text')
.attr('transform', 'rotate(-90)')
.attr('y', 6)
.attr('dy', '.71em')
.style('text-anchor', 'end');
svg.append('path')
.datum(chartData)
.attr('class', 'line')
.attr('d', line);
</script>
</body>
最佳答案
您需要从数据中找到第一个工作日(例如星期三)并根据它设置刻度。
可以使用以下代码实现:
var weekday = new Array(7);
weekday[0]= 'sunday';
weekday[1] = 'monday';
weekday[2] = 'tuesday';
weekday[3] = 'wednesday';
weekday[4] = 'thursday';
weekday[5] = 'friday';
weekday[6] = 'saturday';
var startDay = weekday[new Date(chartData[0].timestamp).getDay()];
var week = 1;
var xAxis = d3.svg.axis()
.scale(xScale)
.orient('bottom')
.tickFormat(function() { return 'week ' + week++ })
.ticks(d3.time[startDay]);
<!DOCTYPE html>
<body>
<style>
path { fill: #CCC; }
.line { fill: none; stroke: #000; stroke-width: 5px;}
</style>
<div id="chart-container">
<svg id="chart"></svg>
</div>
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.12.0/moment.min.js"></script>
<script src="//d3js.org/d3.v3.min.js"></script>
<script>
var now = moment();
var chartData = [
{ timestamp: moment(now).subtract(27, 'days').format('DD-MMM-YY'), value: 40 },
{ timestamp: moment(now).subtract(25, 'days').format('DD-MMM-YY'), value: 36 },
{ timestamp: moment(now).subtract(24, 'days').format('DD-MMM-YY'), value: 33 },
{ timestamp: moment(now).subtract(21, 'days').format('DD-MMM-YY'), value: 35 },
{ timestamp: moment(now).subtract(20, 'days').format('DD-MMM-YY'), value: 35 },
{ timestamp: moment(now).subtract(18, 'days').format('DD-MMM-YY'), value: 33 },
{ timestamp: moment(now).subtract(17, 'days').format('DD-MMM-YY'), value: 33 },
{ timestamp: moment(now).subtract(16, 'days').format('DD-MMM-YY'), value: 33 },
{ timestamp: moment(now).subtract(15, 'days').format('DD-MMM-YY'), value: 32 },
{ timestamp: moment(now).subtract(13, 'days').format('DD-MMM-YY'), value: 35 },
{ timestamp: moment(now).subtract(11, 'days').format('DD-MMM-YY'), value: 31 },
{ timestamp: moment(now).subtract(10, 'days').format('DD-MMM-YY'), value: 28 },
{ timestamp: moment(now).subtract(9, 'days').format('DD-MMM-YY'), value: 32 },
{ timestamp: moment(now).subtract(8, 'days').format('DD-MMM-YY'), value: 30 },
{ timestamp: moment(now).subtract(7, 'days').format('DD-MMM-YY'), value: 33 },
{ timestamp: moment(now).subtract(6, 'days').format('DD-MMM-YY'), value: 36 }
];
//data could have a shorter date range of eg, 1 or 2 weeks
//ideally we want to still display 'week 1, 2, 3, 4' etc in the axis.
//alternatively display dates instead
// var chartData = [
// { timestamp: moment(now).subtract(27, 'days').format('DD-MMM-YY'), value: 40 },
// { timestamp: moment(now).subtract(25, 'days').format('DD-MMM-YY'), value: 36 },
// { timestamp: moment(now).subtract(24, 'days').format('DD-MMM-YY'), value: 33 },
// { timestamp: moment(now).subtract(21, 'days').format('DD-MMM-YY'), value: 35 },
// { timestamp: moment(now).subtract(20, 'days').format('DD-MMM-YY'), value: 35 }
// ];
let lastObj = chartData[chartData.length - 1];
let lastObjTimestamp = lastObj.timestamp;
let lastAndNow = moment(lastObjTimestamp).diff(now, 'days');
console.log('difference between last entry ' + lastObjTimestamp + ' and today: ' + lastAndNow);
var chartWrapperDomId = 'chart-container';
var chartDomId = 'chart';
var chartWrapperWidth = document.getElementById(chartWrapperDomId).clientWidth;
var margin = 40;
var width = chartWrapperWidth - margin;
var height = 500 - margin * 2;
var xMin = d3.time.format('%d-%b-%y').parse(chartData[0].timestamp);
var xMax = d3.time.format('%d-%b-%y').parse(chartData[chartData.length-1].timestamp);
//set the scale for the x axis
var xScale = d3.time.scale();
xScale.domain([xMin, xMax]);
xScale.range([0, width]);
var yScale = d3.scale.linear()
.range([height, 0])
.nice();
console.log('no5 ', chartData[5].timestamp)
var weekday = new Array(7);
weekday[0]= 'sunday';
weekday[1] = 'monday';
weekday[2] = 'tuesday';
weekday[3] = 'wednesday';
weekday[4] = 'thursday';
weekday[5] = 'friday';
weekday[6] = 'saturday';
var startDay = weekday[new Date(chartData[0].timestamp).getDay()];
var week = 1;
var xAxis = d3.svg.axis()
.scale(xScale)
.orient('bottom')
//.tickFormat(d3.time.format('%d-%b'));
//.tickFormat(d3.time.format('%b'))
//tickFormat(d3.time.format('%W'));
.tickFormat(function() { return 'week ' + week++ })
.ticks(d3.time[startDay]);
var yAxis = d3.svg.axis()
.scale(yScale)
.orient('left');
var line = d3.svg.line()
.x(function(d) {
return xScale(d.timestamp);
})
.y(function(d) {
return yScale(d.value);
});
var svg = d3.select('#' + chartDomId)
.attr('width', width + margin * 2)
.attr('height', height + margin * 2)
.append('g')
.attr('transform', 'translate(' + margin + ',' + margin + ')');
chartData.forEach(function(d) {
d.timestamp = d3.time.format('%d-%b-%y').parse(d.timestamp);
d.value = +d.value;
});
yScale.domain(d3.extent(chartData, function(d) {
return d.value;
}));
svg.append('g')
.attr('class', 'axis x-axis')
.attr('transform', 'translate(0,' + height + ')')
.call(xAxis);
svg.append('g')
.attr('class', 'axis y-axis')
.call(yAxis)
.append('text')
.attr('transform', 'rotate(-90)')
.attr('y', 6)
.attr('dy', '.71em')
.style('text-anchor', 'end');
svg.append('path')
.datum(chartData)
.attr('class', 'line')
.attr('d', line);
</script>
</body>
关于javascript - d3 - 如何根据周格式化 xAxis 刻度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36128327/
如何使用 plot() 在 XY 图中绘制第二条线,以不同的比例(如本例(紫色线))? 第一行(红色)我的 R 代码是这样的: p <- sqlQuery(ch,"SELECT wl,param1 F
我正在寻找一种将折线图步骤设置为仅完整数字步骤的方法,例如 1,2,3,4,5..... 目前它看起来像这样: 这些是我的选择。我搜索了很多但找不到解决方案。 let options = {
我的问题是如何将 Y 轴刻度的间隔从 0.2 更改为 0.1?我已经尝试了一切,但我很困!帖子底部堆叠条形图的图片 dpi=600 #pixels per square inch A <- c(
有没有办法根据当前数据集在 D3 轴上动态设置 ticks。我遇到的问题是我的时间范围(x 轴)可能变化很大。对于一些数据集来说,它是几年的值(value),对于其他数据集来说是几个月,在某些情况下只
我已经使用默认参数创建了一个 dojo 蜘蛛图。我需要隐藏轴标签(刻度上的数据值,而不是轴标题)。 我已经尝试过'ticks: false',但是它不适用于蜘蛛图。 require(["dojo/_b
有没有一种简单的方法可以在绘图 Axis 上获得自定义缩放比例? 例如,semilogy 函数提供 {x, log10(y)} 缩放比例,这样就可以自动放大/缩小并自动调整刻度和标签。我想对 {x,
如何修改图形和图表的 y Axis 刻度?我想要这样的东西:my_figure.y_range.end = my_figure.y_range.end * 1.3 所以我想要更高一点的y轴。谢谢! 最
我正在尝试使用 recharts 添加图表一些货币的最新汇率。数据显示正确,但图表始终从 0 开始并略高于最大值。 图表是正确的,但它不需要从 0 开始,因为这样做,它几乎是一条线。 这是图表的图片:
我有一个 SWT Scale 小部件,我需要在刻度上的刻度上添加标签。 有没有办法做到这一点?也许在 slider 小部件上? 谢谢 最佳答案 这可能不是您所要求的,但您可以在 Scale 小部件旁边
这是一个从 .xlsx 文件中读取数据并利用 Plotly 库绘制气泡图的程序。这是 .xlsx 文件的原始数据: 1991 1992 1993 1994 1995
我这里有一个代码笔 - https://codepen.io/anon/pen/yvgJKB 我有一个简单的堆积条形图。 我想将其制作成一个组件,因此我需要传入值以使其可重用 x 缩放函数返回d.da
让我们看一个基本的演示折线图: jsfiddle $(function () { $('#container').highcharts({ //all the code there 我想强制
是否可以在 t-sql 中获得像 DateTime.Ticks 这样的 C# 内容? 感谢帮助 最佳答案 您不太可能从 SQL 中获得与 DateTime.Ticks 相同的精度,因为 SQL 不能以
我正在使用 Bokeh 生成散点图,每个 X 值具有不同的 Y 值。当 Bokeh 生成绘图时,它会根据绘制的值的数量自动填充 x 轴间距。我希望 x 轴上的所有值均匀分布,无论单个数据点的数量如何。
我使用下面的代码使用谷歌图表生成折线图 google.charts.load('current', {packages: ['corechart', 'line']});
我正在尝试在 d3 中构建堆积条形图。 这是我的 jsfiddle: http://jsfiddle.net/maneesha/gwjkgruk/4/ 我正在尝试修复它,使 y 轴从零开始。 我认为这
我有一个 d3 时间刻度图表。目前,轴刻度为每个数据对象呈现一个日期。例如,数据的范围可以是 1 天的数据、1 个月内 2 周的数据、5 个月的数据甚至更多。 理想情况下,我们希望显示带有周数的刻度,
当使用“Cassic”折线图时,我可以为 hAxis 分配刻度,还有这样的格式和标题: var options = { hAxis: { format:'h a', title
我的累积折线图没有正确构建 yScale。 给定要构建图表的数据: var data = [{ key: "Page view", values: [ ["2013-07-01 00:
在 y 轴上使用两个具有正常整数值的 DateAxisSeries(x 轴)我的 jqPlot 将 y 刻度呈现两次。 像这样: 2| 2| 1| 1| 0|_____________________
我是一名优秀的程序员,十分优秀!