使用d3.js,图形的x坐标显示在x = 0或y轴上。 x轴表示日期和时间,y轴表示温度。但这只是在ipad或iphone上。在我自己的机器Linux上,它显示正确。
图表和所有文件都可以在, http://shanespi.no-ip.biz
ipad / iphone显示屏
正确的图表是,
这是javascript,
var xScale = d3.scaleTime()
.domain([new Date(datahourly[0].date), d3.max(datahourly, function(d) {return new Date(d.date)})])
.range([0, (w-2*padding)]); // max x screen space is width - twice padding
var yScale = d3.scaleLinear()
.domain([0, d3.max(datahourly, function(d) {return d.temp})])
.range([(h-2*padding), 0]); // max y screen space is height - twice padding
var xAxis = d3.svg.axis(xScale) // d3 v.4
.ticks(9) // specify the number of ticks
/*.ticks(d3.time.days, 1) */
.tickFormat(d3.time.format('%H:00'))
.scale(xScale)
.orient("bottom");
var yAxis = d3.svg.axis(yScale)
.ticks(7)
.scale(yScale)
.orient("left");
var svg = d3.select('#hourly-readings')
.append('svg') // create an <svg> element
.attr('id', 'svgDaily')
.attr('width', w) // set its dimensions
.attr('height', h);
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(" + (2*padding - 15) + "," + (padding - 15) + ")")
.call(yAxis);
svg.append('g') // create a <g> element
.attr('class', 'axis') // specify classes
.attr("transform", "translate(" + (2*padding - 15) + "," + (h - padding - 15) + ")")
.call(xAxis); // let the axis do its thing
var lineFunctionStart = d3.svg.line()
.x(function(d) {return xScale(new Date(d.date)); })
.y(h - 2*padding - 5)
.interpolate("cardinal");
var lineFunction = d3.svg.line()
.x(function(d) {return xScale(new Date(d.date)); })
.y(function(d) {return yScale(d.temp); })
.interpolate("cardinal");
svg.append("path")
.attr('d', lineFunctionStart(datahourly))
.attr('stroke', "grey")
.attr('stroke-width', 1)
.style('fill', "white")
.attr("transform","translate(" + (2*padding - 13) + "," + (padding - 10) + ")")
.transition()
.duration(3000)
.attr('d', lineFunction(datahourly));
//var svg = d3.select('svg');
var svg = d3.select('#svgDaily');
svg.append("text") // text label for the x axis
.attr("x", 310)
.attr("y", h)
.style("font-size", "12")
.style("text-anchor", "middle")
.text("Time (1 hr. intervals)");
svg.append("text") // text label for the x axis
.attr('transform', 'rotate(-90)')
.attr("x", -85) // Because rotate is first x and y coordinates are transaposed
.attr("y", padding-17)
.style("font-size","10")
.style("text-anchor", "middle")
.text("Temp. Celcius");
var rects = svg.selectAll('circle')
.data(datahourly);
var newRects = rects.enter();
newRects.append('circle')
.attr('cx', function(d, i) { return (Math.random() * (w - 2*padding)) })
//.attr('cx', function(d, i) {
//return (5 + xScale(new Date(d.date)));
//})
.attr('cy', (h - (2*padding)))
.attr('r', 5)
.style('fill', "lightblue")
.attr("transform","translate(" + (2*padding - 18) + "," + (padding - 20) + ")")
.transition()
.duration(3000)
.delay(function(d, i) {return i * 300})
.attr('cx', function(d, i) {
return (5 + xScale(new Date(d.date)));
})
.attr('cy', function(d, i) {
return 10 + yScale(d.temp);
});
这是'datahourly'数据,
[
{
"date":"2016-12-14 22:01:01.799830",
"temp":"24.04"
},
{
"date":"2016-12-15 00:01:02.362875",
"temp":"23.03"
},
......................
{
"date":"2016-12-15 21:01:01.868593",
"temp":"21.93"
},
{
"date":"2016-12-15 22:01:02.278817",
"temp":"15.9"
},
{
"date":"2016-12-15 23:01:01.963714",
"temp":"21.63"
}
]
我在ipad和iphone上使用Linux上的Chrome和Safari。但我确实在iphone上安装了chrome,图表仍然不正确。
iOS存在svg问题吗?
编辑: 主要问题是时间数据未正确解析,
这是正确的解决方案,
var data = [];
$.getJSON("data/data.json",
function(info){
data = info[0].fiveMinReadings;
//console.log(data);
var parseTime = d3.timeParse("%Y-%m-%d %H:%M:%S.%L");
data.forEach(function(d) {
d.date = d.date.slice(0,-3);// remove microseconds
d.date = parseTime(d.date);
d.temp = +d.temp;
});
// Beginning of graph for 5 minute readings
var padding = 25;
var w = 600;
var h = 300;
var xScale = d3.scaleTime()
.domain(d3.extent(data, function(d) { return d.date; }))
.range([0, (w-2*padding)]); // max x screen space is width - twice padding
var yScale = d3.scaleLinear()
.domain([0,d3.max(data, function(d) {return d.temp})])
.range([(h-2*padding), 0]); // max y screen space is height - twice padding
var xAxis = d3.axisBottom(xScale) // d3 v.4
.tickFormat(d3.timeFormat('%H:%M '))
.scale(xScale);
var yAxis = d3.axisLeft(yScale)
.scale(yScale);
var svg = d3.select('#five-min-readings')
.append('svg') // create an <svg> element
.attr('id','svgHourly')
.attr("align","center")
.attr('width', w) // set its dimensions
.attr('height', h);
var valueline = d3.line()
.curve(d3.curveCardinal)
.x(function(d) { return xScale(d.date); })
.y(h - 2*padding - 4);
var valueline2 = d3.line()
.curve(d3.curveCardinal)
.x(function(d) { return xScale(d.date); })
.y(function(d) {return yScale(d.temp); });
svg.append("text") // text label for the x axis
.attr("x", 310)
.attr("y", h)
.style("font-size", "12")
.style("text-anchor", "middle")
.text("Time (5 min. intervals)");
svg.append("text") // text label for the x axis
.attr('transform', 'rotate(-90)')
.attr("x", -85) // Because rotate is first, x and y coordinates are transaposed
.attr("y", padding-17)
.style("font-size","10")
.style("text-anchor", "middle")
.text("Temp. Celcius");
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(" + (2*padding-15) + "," + (padding-15) + ")")
.call(yAxis);
svg.append('g') // create a <g> element
.attr('class', 'axis') // specify class
.attr("transform", "translate(" + (2*padding-15) + "," + (h - padding - 15) + ")")
.call(xAxis); // let the axis do its thing
svg.append('path')
.data([data])
.attr("class","line")
.attr('d', valueline)
.attr('stroke', "grey")
.attr('stroke-width', 1)
.style('fill', "white")
.attr("transform","translate(" + (2*padding - 13) + "," + (padding -10) + ")")
.transition()
.duration(3000)
.attr('d', valueline2 );
var svg = d3.select('#svgHourly');
var rects = svg.selectAll('circle')
.data(data);
var newRects = rects.enter();
newRects.append('circle')
.attr('cx', function(d, i) { return (Math.random() * (w - 2*padding)) })
.attr('cy', h - 2*padding)
.attr('r', 5)
.attr("id", function(d,i){return "circle" + i})
.style('fill', "lightblue")
.attr("transform","translate(" + (2*padding - 18) + "," + (padding - 20) + ")")
.transition()
.duration(3000)
.delay(function(d, i) {return i * 300})
.attr('cx', function(d, i) { return (5 + xScale(d.date)); })
.attr('cy', function(d, i) { return 10 + yScale(d.temp); });
}); // closes getJSON()
答案 0 :(得分:3)
您可以清楚地看到您的圈子正在获得正确的y(&#34; cy&#34;)值,错误在于x(&#34; cx&#34;)值。
问题似乎是使用这种模式在Safari中使用new Date()
:yyyy-MM-dd
。
在您的代码中,根据您的数据结构,您最终会在行生成器中出现类似内容:
.x(function(d) {
return xScale(new Date("2016-12-15 23:01:01.963714"));
})//the first date in your data ---^
您的圈子也一样:
.attr('cx', function(d, i) {
return (5 + xScale(new Date("2016-12-15 23:01:01.963714")));
})
显然,Chrome和Firefox支持此功能,但Safari不支持。奇怪的是,模式(yyyy-MM-dd
)包含在ECMA standard中,因此这可能是Safari特有的问题。
根据this answer,如果您添加T
(我没有对其进行测试),它会有效:
.x(function(d) {
return xScale(new Date("2016-12-15T23:01:01.963714"));
})
或者,删除new Date()
并使用D3(d3 v4.x中的d3.timeParse()
和d3 v3.x中的format.parse()
)解析日期。
编辑:总结一下,您有两种可能的解决方案:
解决方案1 :删除所有new Date
函数(在行生成器和使用它的所有比例中)并使用d3解析日期。 You said您使用的是d3 v3.x,但您的代码使用的是 d3 v4.x 。不过,以下是使用 d3 v3.x :
var date = "2016-12-14 22:01:01.799830".slice(0,-3);
var format = d3.time.format("%Y-%m-%d %H:%M:%S.%L");
var myDate = format.parse(date);
console.log(myDate);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
&#13;
注意:我删除了最后3位数,因为d3可以解析onli miliseconds,而不是微秒。
解决方案2 :保留new Date
个功能,但如上所述添加T
:
var date = "2016-12-14 22:01:01.799830".replace(/\s/, 'T');
console.log(date);
console.log(new Date(date));
&#13;
答案 1 :(得分:0)
似乎dc.js 1.7.5稳定版和d3.js v4之间存在兼容性问题。 dc.js compatibility with v4 of d3.js以及我在此https://stackoverflow.com/questions/41389307/dc-js-1-7-5-not-compatible-with-d3-js-v4
上的新帖子答案 2 :(得分:0)
哇,这个方法在 android 和 iOS 上都有效,节省了我浏览这个问题的时间
var commonDate = item.created_at.replace(/\s/, "T");
var date = new Date(commonDate);
长话短说:我在 ionic angular 版本中使用了 d3,仅在 iOS 中也遇到了同样的问题