I have 2 timeseries that I would like to 'share' tooltip across. However, I have a problem where only the first point of each series is aligned and shares the tooltip. The rest of the points are slightly misaligned and therefore fail to show in the tooltip at the same time.
This fiddle will help demonstrate the problem. Fiddle
If you hover over the very first point, the tooltip appears with an entry for both series. But the very next datapoint only displays a single entry in the tooltip.
May I ask for your advice please? What have I missed for 'aligning' both series in order to share the tooltip? Clearly it's not enough to just add
tooltip: {
shared: true,
}
Thank you.
Assuming that the end goal is to compare two different dates based on the time of day, and assuming that the data points are at regular intervals, or are close enough and can be fudged (ie 1 point per hour, or every 10 minutes, etc), I would approach this differently:
1) use a single date. it can be today's date, or any other date, it doesn't matter, as the time of day is the important segment of the date string.
2) use the pointStart and pointInterval properties to set the proper timing (based on the artificial date, but the correct time interval)
3) Set the actual date of each data series as the series name, which will show in the legend and the shared tooltip to properly display the date of each data set.
4) use the formatting options on the x axis labels to show only the time portion of the label and not the date
In this way you remove the need for a 2nd x axis, remove any complications in tooltip formatting, remove the need to use more complex data structures like in your comment ( "{"y":0.87,"realDateTime":'25/12/2015 03:00'}" ), and only ever have to pass the appropriate date to the name property of each series.
//use the current date as the base - the date doesn't matter, just the time
var d = new Date();
var date = new Date(d.getFullYear(), d.getMonth(), d.getDate(), 0,0,0);
var pointStart = date.getTime();
var pointInterval = 3600 * 1000 // 1 hour
.
series: [{
name : 'Apr 17, 2015',
data : [2,5,8,9,8,7,4,5,6,9,8,7,8,9,8,7,8,5,3,2,1,4,4,5]
},{
name : 'Jun 12, 2015',
data : [3,6,9,5,4,7,8,5,2,1,4,5,9,8,7,5,6,9,8,7,4,5,6,3]
}]
Example:
http://jsfiddle.net/jlbriggs/b3t7ueam/
[[and, of course, you can do this with as many different dates as desired (though this many obviously doesn't make sense):
http://jsfiddle.net/jlbriggs/v76u9w2L/
]]
I know that this is an old question, but an alternative approach which I've found to work is to reformat the data into a CSV format and add an import for the data module.
There's a demo on the Highcharts site which does pretty much what you're asking for (albeit nested inside an ajax request) over here. The two key parts from there are:
<script src="https://code.highcharts.com/modules/data.js"></script>
and
data: {
csv: csvData
}
The example reads in an actual csv file, but it'll accept any string which is formatted similarly. Also, if you set up headers in that csv string, you don't need to declare their names in your series options.
Related
Is it possible to remove certain days in highcharts? I have a chart that only get data intervals from Monday to Friday. The problem Is that Saturday and Sunday is auto added to the graph even when there is no data for these days. I cant find anything that helps on api.highcharts.com they usually have solutions to all graph related problems but I cant seem to find anything about my problem. It's probably some easy option in the chart but I cant find anything that works.
You have two options, use highcharts and breaks.
An array defining breaks in the axis, the sections defined will be left out and all the points shifted closer to each other.
Requires that the broken-axis.js module is loaded.
It would look something like this, in a datetime axis:
xAxis: {
tickInterval: 1,
breaks: [{
from: 1537567200000,
to: 1537740000000,
breakSize: 1
}]
}
Working example: http://jsfiddle.net/ewolden/L3ykegzq/
Or switch to highstock where you can have an ordinal axis (ordinal is used by default):
In an ordinal axis, the points are equally spaced in the chart regardless of the actual time or x distance between them. This means that missing data periods (e.g. nights or weekends for a stock chart) will not take up space in the chart. Having ordinal: false will show any gaps created by the gapSize setting proportionate to their duration.
Working example: http://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/stock/xaxis/ordinal-true/
JSFiddle here: https://jsfiddle.net/ayyrickay/k1crg7xu/47/
My code is a bit of a mess right now, but essentially, I have two choropleths, and I want to render a multiline chart based on the choropleth data - I just have no idea how to wrangle the data to make it work.
The line chart is be a composite line chart. One line would be New Yorker circulation data, the other would be Saturday Evening Post circulation data. The y axis is issue_circulation, the x axis is actual_issue_date
In the current implementation I’ve set up two crossfilters (one for each data set) and I’m creating a dimension for the choropleth and one for the line chart. The choropleths render properly, but I’ve yet to get the line charts to render. I can’t tell if its because of the format of my data ({key: date, value: y-axis-value}) or if my implementation of crossfilter is just too janky. I'm trying to understand based on other StackOverflow questions, but nothing I've tried seems to work (this includes prefiltering the data like I'm doing now, creating two different crossfilters and separate dimensions, trying to be meticulous apart parsing dates, etc.)
When you're using a time scale for the X axis, the keys of your group should be Date objects. So it won't work to format the dates as strings when creating the dimensions & groups; instead just use raw Date objects.
Since Dates are slow, I suggest doing this as a data preprocessing step:
data.forEach(function(d) {
d.actual_issue_date = new Date(d.actual_issue_date);
})
Then your dimension key functions just extract the date object:
const dimension1 = title1Circulation.dimension(d => d.actual_issue_date)
const lineChartYear1 = title1Circulation.dimension(d => d.actual_issue_date)
const lineChartYear2 = title2Circulation.dimension(d => d.actual_issue_date)
This ends up looking kind of messy, because the Saturday Evening Post data fluctuates a lot by week:
Zoomed in:
Assuming this isn't a data cleaning problem (kind of looks like it?), one way to improve the display would be to aggregate by month:
const circulationGroup1 = lineChartYear1.group(d => d3.timeMonth(d)).reduceSum(d => d.issue_circulation)
const circulationGroup2 = lineChartYear2.group(d => d3.timeMonth(d)).reduceSum(d => d.issue_circulation)
composite
.xUnits(d3.timeMonths)
This rounds the group key down to the beginning of each month, adding together all the values for each month.
Still kind of messy, but better:
Welp, you still have some work to do, but anyway, that's why the data was not displaying!
Fork of your fiddle.
Could any one please let me know, how to display monthly, weekly, daily data from JSON.
Example:
How to obtain last 4 weeks of data from JSON (Monthly) ?
How to obtain last 12 months of data from JSON (Yearly) ?
How to obtain last 7 days of data from JSON (weekly) ?
JSON Example:
{"date" : "2016-06-16"}
...
...
{"date" : "2016-05-16"}
{"date" : "2016-04-16"}
I moved your code to plnkr (I'm not a fan of jsfiddle; plnkr lets you create files as you want.
First, I noted you use d3 v3; I would recommend upgrading to v4 to enjoy the latest functionalities and improvements (but this is out-of-topic).
Second, I added a couple of lines (102 to 107) to create a nesting of data by month (as an example):
var byMonth = d3.nest()
.key(function(d){
return d.month;
})
.entries(data["BC"])
console.log(byMonth);
Now, the object byMonth has a key property, corresponding to the number of the month you already mapped, and a values property containing all values in said a month. You could now create/update a scale range using something like scale.range(byMonth.map(function(d){return d.key;}), use that scale for an axis, and plot your data accordingly. The same technique could be applied to the day or year property.
I've made a custom data source selector for the Google Chart Editor which has worked out wonderfully, but I'm running into an annoying little problem with the way the dates are represented on the continuous major axis of type date. For some reason, giving a date at the end of the year (e.g. new Date(2014,11,31,0,0,0)) gets labelled as the next year.
Here's a JSFiddle that describes the issue. I know I could just use a discrete axis and pass a string representation of the year, but my data source selector allows selecting a different interval (i.e. daily, monthly, weekly yearly) and a continuous axis is best for this.
Does anyone know why this happens, and is there a way to adjust how the API chooses labels for a continuous date axis?
It's interesting how phrasing a question for others can make one think of an answer. I decided to try specifying the options.hAxis.ticks and although I pass the same dates, it does change the hAxis labels to what I expect.
See the JSFiddle
It's not the best solution, since I would rather have the hAxis ticks match the nearest data point, but it is functional.
Here are the options that I specified:
var options = {
title: 'Total Sales Value Per Year',
hAxis: {
title: 'Year End',
ticks: [
new Date(2010,11,31,0,0,0),
new Date(2011,11,31,0,0,0),
new Date(2012,11,31,0,0,0),
new Date(2013,11,31,0,0,0),
new Date(2014,11,31,0,0,0)
]
}
};
I'm using Highcharts for a project in which I have to display two series with about a thousand points each. The x-axis represents a date, and the y-axis a quantity. In addition, each point has an associated list of namesMy data is day-by-day without gaps, with a structure such as
var mydata = [ ...
{x: theDate, y: theValue, names: theNames},
... ]
where theNames is an array of strings. I can access these in the tooltip formatter through this.points.point.names, given that the range displayed on the chart is small enough. If I change the x-axes so that the start date and end date are more than roughly a year apart, then the tooltip is not rendered at all.
One of the possible avenues that I have tried but failed with so far is setting the turboThreshold limit to the length of the longest series plus 1. Setting this lets me at least display a graph when mydata.length > 1000 (the default value). However, this only displays the tooltip if the x-axis range is less than 261. Otherwise, the tooltip disappears entirely, as does the point.data object where I'm getting the name from.
I'm also not great at JavaScript, but I was wondering if there were a way to separate the names of the points from the array containing them (in my examples, myData1 and myData2) and somehow access those names from the tooltip function without going through the current point.
Here is the link to the jsFiddle demonstrating this issue.
All help is appreciated!
The problem is in dataGrouping, when disabled works fine: http://jsfiddle.net/34tfg/1/
DataGrouping is method in Highcharts to approximate points and display them when width of the chart is not enough, e.g. how to display 10 000points in a chart of width 1 000px -> 10 points in a one pixel..? And when dataGrouping is used, new points are created, so all your custom options like 'names' etc. are lost (at least not accessible).
Code:
plotOptions: {
line: {
dataGrouping: {
enabled: false
},
turboThreshold: 10000
}
},