How to remove weekend datetime gaps from x-axis of a financial chart? - d3.js

I have a use case where I pull and plot Forex data in the form of ask and bid on the graph and this is based on minute, hour or day candlesticks and I am only plotting the closing value for bid and ask as a spline.
Issue
The endpoints that I am using their Forex data feed is not available from Friday 8pm to Sunday 9pm. Let's say I have the following use case
Plot a 200 data points (i.e. hourly candle) on the graph at a time, on new candle phase out the oldest and plot the newest
The X-Axis is the data point's datetime in UTC ISO Format
The Y-Axis is the value of ask and bid
At a time the graph shows 4.1 days worth of hourly candle
The graph is pretty and smooth when the datetime on x-axis do not have any gaps. The candle timestamps are returned in the following form
2018-06-29T16:00:00.000000000Z
2018-06-29T17:00:00.000000000Z
2018-06-29T19:00:00.000000000Z
2018-06-29T20:00:00.000000000Z (Friday last candle 8pm)
2018-07-01T21:00:00.000000000Z (Sunday first candle 9pm)
2018-07-01T22:00:00.000000000Z
2018-07-01T23:00:00.000000000Z
2018-07-02T00:00:00.000000000Z
As soon as there is a gap (around 47-49 hours) everything gets compressed to accommodate for the stretched part of the graph as shown below (Using plotly.js)
Mostly, financial graphs do not show the gap. For example, looking at the TradingView interactive chart you will see the following for weekend
If you know how to tackle this issue with open source charting libraries (excluding TradingView) then please share your solution.

