Highcharts - draw line chart with summed values but show breakup on hover - ajax

I am using Highcharts - Line - Ajax.
Let's say I have two series of data - 'Headcount 1' and 'Headcount 2'. I want to draw a line graph of 'Headcount', which is the sum of the 2 series. However, when someone hovers on one data point, I want to show the individual values in the callout. Is this possible? How can I do this?
e.g.
H1 = (1, 2, 3)
H2 = (5, 6, 7)
Ht = (6, 8, 10)
I will draw a line graph with Ht. If I hover on '6' on the chart, the callout should show the values of H1 = 1 and H2 = 5

You can set the visibility for series H1 and H2 to false,
series: [{
name: 'H1',
data: [1, 2, 3],
visible: false,
showInLegend: false
}, {
name: 'H2',
data: [5, 6, 7],
visible: false,
showInLegend: false
}, {
name: 'H',
data: [6, 8, 10]
}]
and edit tooltip formatter to display what you want
tooltip: {
formatter: function() {
var s = '<b>' + this.x + '</b>';
var chart = this.points[0].series.chart; //get the chart object
var categories = chart.xAxis[0].categories; //get the categories array
var index = 0;
while(this.x !== categories[index]){index++;} //compute the index of corr y value in each data arrays
$.each(chart.series, function(i, series) { //loop through series array
if (series.name !== 'H') {
s += '<br/>'+ series.name +': ' +
series.data[index].y +'m'; //use index to get the y value
}
});
return s;
},
shared: true
}
Have a look at jsfiddle.net/s190ebby/27/

Yes
Points can have custom property, taking care that the names do not shadow highcharts variable names.
var data = [{
y: 6,
h1Value: 1,
h2Value: 5
},{
y: 8,
h1Value: 2,
h2Value: 6
}];
Set your series to this data in your config object, by series: data
Customise the tooltip as:
tooltip: {
pointFormat: '<b>H Value</b>: {point.y}<br/>
<b>H1 Value</b>: {point.h1Value}<br/>
<b>H2 Value</b>: {point.h2Value}'
}

Related

How can I determine if a point is hidden on a 3D Scatterplot (Plotly.js)?

I'm using Plotly.js to draw a 3-D scatter plot . On zoom , I want to check which points are visible . Can this be done on svg level ? or any plotly expert ?
Snippet:
var myPlot = document.getElementById("myDiv");
var trace = {
x: [1, 7, 2, 4,1],
y: [12, 9, 15, 12,2],
z: [1, 2, 4, 8,4],
// x: [1,2],
//y: [12,15],
//z: [1, 4],
mode: 'markers' ,
type: 'scatter3d' ,
marker: {size:5 }
}
var data = [trace];
var layout = {
margin: {
l: 0,
r: 0,
b: 0,
t: 0} ,
//title: {text: 'ReOptim8 Scatter Plot'},
scene: {
yaxis:{title: 'X-axis'},
xaxis:{title: 'y-axis'},
zaxis:{title: 'z-axis'},
camera: {eye: {x:1.25, y:1.25, z:1.25}}
}
};
var config = {
displayModebar : true,
displaylogo: false,
responsive: true
};
Plotly.plot( myPlot, data, layout, config );
Code pen link below :
https://codepen.io/aniwar/pen/wLOzZv

Handsontable cross calculations

I have a handontable demo.
document.addEventListener("DOMContentLoaded", function() {
var
example = document.getElementById('example1'),
hot1;
hot1 = new Handsontable(example, {
data: [
['', '', '', ''],
[1, 2, 3, '=SUM(A2:C2)'],
[1, 2, 3],
],
width: 584,
height: 320,
rowHeaders: true,
formulas: true,
colHeaders: true,
columns: [1, 2, 3, 4],
columnSummary: function () {
var summary = [];
for (var i = 0; i < 4; i++) {
summary.push({
ranges: [[1, 2]],
destinationRow: 0,
destinationColumn: i,
type: 'sum',
forceNumeric: true,
sourceColumn: i
});
}
return summary;
}
});
});
It caclulates:
Sum of column and puts a result in the first raw.
Sum of rows (except first one) and puts it in the column "D"
I need to calculate correct total of the totals, which is the cell D1.
After loading and changing any cell calculation of D1 has to work properly.
Thank you for any ideas.
The option columnSummary should not be applied on the 4th column (the column of SUM results). Try to apply you code of columnSummary option only for the first three columns :
for (var i = 0; i < 3; i++) //Instead of i < 4
And use in the row one what you use to calculate the sum on your other rows :
data: [
['', '', '', '=SUM(A1:C1)'],
[1, 2, 3, '=SUM(A2:C2)'],
[1, 2, 3, '=SUM(A3:C3)'],
],
You will see that it works like a charm : JSFiddle.

