Handsontable cross calculations - handsontable

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.

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

How to draw line plus bar chart using highcharts/d3.js or any other chart library?

How to draw line plus bar chart as below using highcharts/d3.js or any other chart library?
So What exactly I am trying to achieve is "Display bar if no data available for particular time interval" (here chart says that there is not data available for time interval (17:30-18:30)).
Also you can use Highcharts with plotBands functionality (which should be more elastic). There is the algorithm implemented on chart.events.load which checks whether the nulls are in data, and adds the plot bands to your chart dynamically basing on your current data. Take a look at this code:
load() {
var axis = this.xAxis[0]
var boundaries = []
var color = '#55f'
// Check there are nulls in data. If yes, save the boundaries.
data.forEach((elem, i) => {
if (elem === null) {
if (data[i-1]) { boundaries.push(data[i-1][0]) }
if (data[i+1]) { boundaries.push(data[i+1][0]) }
}
})
// Create plotBands basing on current boundaries.
boundaries.forEach((range, i) => {
if (i % 2) {
axis.addPlotBand({
from: boundaries[i-1],
to: range,
color: color
})
}
})
}
Additionally, you can add another series to your chart (fake one, with empty data), which will serve to toggling visibility of plot bands. Here is the code:
{
// Fake series to add toggling visibility of plotbands functionality.
name: "Zone of Unavailability",
data: [],
events: {
legendItemClick() {
var bandsGroup = this.chart.xAxis[0].plotLinesAndBandsGroups['bands-0']
var bandsVisibility = bandsGroup.attr('opacity')
bandsGroup.attr({
opacity: bandsVisibility ? 0 : 1
})
}
}
}
Live example: http://jsfiddle.net/dzj8bwLm/
API Reference:
https://api.highcharts.com/highcharts/xAxis.plotBands
https://api.highcharts.com/highcharts/series.line.events.legendItemClick
You can use Highcharts/Highstock for this. You can put line and column series into one chart and manipulate them however you like.
<script src="https://code.highcharts.com/stock/highstock.js"></script>
<div id="container" style="height: 400px; min-width: 600px"></div>
and
var data = [];
for (let i = 0; i < 100; i++) {
if (i == 10 || i == 11 || i == 12 || i == 13 || i == 14 || i == 15 || i == 16 || i == 17 || i == 18 || i == 27 || i == 28 || i == 29) {
data.push(null)
} else {
data.push([i, Math.floor((Math.random() * 100) + 1)])
}
}
Highcharts.stockChart('container', {
xAxis: {
ordinal: false,
labels: {
format: '{value}'
}
},
series: [{
data: data,
connectNulls: false,
dataGrouping: {
enabled: false
}
}, {
type: 'column',
pointWidth: 9,
dataGrouping: {
enabled: false
},
data: [
[10, 100],
[11, 100],
[12, 100],
[13, 100],
[14, 100],
[15, 100],
[16, 100],
[17, 100],
[18, 100],
[27, 100],
[28, 100],
[29, 100]
]
}]
});
See this online demo: jsFiddle

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

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}'
}

Parsing JSON to highcharts - Data gathered using AJAX

My JSON looks like
[{"target": "sumSeries(integral(org.example.fib.hi.value),integral(org.example.fib.hi1.value))",
"datapoints":
[
[2, 1359214560],
[3, 1359215040],
[4, 1359215050],
[null, 1359215060],
[null, 1359215070],
[5, 1359215080],
[7, 1359215090],
[9, 1359215100],
[10, 1359215110],
[null, 1359215120],
[10, 1359215130],
[14, 1359215140],
[null, 1359215150]
]}
]
I am trying to grab this data from my localhost and have highcharts render a line graph.
I have something like :
$(function() {
$.getJSON('http://localhost/render?target=sumSeries(integral(org.example.fib.*.value))&from=-10minutes&format=json', function(data) {
// Create the chart
window.chart = new Highcharts.StockChart({
chart : {
renderTo : 'container'
},
rangeSelector : {
selected : 1
},
plotOptions: {
series: {
stacking: 'normal'
}
},
series : [{
name : 'AAPL',
data : data,
tooltip: {
yDecimals: 2
}
}]
});
});
});
How can I parse this data?
I assume that you use timestamps (as second parameter in JSON), so data should be parsing to display as datetime. If yes, you should revert your data parameters in JSON, and multiply timestamps by 1000 (javascript timestamps format). Example of parsing:
var tmpdata = [],
i = 0,
len = data[0].datapoints.length;
for(i=0;i<len;i++)
{
tmpdata[i] = [data[0].datapoints[i][1]*1000,data[0].datapoints[i][0]];
}
and then in series data:
series : [{
name : 'AAPL',
data : tmpdata,
tooltip: {
yDecimals: 2
}
}]

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