TL;DR
Based on my findings, you can exclude the gaps using HighStock of Highcharts library. Highcharts is open source and only free to use for Non-commercial use, for more details see highcharts licensing
plotly.js
I initially started off with plotly.js because it really is a very good charting library to be honest. After I came across the datetime gap issue (see screenshot in question) on x-axis I researched for solution and came across the following issues
https://community.plot.ly/t/tickformat-without-weekends/1286/5 (forum)
https://github.com/plotly/plotly.js/issues/1382 (locked github thread)
https://community.plot.ly/t/x-axis-without-weekends/1091/2
As per the Github issue link above, this is not achievable at the moment for how the datetime is handled on x-axis. There are workaround (like 3rd link above) but, I tried some and it either didn't work or I lost some piece of information.
I came to the conclusion that even though plotly is a great library, it simply cannot help me in this case. If you think it does, please share your solution :)
C3.js
After some more research of charting libraries, I give C3.js a try and after editing their live demo example with datetime for x-axis I observed the same weekend gap issue (see below)
I did not bother researching why and that's probably because of being based on D3.js just like plotly.js. If you think the datetime gap can be handled with C3.js then please feel free to share your solution.
Highcharts
I finally came across the family of Highxxxxx charting library and at first look it looked so pretty and offered all the functionalities that I wanted. I tried Highchart and I got the same weekend gap issue
Well, I started to think that the only solution is to NOT TO PLOT the datetime in x-axis at all and somehow show the datetime in tooltip and that seem to do the job as shown below
But, being too stubborn to give up I continued my research. I really wanted to get the charting done like TradingView and other stock visualization.
I decided to do some more research and little did I knew that I was so so close to a solution by the very same charting library Highcharts and it is called HighStock
Highstock of Highcharts
HighStock by default takes care of the gaps as shown below
I used the following piece of Javascript
Highcharts.setOptions({
global: {
useUTC: false
}
});
Highcharts.StockChart('chart', {
chart: {
type: 'spline',
events: {
load: function () {
console.log('Highcharts is Loaded! Creating a reference to Chart dom.')
//store a reference to the chart to update the data series
var index=$("#chart").data('highchartsChart');
highchartRef = Highcharts.charts[index]; //global var
//Initiating the data pull here
}
}
},
title: {
text: 'Chart title'
},
series: [
{
name: 'Ask',
data: [],
tooltip: {
valueDecimals: 7
},
marker: {
enabled: true
}
},
{
name: 'Bid',
data: [],
tooltip: {
valueDecimals: 7
},
marker: {
enabled: true
}
}
]
});
There you have it, a gapless (not sure if it is a real word) financial chart with datetime x-axis for financial data.
Libraries I did not try
I have researched but, did not try the following charting libraries
Google charts (didn't feel right for unknown reasons)
Chartist (didn't see much of interactivity and financial related chart types and examples
Chartjs (same as Chartist)
TradingView (I give up after reading their terms of use - weird clause, my point of view)
A majority of others that lacked the level of documentation, interactivity, finance-related charts like Plotly and Highcharts.
Final thought
I found Highcharts to be
Well documented
A ton of jsfiddles examples around
Lots of useful SO answers
Pretty and very functional
Many options
Easy to use
Similar SO questions relating to gaps
How can I hide data gaps in plotly?
HighCharts datetime xAxis without missing values (weekends) (Highcharts)
Remove weekend gaps in gnuplot for candlestick chart (candlestick-chart, gunplot)
How to remove gaps in C3 timeseries chart? (c3/d3 - fiddles are not working so its hard to see the solution)
How to remove weekends dates from x axis in dc js chart (c3.js - the gap is some gap)

Plotly is now supporting to hide weekend and holidays in chart with help of rangebreaks. check this link:https://plotly.com/python/time-series/ go to the section:"Hiding Weekends and Holidays"
Below is section copied from this link, example is for plotly.express but it also works for plotly.graph_objects
Hiding Weekends and Holidays
The rangebreaks attribute available on x- and y-axes of type date can be used to hide certain time-periods. In the example below, we show two plots: one in default mode to show gaps in the data, and one where we hide weekends and holidays to show an uninterrupted trading history. Note the smaller gaps between the grid lines for December 21 and January 4, where holidays were removed. Check out the reference for more options: https://plotly.com/python/reference/#layout-xaxis-rangebreaks
import plotly.express as px
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv')
fig = px.scatter(df, x='Date', y='AAPL.High', range_x=['2015-12-01', '2016-01-15'],
title="Default Display with Gaps")
fig.show()
Display without Gaps
import plotly.express as px
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv')
fig = px.scatter(df, x='Date', y='AAPL.High', range_x=['2015-12-01', '2016-01-15'],
title="Hide Gaps with rangebreaks")
fig.update_xaxes(
rangebreaks=[
dict(bounds=["sat", "mon"]), #hide weekends
dict(values=["2015-12-25", "2016-01-01"]) # hide Christmas and New Year's
]
)
fig.show()

According to documentation
try to add this before fig.show()
fig.update_xaxes(
rangebreaks=[
dict(bounds=["sat", "sun"]), #hide weekends
]
)
or
fig.layout.xaxis.type = 'category'

Using category as the xaxis type worked for me quite nicely (notice the go.Layout object):
import plotly.graph_objects as go
layout = go.Layout(
xaxis=dict(
type='category',
)
)
fig = go.Figure(data=[go.Candlestick(x=self.price_df.index.to_series(),
open=self.price_df[e.OHLCV.OPEN.value],
high=self.price_df[e.OHLCV.HIGH.value],
low=self.price_df[e.OHLCV.LOW.value],
close=self.price_df[e.OHLCV.CLOSE.value])],
layout=layout)
fig.show()

First of all, no need to quit on Plotly. The use of rangebreaks is indeed the tool to use, but that’s one side of it. I say this because for stock data bounds aren't practical compared to values, but you would be specifying dates for many holidays per year, and most of them change from one year to the other. So use values for rangebreaks and feed it with a list of every date that you don’t have in the CSV file you are loading. In case you need a bigger push to solve this, what I mean is taking the ‘date’ column aside, looping through it, and appending dates that are not there in another list. Then you can go fig.update_xaxes(rangebreaks=[dict(values=mylistofdates)])
Hope this brings you back to Plotly!

To remove empty columns such as Weekends from Financial Data using plotly ,Use below code.
Code-
import plotly.express as px
#Daily Percentage change in Nifty 50 Index
daily_returns = np.log(1+df_close.pct_change())*100
fig = px.bar(daily_returns,y = "Close", orientation='v')
fig.update_xaxes( rangeslider_visible=True, rangebreaks=[
dict(bounds=["sat", "mon"]), #hide weekends
])
fig.update_layout(
title='Nifty 50 Daily Returns in %',
yaxis_title='Daily % Change')
fig.update_layout( xaxis_tickformat = ' %d %B (%a)<br> %Y')
fig.show()
Snap-

Related

create a double donut chart in a single view with two measure values in tableau

I need to create this visual in a single view in tableau. The chart contains two value, one is ytd and other one is lytd. both are measures(made by a calculated field). Need help to achieve this visual.
Let's just look at how to show two pie charts on one sheet, which isn't obvious!
In Tableau Public take the Superstore and make dual pie charts for two variables, sales and profits, including all data in each chart.
The trick is to use a new calculated variable MIN(1) ( yes, minimum of one. ) and put that up on the rows shelf. ( To be honest I have no idea at all why this works. )
Here's btProvider's youtube video that suggested this idea.
https://www.youtube.com/watch?v=1rqkjkUsUj4
and here's a polished version what I got relatively easily
Here's a view of what the sheet looks like with Min(1) up on the rows shelf twice which produces two pie charts that can be separately defined on the Marks card.
I put my whole workbook up on Tableau Public so you can see what I did.
https://public.tableau.com/app/profile/wade.schuette/viz/dualpiechartsdemo/Dashboard1?publish=yes

Group by multiple dimensions recursively in dc.js?

dc.js has been great, and now I'm trying to understand how to use it for data with multiple dimensions.
I have time series data (csv), which contains the number of people that fit a certain attribute on a given day - e.g. the number of brown-haired people age 65+. A simplified version of it looks like this (There are 5 options for hair color, 5 for age group, and about 200 dates):
Date, Hair Color, 0-18, 19-39, 40-64, 65+
1/1/21, Brown, 5, 3, 10, 2
1/1/21, Blonde, 15, 2, 4, 1
1/2/21, Brown, 2, 8, 0, 2
1/2/21, Blonde, 11, 6, 7, 4
...
I'd like to be able to plot the cumulative counts over time for each sub-population. The complication is that I'd like to show
A plot aggregated by hair color
(so summing over all age groups), which can then be toggled (ideally by clicking on one of the lines) to show:
A plot for a given hair color
disaggregated by age group.
(Note that in the mockups, I'm normalizing counts to show it as a cumulative percentage. I've been doing that calculation straightforwardly with valueAccessors.)
My question is: how do I create the dimensions and groups to create these plots?
I'd prefer not to create individual variables for each age group (I'd like it to be generic enough to expand to finer categories). But I'm having trouble understanding how to use reduce and filters to achieve my desired outcome.
Also, should I be doing it all as linecharts in a compositeChart, or in a series chart? There is the added wrinkle that I plan to then annotate the chart with extra trendlines added in from d3.
Thanks!
The series chart is a convenience class that generates a composite chart underneath.
It allows you to specify your data using a 2D key, where one component is the key to be used for the X values in the chart, and one component is another key to be used for splitting the data into multiple layers - lines, in your case. You also give it the "prototype" of the layer chart, in the form of a function that returns a partially-initialized chart.
It sounds like you are on the right track, so I won't attempt to give a complete answer, just a few hints. Please feel free to follow up in the comments, and I will edit this answer to fill in details.
Flattening the data
You will probably want to flatten your data so that there is only one value per row, i.e. structure it with an Age column and a Value column. This is a general best practice for working with crossfilter.
It's possible to work with the data as you have it, but
you won't be able to filter by age, since filtering in crossfilter is by row
aggregating across ages will be more complicated, requiring custom reductions
Using multikeys and series chart
Following the series chart example, you might define your dimension as
const colorDateDimension = cf.dimension(d => [d['Hair Color'], d.Date]);
Now any group on this dimension will aggregate by both hair color and date.
Now if you're using the series chart, you can extract the components with
chart
.seriesAccessor(({key}) => key[0])
.keyAccessor(({key}) => key[1])
You could use the third parameter of the series chart chart function to determine the color or dash style of the layer, e.g.:
const dashStyles = {
'0-18': [3,1],
'19-29': [4,1,1,1],
// ...
};
.chart(function(c, _, subkey) {
return new dc.LineChart(c).dashStyle(dashStyles[subkey]);
})
Interaction
dc.js does not natively support the kind of drill-down you are describing. It would be easier to have one chart which is by hair color and another chart which is by age. Then when no hair color is selected, the age chart will show all hair colors, and when no age is selected, the hair color chart will show all ages.
If you want drill-down as you describe, you will have to write custom code to apply the filter and swap the chart definition when a hair color is clicked. It's not terribly complicated but please ask a follow-up question if you can't figure it out - it's better to keep SO questions on a single topic.
Annotating with D3
This part is pretty simple no matter how you implement the charts.
You will implement a pretransition handler and use chart.selectAll to add the content you need. There are many examples here on SO, so I won't go into it here.
Conclusion
I hope this gets you started. I've answered your specific question and given some hints about other assumptions or implicit questions within your question. It will be some work to get the results you want, but it is definitely possible.

CanvasJS - Adding wrong values on X axis (datetime) and line chart mistakes

I've made this chart using canvas.js, the problem is it shows data on april (it uses date and time as X axis) and there is no data for april.
It comes from a 3 month Bitcoin chart, it was too much data so i only left some days here, the chart looks ugly like this but it shows the problem perfectly. My complete charts also has some drawing problems but I assume it's al related to this data that went to april. See fiddle link.
enter code here (not sure why i'm asked to enter code when my code is in that fiddle)
fiddle:
https://jsfiddle.net/K82z6/300/
Ouch, month is cero based when creating the date on canvasjs. Resolved.

Creating Gantt Chart in SSRS 2015 and Data Will Not Display

I have the following result set giving me a specific status of an item . I need to build a SSRS 2015 Gantt chart to represent this data. I am having difficulty getting the data to display.
Result Set: StatusDate,Status,BegDate,EndDate, StatusDays
In the chart, I want the category to be on monthly intervals of the range provided (BegDate – EndDate) and the series to be each DAY in the range provided (BegDate – EndDate).
The bars should represent the item being Up or Down with “Up” being Green and “Down” being black for each day (x-axis) of each month (y-axis).
Hoped for Results
The current preview shows the X & Y axis' correctly, but does not show any "bars" to represent the data.
This is my first chart using SSRS and I am quite lost. Does anyone know where I can get a true tutorial on Range Bar Charts for SSRS 2015 or how I might overcome this “data Display” challenge I am stuck on? I appreciate any direction / guidance offered.
This issue was ultimately resolved by #AlanSchofield through another (and probably more clear) question, found here.
After choosing the correct chart, setting the correct properties, and determining the correct values I was able to get the chart I needed, but the behavior was still off. It would not show the a status more than once.
To fix this, and simply put, I needed to sort my data using Dense_Rank and then add the new "sort" column to my Series Group in the Chart properties. Worked like a charm!
Also got some useful guidelines on this blog post.

Draw line chart using dc js

I wish to draw a simple line chart of my data, plot the sum of reviews against review dates. Examples I've seen so far are only plotting frequencies http://www.d3noob.org/2013/08/add-line-chart-in-dcjs.html i.e. number of occurrence of the days. Can someone please show me how I can do that or a link to an example?
var data = [{review_date:'2013-Feb-1', reviews:40},
{review_date:'2013-Feb-2', reviews:12},
{review_date:'2013-Feb-2', reviews:47},
{review_date:'2013-Feb-3', reviews:71},
{review_date:'2013-Feb-5', reviews:80},
review_date:'2013-Feb-5', reviews:13}]
Is your data sorted by date already? Then just create a new dataset and summarize your data there. You can find an example of a simple line chart here:
http://bl.ocks.org/mbostock/3883245

Resources