仅在d3.js中显示某些时间 [英] only display certain hours with d3.js

查看:101
本文介绍了仅在d3.js中显示某些时间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我以10分钟的间隔和10天的时间来绘制股价图.当然,股市仅在9:30到4之间开放.我如何仅显示图表中上午9:30到4之间的部分?例如,谷歌财务图表 https://www.google.com/finance?q=AAPL

var margin = {top: 10, right: 10, bottom: 10, left: 10};
var width = $('#'+stock.symbol+'_graph').width() - margin.left - margin.right;
var height = 100 - margin.top - margin.bottom;

var x = d3.time.scale().range([0, width]);
var y = d3.scale.linear().range([height, 0]);

var xAxis = d3.svg.axis().scale(x).orient("bottom");
var yAxis = d3.svg.axis().scale(y).orient("left");

var line = d3.svg.area()
    .x(function(d) { return x(d.date); })
    .y1(function(d) { return y(d.price); })
    .y0(height);

var svg = d3.select('#'+stock.symbol+'_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 + ")");

x.domain(d3.extent(stockHistory, function(d) { return d.date; }));
y.domain(d3.extent(stockHistory, function(d) { return d.price; }));

svg.append("path")
    .datum(stockHistory)
    .attr("class", "line")
    .attr("d", line);

解决方案

我想您不仅要显示9:30到4:00之间图表的一部分,还希望显示每天的范围./p>

您可以通过将其余时间压缩到该范围的同一部分中来完成此操作,这可以通过利用d3刻度可以取一个范围内的值这一事实来实现.例如,假设我有以下数据:

var data = [
    {x:0, y:2},{x:0.5, y:2.2},{x:1.3,y:5},{x:2.0,y:3},
    {x:10,y:2},{x:10.7,y:4.6},{x:11.3,y:0},{x:12,y:2}
    ];

我的数据仅具有[0,2]和[10,12]范围内的值,所以我只想显示这些值.

我首先为x值设置比例,如下所示:

var xscale = d3.scale.linear()

现在我需要设置域.

    .domain([0,2,10,12])

这有效地将我的领域分为三个部分:[0,2],[2,10]和[10,12].如果我类似地给出一个包含四个值的数组的范围,则可以创建分段线性刻度.假设我要绘制一个500x500的SVG.我想将域中每个有趣的部分映射到svg的一半,并在边缘上进行一些填充,然后将整个无聊的中间部分映射到单个值.为此,我提供以下范围:

    .range([10,250,250,490])

现在,我在分段线性刻度上具有以下三个映射:[0,2]-> [10,250],[2,10]-> [250,250]和[10,12]-> [250,490].我已经有效地将网域切成薄片.

我还需要修复刻度值,因为如果我用x轴绘制刻度值,则d3不会足够聪明,以至于不会尝试为我已经折叠成一个区域的部分绘制任何值单个像素.我可以通过明确声明我的刻度值来做到这一点:

var xAxis = d3.svg.axis()
    .scale(xscale)
    .orient('bottom')
    .tickValues([0,1,2,11,12])

我在此处中创建了一个简单示例的小提琴.相同的方法也可以应用于路径以获得您的示例中显示的效果.

为了使它美观,易读并且可扩展到多天,您只需要编写函数来生成域,范围和报价值数组,尽管在一些不同的时间段添加一些线性除法器会使事情变得很多更容易.

I'm charting stock prices with an interval of ten minutes and length of 10 days. Of course the stock market is only open between 9:30 and 4. How do I only display the portion of the chart that is between 9:30am and 4? For example google finance charts https://www.google.com/finance?q=AAPL

var margin = {top: 10, right: 10, bottom: 10, left: 10};
var width = $('#'+stock.symbol+'_graph').width() - margin.left - margin.right;
var height = 100 - margin.top - margin.bottom;

var x = d3.time.scale().range([0, width]);
var y = d3.scale.linear().range([height, 0]);

var xAxis = d3.svg.axis().scale(x).orient("bottom");
var yAxis = d3.svg.axis().scale(y).orient("left");

var line = d3.svg.area()
    .x(function(d) { return x(d.date); })
    .y1(function(d) { return y(d.price); })
    .y0(height);

var svg = d3.select('#'+stock.symbol+'_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 + ")");

x.domain(d3.extent(stockHistory, function(d) { return d.date; }));
y.domain(d3.extent(stockHistory, function(d) { return d.price; }));

svg.append("path")
    .datum(stockHistory)
    .attr("class", "line")
    .attr("d", line);

解决方案

I'm guessing that you want to display not just the part of the chart between 9:30 and 4:00, but that range of each day.

You can do this by compressing the rest of the hours into the same part of the range, which can be accomplished by utilizing the fact that d3 scales can take a range of values. For example, let's say I have the following data:

var data = [
    {x:0, y:2},{x:0.5, y:2.2},{x:1.3,y:5},{x:2.0,y:3},
    {x:10,y:2},{x:10.7,y:4.6},{x:11.3,y:0},{x:12,y:2}
    ];

My data only has values in the ranges [0,2] and [10,12], so I'd like to display only those values.

I start by setting up a scale for the x-values, like so:

var xscale = d3.scale.linear()

Now I need to set the domain.

    .domain([0,2,10,12])

This slices my domain, effectively, into three parts: [0,2] , [2,10] , and [10,12]. If I similarly give a range with an array of four values, I can crate a piecewise linear scale. Let's say that I have a 500x500 SVG I'm plotting in. I want to map each interesting section of my domain to half of my svg, with a bit of padding on the edges, and map the entire boring middle section to a single value. To do this, I supply the following range:

    .range([10,250,250,490])

Now I have the following three mappings on my piecewise linear scale: [0,2] -> [10,250] , [2,10] -> [250,250] , and [10,12] -> [250,490]. I've effectively sliced out the middle of my domain.

I also need to fix the tick values, since if I plot this with an x-axis, d3 won't be smart enough to not try to plot any values for the section of the domain that I've collapsed into a single pixel. I can do this by explicitly declaring my tick values:

var xAxis = d3.svg.axis()
    .scale(xscale)
    .orient('bottom')
    .tickValues([0,1,2,11,12])

I've created a fiddle of this simple example here. The same method could be applied to paths instead of circles to get the effect shown in your example.

In order to make this nice, readable, and scalable to multiple days, you would just need to write functions to generate your domain, range, and tick value arrays, though adding some linear dividers to separate time periods would make things much easier.

这篇关于仅在d3.js中显示某些时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