I'm trying to create a project scheduling plot using Highcharts and I'm having a bit of an issue separating the values I want to plot from the axis labels. For example, I want a task to start in week 20 of 2016 so what I have been doing is just concatenating the year and week into: "201620" and then turning it into a category. For my labels I simply split off the last two digits from the first four so it looked like "2016-20". I accomplished this by using the label formatter code in the yAxis portion of the code:
formatter: function() {
var FullDate = this.value.toString();
var FiscalYear = FullDate.substring(0, 4);
var WorkWeek = FullDate.substring(4, 6);
return FiscalYear + '-' + WorkWeek;
}
This works great as long as all the tasks happen within the same year (see fiddle).
My problem is what to do when 2017 comes around (there shouldn't be 99 weeks in the year, see fiddle). I therefore am converting the work weeks into an auto-calculated integer but I still want my plots to display "2016-20".
So my question is: How can I plot integers but display separate text on an axis?
Link to working example.
Any help would be appreciated!
I added an array at that stored my axis label and I think I solved my issue. Link to fiddle here.
var WorkWeekLabels = {
'1967' : '2016 - 23',
'1968' : '2016 - 24',
'1969' : '2016 - 25',
'1970' : '2016 - 26',
'1971' : '2016 - 27',
'1972' : '2016 - 28',
'1973' : '2016 - 29',
...etc...
}
This post pretty much solved it for me.
Related
I'd like to visualize the amount of steps taken over a day. Each datapoint looks simplified like this:
{
startDate: 1481029440000,
endDate: 1481029920000,
steps: 31
}
I'd like to plot it over an entire day and illustrate the duration but also the grow of step increase. Each datapoint is a separate series as I didn't want to have points connected to each other.
The result looks like what I want except for the styling which I have change. However the performance and zoom into the chart is extremely slow. Might there be a better way to use it?
Highcharts is optimised for managing many points, not many series (the work has been start on optimising series, though - as far as I know).
You can use one series with the null points as separators. By default connecting nulls is disabled.
data: (function (data) {
var d = [], i = 0, len = data.length, point;
for (; i < len; i++) {
point = data[i];
d.push([point.startDate, point.steps], [point.endDate, point.steps]);
if (i < len - 1) {d.push([point.endDate, null]);}
}
return d;
})(data)
example: http://jsfiddle.net/7vtd4fzm/
I have a requirement where i have to show custom points on x-axis instead of dates values. Also same custom data points needs to be shown on navigator as well. In the below Js fiddle, i am converting data (Per13/2016 etc) into equivalent date values and then binding the chart using converted date values.
Below is the link of the JS fiddle:- Fiddle link
In the Js fiddle, i am showing Per1,Per2 etc.on x-axis and same has to be shown on navigator as well.
Now i am facing problem with the navigator,when i changes the range using slider ,the x-axis labels changes but not according to the range selected.Also tool-tip formatting is getting changed.
Can you please let me know how to handle this scenario and best way to do the same.
//few code lines to post fiddle link
xAxis: {
labels: {
formatter: function () {
if(fiscal13){
var perDate = new Date(this.value);
return 'Per' + (perDate.getMonth() + 1);
}
}
}
}
I am not sure if I am right, but I think you are overdoing this.
Let's keep original data, so remove fiscal13Data.Data.forEach(function(item) { .. }); function. And When creating data, use simply index of the point as x-value:
var cost = [],
usage = [],
dataLength = fiscal13Data.Data.length
i = 0;
for (i; i < dataLength; i += 1) {
// need to sum costs
cost.push([
i, // the index
fiscal13Data.Data[i]['Cost'] // cost
]);
usage.push([
i, // the index
fiscal13Data.Data[i]['Usage'] // Usage
]);
}
Now you can get to the "Per13/2016" strings in a simple way in xAxis labels' formatters:
var str = fiscal13Data.Data[this.value].Date;
In tooltip formatter, it is almost exactly the same:
var str = fiscal13Data.Data[this.x].Date;
And here is working demo: http://jsfiddle.net/qneuh4Ld/3/
Note: You data looks a bit strange - don't you want to sort it first? Also, you have twice every date (e.g. "Per13/2016" - once for "water" and once for "electric").
Here is a necessary code snippets,
X axis label formatter,
NSDateFormatter dateFormatter = new NSDateFormatter();
dateFormatter.DateFormat = "dd/MM";
var timeFormatter = new CPTTimeFormatter(dateFormatter);
timeFormatter.ReferenceDate = NSDate.FromTimeIntervalSinceNow(0);
x.LabelFormatter = timeFormatter;
Delegate method of getting records,
public override NSNumber NumberForPlot(CPTPlot plot, CPTPlotField forFieldEnum, nuint index)
{
if (forFieldEnum == CPTPlotField.ScatterPlotFieldX)
return new NSNumber((index + 1) * 86400);
Debug.WriteLine("{0}", Data[(int)index].Rate);
return Data[(int)index].Rate;
}
See attached screenshot for result looks like. You can see that markers are not aligned to X axis. First data point should display on “01/01” but it is displaying just before it. Same for all other points.
Let me know if anybody wish to look at any other part of code. I just need direction or clue what could lead to this record shifting. I have already looked at sample code provided in coreplot but didn't get any clue on this.
Edit:
Ranges are as below,
plotSpace.XRange = new CPTPlotRange(NSNumber.FromDouble(0).NSDecimalValue, NSNumber.FromDouble(86400 * 9).NSDecimalValue);
plotSpace.YRange = new CPTPlotRange(NSNumber.FromDouble(-1).NSDecimalValue, NSNumber.FromDouble(9).NSDecimalValue);
Also tried,
var space = graph.DefaultPlotSpace as CPTXYPlotSpace;
space.ScaleToFitPlots(new CPTPlot [] { dataSourceLinePlot });
Edit: Graph setup code
The problem is with the ReferenceDate for the time formatter. It is being initialized with the current date and time, so the offset will vary throughout the day depending on when the setup code runs. There are several ways to make an NSDate object that corresponds to a fixed time of day. The most straightforward is by using NSDateComponents.
Several of the Core Plot example apps, including the "Date Plot" demo in the Plot Gallery app, use this technique to generate reference dates.
Also, the automatic axis labeling policy doesn't work well with dates. It's picking tick locations that fall on "nice" numbers of seconds between ticks, but that doesn't correspond to even numbers of days. You should use the fixed interval policy (the default) or one of the ones that let you provide the tick locations directly.
I have set up a fiddle which allows you to move the highstock navigator and see underneath the times selected plus a sum of the values for the selected period.
http://jsfiddle.net/o8dLh3m5/3/
The problem I am having is that when the selection contains too much data, the chart.series[0].data array is empty so I can't calculate the total.
Could someone please explain what is happening (ie where is this threshold set?), and what are my options for calculating totals when the data returned is larger than the threshold.
Thanks in advance,
xAxis:{
type: 'datetime',
events: {
afterSetExtremes:function(event){
// convert to dd/mm/yyyy hh:mm
var start_date = new Date(event.min);
var end_date = new Date(event.max);
$('#id_start_date').text( moment(start_date).format('DD/MM/YYYY HH:mm') );
$('#id_end_date').text( moment(end_date).format('DD/MM/YYYY HH:mm') );
// get totals
var sum = 0, chartOb = this;
$.each(chartOb.series, function(series_id){
$.each(chartOb.series[series_id].data, function(i,point){
// array returned is empty!
When number of points exceeds cropThreshold, then array can be empty. I think it would be better to use series.processedYData to calculate that sum. That is just an array with actually displayed y-values on a chart in one series.
Note: It's not part of official API but can be used ;)
I've read some articles about the weekend problem with teechart and the suggestions are the foolowing steps:
TChart1.Series(0).XValues.DateTime = False
Use continuous numbers as Xvalues
replace the X label with datetime.
The problem is: I draw the real time candlesticks according to the date,hour and minute and I must keep TChart1.Series(0).XValues.DateTime = True
So are there any ways to get rid of the null weekend (not only the weekend, even some time in a day as from 5:15 to 6:00 need to be removed) so that the candlesticks are shown continuously (the Xvalues must keep datetime style all the time)?
thanks.
(BTW, I use Teechart2011 Eval & VB6)
TeeChart draws each point according to its X and Y values in the associated axes.
You can work with Break Axis tool to obtain a discontinuous effect in an axis, but the easiest way to draw the points continuously in the horizontal axis is having continuous X values. So I'd suggest you to use the TChart1.Series(i).asCandle.AddCandle XVal, OpenVal, HighVal, LowVal, CloseVal, Label, clTeeColor function, being:
XVal: TChart1.Series(i).Count, instead of the date retrieved from the system
Label: the date retrieved from the system, converted to string
If this doesn't solve the problem because you still think you must have DateTime XValues, please explain why.
Taking your snipped of code from here, I've created a simple example that seems to work fine for me here. Find it below:
Private Sub Form_Load()
Dim month, day, year, hour, minute, second, nums As Integer
Dim tmpDate As Date
month = 6
day = 7
year = 2012
hour = 6
minute = 15
second = 0
nums = 10
TChart1.Aspect.View3D = False
TChart1.AddSeries scCandle
TChart1.Axis.Bottom.Labels.Angle = 90
For i = 1 To nums
tmpDate = (DateValue(day & "," & month & "," & year) + TimeValue(hour & ":" & minute & ":" & second))
If Not IsWeekend(tmpDate) Then
With TChart1.Series(0)
.asCandle.AddCandle .Count, 5, 15, 0, 10, tmpDate, clTeeColor
End With
End If
day = day + 1
Next i
End Sub
Public Function IsWeekend(InputDate As Date) As Boolean
Select Case Weekday(InputDate)
Case vbSaturday, vbSunday
IsWeekend = True
Case Else
IsWeekend = False
End Select
End Function