jqGrid - formoptions rowpos and colpos is being used to create 3 column View form. How can you make 1 row's data field colspan the full width/

If I have configured the formoptions to create a form with 6 columns (3 for labels and 3 for data) and I want 1 row in the form to have 2 columns (1 for label and 1 for data that is the full width of the form), how can I do this?
I've tried using colSpan and looking at this example but could not get it to work.
Here's the structure of my jqGrid:
colModel :[ {
label: 'Row 1 Column 1',
name: 'a',
formoptions: {
colpos: 1, // the position of the column
rowpos: 1, // the position of the row
}
}, {
label: 'Row 1 Column 2',
name: 'b',
formoptions: {
colpos: 2, // the position of the column
rowpos: 1, // the position of the row
}
}, {
label: 'Row 1 Column 3',
name: 'c',
formoptions: {
colpos: 3, // the position of the column
rowpos: 1, // the position of the row
}
}, {
label: 'Row 2 Full Width',
name: 'd',
formoptions: {
colpos: 1, // the position of the column
rowpos: 2, // the position of the row
}],
and the configuration of the view form options
{
//edit options
},
{
//add options
},
{
//del options
},
{
//search options
},
{
//view options
width : 1000,
labelswidth :50,
viewPagerButtons : false,
closeOnEscape : true,
beforeShowForm: function(form) {
var dlgDiv = $("#viewmod" + mygrid[0].id);
var parentDiv = dlgDiv.parent();
var dlgWidth = dlgDiv.width();
var parentWidth = parentDiv.width();
var dlgHeight = dlgDiv.height();
var parentHeight = parentDiv.height();
dlgDiv[0].style.top = Math.round((parentHeight-dlgHeight)/2) + "px";
dlgDiv[0].style.left = Math.round((parentWidth-dlgWidth)/2) + "px";
var $tr = $("#trd_d"), // 'name' is the column name
$label = $tr.children("td.CaptionTD"),
$data = $tr.children("td.DataTD");
$data.attr("colspan", "5");
$data.children("input").css("width", "95%");
$label.hide();
}
};
You need to hide some unneeded columns in the second row of the View. The code of beforeShowForm could be like below
beforeShowForm: function ($form) {
var $captionTds = $("#trv_d>td.CaptionTD"),
$dataTds = $("#trv_d>td.DataTD");
$captionTds.filter(":gt(0)").hide();
$dataTds.filter(":gt(0)").hide();
$dataTds.first().attr("colspan", 5);
}
I'd recommend you additionally to use formViewing option to specify View options. It makes the code more readable. See https://jsfiddle.net/OlegKi/4xyf0adw/

Adding custom non-uniform labels to a Y-axis of a stacked area chart in NVD3

I want a stacked area chart of several datasets. possibly unusually I want to use the y axis to clarify what each set represents and its starting value.
i.e. The Y-axis doesn't need to be a regular tick over the range of the data.
for the sets:
[
{key: 'the first set', values: [x: 0, y: 4]},
{key: 'the second set', values: [x: 0, y: 10]},
]
the y-axis should have a tick at 4 labelled: 'the first set: 4', and another at 10 labelled: 'the second set: 10'
nv.addGraph(function() {
var chart = nv.models.stackedAreaChart()
.showLegend(false)
.showControls(false);
var data = [
{
key: 'first',
values: [
{ x: 0, y: 2 },
{ x: 2, y: 4 },
{ x: 4, y: 6 },
{ x: 6, y: 8 }
]
},
{
key: 'second',
values: [
{ x: 0, y: 4 },
{ x: 2, y: 6 },
{ x: 4, y: 8 },
{ x: 6, y: 10 }
]
}
];
var firstItemsLabels = ['', 'first', 'second', ''];
var firstItemsValues = [0, 2, 4, 10];
//the below doesn't seem to make any difference
//var firstItemsLabels = ['first', 'second'];
//var firstItemsValues = [2, 4];
chart.yAxis.tickValues(firstItemsLabels);
chart.yAxis.tickFormat(function(d, i) {
console.log('getting tick format for d: "' + d + '" at i ' + i);
console.log('for i: ' + i + ' = ' + firstItemsValues[i]);
var result = firstItemsValues[i];
return result;
});
d3.select('#chart svg')
.datum(data)
.call(chart);
nv.utils.windowResize(chart.update);
return chart;
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.3.13/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.1/nv.d3.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.1/nv.d3.css" rel="stylesheet">
<div id="chart">
<svg></svg>
</div>
I thought that the code in this snippet should achieve that but it doesn't
The console log output from that snippet...
getting tick format for d: "" at i 0
for i: 0 = 0
getting tick format for d: "first" at i 1
for i: 1 = 2
Error: Invalid value for <g> attribute transform="translate(0,NaN)
getting tick format for d: "0" at i undefined
for i: undefined = undefined
getting tick format for d: "18" at i undefined
for i: undefined = undefined
...confuses me because tickformat is looking for a value of 18 at one point which isn't in the dataset.
Am I trying to achieve something impossible? If not, since I'm clearly doing it wrong, how can it be done?
If I understand your goal correctly, you can use:
chart.yAxis.tickValues([4,10]);
chart.yAxis.tickFormat(function(d, i) {
if (d === 4 || d == 10) {
return "the first set: " + d
}
});
See this Plunk for a working example:
http://plnkr.co/edit/sdM14ebvv8cYCvOtX8em?p=preview

How to render jquery jqplot 3 year stacked line graph with a date axis render

I would like to be able to use jqplot to stack 3 different years of data on top of each other to compare the data accordingly. The only way to do it that I have found is to "hack" the dates of each result series to use the same year as a base date.
This is not exactly ideal and was wondering if anyone had found a better fix?
I am using C# and javascript to do this for 2 years of data.
In C#
I perform 2 queries to the database getting year1 data and year2 data.
I loop through year2 data setting the year to be the same as year1
I push this data to the client in two arrays. If there is no data for one of the years I set the array to null. Sending an empty array makes jqplot display an empty graph.
I push the two labels for example 2011 and 2010.
On the client
I create an array of data.
If the year array is not null I push it to the array.
I display the charts. I thought I might need to create an array for holding the labels, but jqplot doesn't display the labels when there is no corresponding chart. If you are doing it for three years you will need to have a seperate array for labels.
Here is my C# code:
protected void btnShowGraph_Click(object sender, EventArgs e)
{
SomeRatingSummary SearchCriteria = GetSearchCriteria();
var year1Results = SearchCriteria.ExecuteFind();
string year1Label = SearchCriteria.YearTypeCode;
StringBuilder year1 = getJavaScriptArrayFromRatingsData(year1Results);
int year1int = int.Parse(year1Label);
SearchCriteria.YearTypeCode = (year1int - 1).ToString();
var year2Results = SearchCriteria.ExecuteFind();
year2Results.ToList().ForEach(a => a.FirstSeasonRating = DateTime.Parse(a.FirstSeasonRating).AddYears(1).ToShortDateString());
var year2Label = SearchCriteria.YearTypeCode;
StringBuilder year2 = getJavaScriptArrayFromRatingsData(year2Results);
string script = " jQuery(document).ready(function () {{drawChart('{0}','{1}',{2},{3});}});";
string filledScript = String.Format(script, year1Label, year2Label, year1, year2);
this.Page.ClientScript.RegisterStartupScript(this.GetType(), "callChart", filledScript, true);
}
private static StringBuilder getJavaScriptArrayFromRatingsData(SubSonicList<SomeRatingSummary> results)
{
var firstYear = results.OrderBy(srs => srs.FirstSeasonRating).GroupBy(a => a.FirstSeasonRating).Select(g => new { value = g.Key, count = g.Count() });
string prefix = "[";
StringBuilder year1 = new StringBuilder(prefix);
firstYear.ToList().ForEach(a => year1.AppendFormat("['{0}', {1}],", a.value, a.count));
if (year1.Length > prefix.Length)
{
year1.Length = year1.Length - 1;
year1.Append("]");
}
else
{
year1.Length = 0;
year1.Append("null");
}
return year1;
}
Here is my JavaScript code:
function drawChart(year1Label, year2Label, year1Data, year2Data) {
//these are two sample charts.
//var line1 = [['2008-09-30 4:00PM', 1], ['2008-8-30 4:00PM', 3], ['2008-11-30 4:00PM', 5], ['2008-12-30 4:00PM', 7], ['2009-01-30 4:00PM', 9]];
//var line2 = [['2008-09-31 4:00PM', 5], ['2008-10-20 4:00PM', 2], ['2008-11-15 4:00PM', 4], ['2008-12-16 4:00PM', 9], ['2009-01-29 4:00PM', 8]];
var chartData = [year1Data];
if (year2Data != null) {
chartData.push(year2Data);
}
var plot1 = jQuery.jqplot('chart1', chartData, {
grid: {
//background:'#f0ffff',
background: '#F0F8FF',
gridLineColor: '#dfdfdf',
borderWidth: 1.5
},
title: 'Ratings by Day',
axes: { xaxis: {
renderer: jQuery.jqplot.DateAxisRenderer,
rendererOptions: { tickRenderer: jQuery.jqplot.CanvasAxisTickRenderer },
tickInterval: '2 month',
tickOptions: { formatString: '%b' }
}
},
legend: { show: true, location: 'e', showSwatch: true },
seriesDefaults: { showMarker: false, lineWidth: 1.5, markerOptions: { style: 'square'} },
series: [{ label: year1Label }, { label: year2Label}]
});
};

Resources