D3.js 单个值时的d3中心记号和x轴标签

D3.js 单个值时的d3中心记号和x轴标签,d3.js,D3.js,我有以下d3代码: var json = [ { date: "05/17", numTags: 23 } ]; d3.select('summary-graph').selectAll('*').remove(); var svg = d3.se

我有以下d3代码:

                var json = [
                {
                    date: "05/17",
                    numTags: 23
                }
            ];

            d3.select('summary-graph').selectAll('*').remove();

            var svg = d3.select("summary-graph"),
                margin = {
                    top: 20,
                    right: 30,
                    bottom: 30,
                    left: 40
                },
                width = svg.attr("width") - margin.left - margin.right,
                height = svg.attr("height") - margin.top - margin.bottom;

            var parseTime = d3.timeParse("%m/%y");

            var svg = d3.select("summary-graph").append("svg")
                .attr("width", width + margin.left + margin.right)
                .attr("height", height + margin.top + margin.bottom)
                .append("g")
                .attr("transform",
                    "translate(" + margin.left + "," + margin.top + ")");

            // Get the data
            var data = json;

            // format the data
            data.forEach(function (d) {
                console.log(d);
                d.date = parseTime(d.date);
                d.numTags = +d.numTags;
            });

            // set the ranges
            var xScale = d3.scaleTime()
                            .range([0, width])
                            .domain(d3.extent(data, function (d) {
                                return d.date;
                            }))
                            .nice();

            var yScale = d3.scaleLinear()
                            .range([height, 0])
                            .domain([0, d3.max(data, function (d) {
                                return Math.max(d.numTags);
                            })])
                            .nice();

            // define the 1st line
            var tagLine = d3.line()
                .x(function (d) {
                    return xScale(d.date);
                })
                .y(function (d) {
                    return yScale(d.numTags);
                });


            // Axes
            var xAxis = d3.axisBottom()
                          .scale(xScale)
                          .ticks(json.length)
                          .tickSizeOuter(0)
                          .tickFormat(d3.timeFormat('%B %Y'));

            var yAxis = d3.axisLeft().scale(yScale);

            svg.append("path")
                .data([data])
                .attr("class", "line")
                .style("stroke", "blue")
                .attr("d", tagLine);

            var points = svg.selectAll(".point")
                    .data(data)
                    .enter().append("svg:circle")
                     .attr("stroke", "green")
                     .attr("fill", function(d, i) { return "blue" })
                     .attr("cx", function(d, i) { return xScale(d.date) })
                     .attr("cy", function(d, i) { return yScale(d.numTags) })
                     .attr("r", function(d, i) { return 10 });

            // Add the X Axis
            svg.append("g")
                .attr("transform", "translate(0," + height + ")")
                .call(xAxis)
                .style("font-size","14px");;

            // Add the Y Axis
            svg.append("g")
                .call(yAxis);
这将产生以下可视化效果:

我想知道当只有一个这样的数据点时,如何将记号标记居中并显示x轴标签。在2个数据点上,我不喜欢它仍然在x轴的最末端设置刻度线的方式。对于3个数据点及以上的数据点,它看起来很不错(感谢.nice())

有什么帮助吗


根据Gerado的反应,我能够接近。最后一个关键点是,尽管没有当天的数据,X轴左侧现在有月份(3月)

固定的:
将.ticks(json.length)更改为.ticks(d3.timeMonth.every(1))

因为您只使用一个数据点,所以日期刻度有一个域,其中上下限值相同:

[
    Mon May 01 2017 00: 00: 00 GMT + 1000,
    Mon May 01 2017 00: 00: 00 GMT + 1000
]

把这个圆放在X轴的中间,你必须为刻度的域设置不同的值。< /P> 有几种方法可以做到这一点。我在这里提出的解决方案涉及验证域的值是否相同

if (xScale.domain()[0].getTime() == xScale.domain()[1].getTime()) {
。。。如果是,就改变它们。在这种情况下,我从下限减去一天,在上限上加一天:

if (xScale.domain()[0].getTime() == xScale.domain()[1].getTime()) {
    var dateLess = d3.timeDay.offset(xScale.domain()[0], -1);
    var dateMore = d3.timeDay.offset(xScale.domain()[0], 1);
    xScale.domain([dateLess, dateMore])
}
检查结果:

var json=[{
日期:“2017年5月5日”,
numTags:23
}];
var保证金={
前20名,
右:30,,
底数:30,
左:40
},
宽度=400,
高度=200;
var parseTime=d3.timeParse(“%m/%y”);
var svg=d3.选择(“正文”).追加(“svg”)
.attr(“宽度”,宽度+边距。左侧+边距。右侧)
.attr(“高度”,高度+边距。顶部+边距。底部)
.附加(“g”)
.attr(“转换”,
“翻译(“+margin.left+”,“+margin.top+”);
//获取数据
var-data=json;
//格式化数据
data.forEach(函数(d){
d、 日期=解析时间(d.日期);
d、 numTags=+d.numTags;
});
//设定范围
var xScale=d3.scaleTime()
.范围([0,宽度])
.域(d3.范围(数据、函数(d)){
返回日期;
}))
.nice();
如果(xScale.domain()[0].getTime()==xScale.domain()[1].getTime()){
var dateLess=d3.timeDay.offset(xScale.domain()[0],-1);
var dateMore=d3.timeDay.offset(xScale.domain()[0],1);
域([dateLess,dateMore])
}
var yScale=d3.scaleLinear()
.范围([高度,0])
.domain([0,d3.max(数据,函数(d)){
返回Math.max(d.numTags);
})])
.nice();
//定义第一行
var tagLine=d3.line()
.x(功能(d){
返回xScale(d.日期);
})
.y(功能(d){
返回yScale(d.numTags);
});
//斧头
var xAxis=d3.axisBottom()
.scale(xScale)
.ticks(json.length)
.滴答器(0)
.tickFormat(d3.timeFormat(“%B%Y”);
var yAxis=d3.axisLeft().scale(yScale);
追加(“路径”)
.数据([数据])
.attr(“类”、“行”)
.style(“笔划”、“蓝色”)
.attr(“d”,标语);
var points=svg.selectAll(“.point”)
.数据(数据)
.enter().append(“svg:circle”)
.attr(“笔划”、“绿色”)
.attr(“填充”,函数(d,i){
返回“蓝色”
})
.attr(“cx”,函数(d,i){
返回xScale(d.date)
})
.attr(“cy”,函数(d,i){
返回yScale(d.numTags)
})
.attr(“r”,函数(d,i){
返回10
});
//添加X轴
svg.append(“g”)
.attr(“变换”、“平移(0)”、“高度+”)
.呼叫(xAxis)
.style(“字体大小”、“14px”);;
//添加Y轴
svg.append(“g”)
.呼叫(yAxis)

你是说
xScale.domain()[0]。getTime()==xScale.domain()[1]。getTime()
(检查第一个值和最后一个值?)(我无法编辑,因为它只有两个字符的编辑)谢谢你的发现。看起来很棒。虽然现在我还有上个月的记号。将发布到问题。@Marc不要编辑您的问题来询问其他问题。如果您还有其他问题,请发布其他问题。这里的问题是,在单个数据点的情况下,使圆居中,这一问题已得到解决。关于这个新问题,只要搜索“如何删除第一个勾号”,就会有很多答案。我通常会同意你的看法。不过,我相信这与您发布的解决方案有关。因此,任何使用您的解决方案的人都会遇到同样的问题。如果您在上面看到,我已经包含了d3.axisBottom().tickSizeOuter(0),这是关于删除外部记号(v4)的所有内容。它仍然保持着外部的滴答声。