I have this example: http://jsfiddle.net/qzprvohr/1/
What i'm trying to achieve - if i click (just once) to some column, i need to select all columns which has the same x-axis value. Currently it works just for clicked one, the rest is unselected. Also is there any possibility to use some background color for selected columns (not for column itself). Something like xAxis.crosshair.color & xAxis.crosshair.width do for hover state.
I tried something like this to select all columns (but it does not work properly):
plotOptions: {
series: {
allowPointSelect: true,
cursor: 'pointer',
point: {
events: {
click: function (event)
{
var selectedCategory = this.category;
var chart = this.series.chart;
for (var i = 0; i < chart.series.length; i++)
{
for (var j = 0; j < chart.series[i].data.length; j++)
{
if (typeof chart.series[i].data[j] !== "undefined" &&
chart.series[i].data[j].category == selectedCategory)
{
chart.series[i].data[j].select(true, true);
}
}
}
}
}
}}}
I played a bit with the example and i think i found the solution. If I use setTimeout function for selection then all selected column will stay in selected state. Also i used plotBands for another background color. Example here: http://jsfiddle.net/qzprvohr/2/
plotOptions: {
series: {
allowPointSelect: true,
cursor: 'pointer',
point: {
events: {
click: function (event) {
var clickedPoint = this;
setTimeout(function () {
var selectedCategory = clickedPoint.category;
var chart = clickedPoint.series.chart;
for (var i = 0; i < chart.series.length; i++) {
for (var j = 0; j < chart.series[i].data.length; j++) {
if (typeof chart.series[i].data[j] !== "undefined" && chart.series[i].data[j].category == selectedCategory) {
chart.series[i].data[j].select(true, true);
chart.xAxis[i].removePlotBand('selection' + i)
chart.xAxis[i].addPlotBand({
color:'red',
from: selectedCategory - 40000000,
to: selectedCategory + 40000000,
id: 'selection'+i
});
}
}
}
}, 0);
}
}
}
}
}
Related
I want to show and hide y-axis on clicking the legends in x-axis. but the condition is that I have different chart values each time I select a value.
so the y axis does not changes its functionality of show and hide.
setValue(chartValue) {
var n
if (chartValue== "a") {
n = 6
}
if (chartValue== "b") {
n = 4
}
if (chartValue== "c") {
n = 8
}
Chart.plugins.register({
beforeDraw: function (c) {
var canvas_id = c.chart.canvas.id;
if (canvas_id === 'myChart') {
console.log("chart val>>", n)
for (var ii = 0; ii < 4; ii++) {
if (!c.isDatasetVisible(ii)) {
c.options.scales.yAxes[ii].display = false;
} else c.options.scales.yAxes[ii].display = true;
}
}
}
});
}
html :
<canvas id="myChart" style="display: block; width: 1415px; height: 550px;"></canvas>
the above code only runs on 1st instance. if I call the same function later on button click it does not work. I want It to work on various n values
Coming again with another question :)
This time I had a requirement to show some progress while Child rows are being loaded. Since there is an Api call which relatively takes little time to return data, I do want to show the some progress unless the user who clicks the parent row is totally unaware whether there is a call done to see its child rows.
What I have done:
I wrote a style sheet class which has a
loader-small.gif
image as this:
tr.loading td.details-control {
background: url('/Images/loader-small.gif') no-repeat center center;
}
and applied like this:
$('#accountManagerEarningsDataTable tbody').on('click', 'td.details-control', function () {
var tr = $(this).closest('tr');
var row = table.row(tr);
try {
if (row.child.isShown()) {
// This row is already open - close it
row.child.hide();
tr.removeClass('shown');
}
else {
//Calling the loading Class ------>
tr.addClass('loading');
// Open this row
var arrForTable1 = [];
var arrForTable2 = [];
totalBrokerage = 0;
totalRetailBrokerage = 0;
totalSelfServiceBrokerage = 0;
console.log('You selected: ' + row.data().AccountManagerID);
var settings = {
"columnDefs": [
{ targets: 1, align: "right", decimals: 0 },
{ targets: 2, align: "right", decimals: 0 },
{ targets: 3, align: "right", decimals: 0 },
{ targets: 4, align: "right", decimals: 2 },
{ targets: 5, align: "right", decimals: 2 }
]
};
//problems with asynchoronus call back
var response = organization_GetAccountManagerDetailEarningsAccountData(row.data(), purl2, pcontext);
if (response.success === "true") {
for (var i = 0; i < response.value.length; i++) {
for (var j = 0; j < response.value[i].Securities.length; j++) {
var itemRow2 = {};
itemRow2["Security ID"] = response.value[i].Securities[j].SecurityId;
itemRow2["Trades"] = response.value[i].Securities[j].Trades;
itemRow2["Buy Qty"] = response.value[i].Securities[j].BuyQuantity;
itemRow2["Sell Qty"] = response.value[i].Securities[j].SellQuantity;
itemRow2["Total Brkg"] = response.value[i].Securities[j].Effective_Brokerage;
itemRow2["Online Brkg"] = response.value[i].Securities[j].Online_Brokerage;
arrForTable2.push(itemRow2);
totalBrokerage = totalBrokerage + parseFloat(response.value[i].Securities[j].Effective_Brokerage);
totalSelfServiceBrokerage = totalSelfServiceBrokerage + parseFloat(response.value[i].Securities[j].Online_Brokerage);
}
totalBrokerage = Math.round(totalBrokerage * 100) / 100;
totalSelfServiceBrokerage = Math.round(totalSelfServiceBrokerage * 100) / 100;
totalRetailBrokerage = Math.round(totalRetailBrokerage * 100) / 100;
var itemRow1 = {};
itemRow1["Account ID"] = response.value[i].AccountId;
itemRow1["Account Name"] = response.value[i].AccountName;
itemRow1["..."] = '<div class="alert alert-info" role="alert">' + buildHtmlTable(arrForTable2, 'table2x' + j, settings) + '<p>Total Brokerage ' + numberWithCommas(totalBrokerage) + '</p></div>';
arrForTable1.push(itemRow1);
arrForTable2 = [];
totalBrokerage = 0;
totalRetailBrokerage = 0;
totalSelfServiceBrokerage = 0;
}
tr.removeClass('loading');
htmlTable1 = buildHtmlTable(arrForTable1, 'table1x' + i);
row.child(htmlTable1).show();
tr.addClass('shown');
}
else {
row.child('<table><tr><td>' + response.value[0].AccountId + '</td></tr></table>').show();
tr.addClass('shown');
};
}
} catch (e) {
console.log(e.message);
}
});
The Problem:
Firefox nicely shows the Progress image after the user clicks it, but Edge and Chrome does not show. Both browsers crossed this piece of code when I was debugging from developer tools of the respective browser.
Its browser compatible problem? Is there a solution for it? Help me please.
In case of chrome there is such an issue while showing the loading bar while making a server call. Please make the following changes where you are making the service call. First add the class loading to the table
tr.addClass('loading');
After that make the service call by giving a timeout function
setTimeout(function(){
var response = organization_GetAccountManagerDetailEarningsAccountData(row.data(), purl2, pcontext);
......
//Your service calls and response call backs
},1);
On providing a timeout (say 1ms), Chrome will get the time to bind the loading bar to DOM, In other case the DOM Object is not available to show the spinner.
I'm currently trying to get a chart I have as drilldown remove all series data previously and redraw with new data. Below I've added the ajax calls and the html/javascript for the chart. The problem was that everytime I called the chart, it would rebuild the chart and double call. So I've been trying to get it to simply remove the data and redraw with new data from the ajax call.
AJAX & SetData call:
self.drilldownLoad = (year: number) => {
self.isDrilldownLoading(true);
self.isDrilldownLoaded(false);
$.ajax({
xhrFields: { withCredentials: true },
url: areaUrl + "api/Incident/IncidentDrilldown?year=" + year,
success: data => {
self.isDrilldownLoading(false);
self.data(data);
self.setDrilldownPlotData(data);
self.isDrilldownLoaded(true);
},
error: data => {
self.loadingError(true)
}
});
}
self.setDrilldownPlotData = (data: any) => {
while (self.drilldownPlotData().length) {
self.drilldownPlotData().pop();
}
while (self.drilldownPlotDataLabels().length) {
self.drilldownPlotDataLabels().pop();
}
var len = data.List.length,
i;
var criticalData = [];
for (i = 0; i < len; i++) {
criticalData.push(
data.List[i].Critical
)
}
var highData = [];
for (i = 0; i < len; i++) {
highData.push(
data.List[i].High
)
}
var mediumData = [];
for (i = 0; i < len; i++) {
mediumData.push(
data.List[i].Medium
)
}
var lowData = [];
for (i = 0; i < len; i++) {
lowData.push(
data.List[i].Low
)
}
for (i = 0; i < len; i++) {
self.drilldownPlotDataLabels.push(
data.List[i].IncidentMonth
)
}
self.drilldownPlotData.push(
{
name: 'Critical',
data: criticalData,
color: '#fa5a5a',
},
{
name: 'High',
data: highData,
color: '#fea156',
},
{
name: 'Medium',
data: mediumData,
visible: false,
color: '#b191c3',
},
{
name: 'Low',
data: lowData,
visible: false,
color: '#83bfd1',
}
)
}
This creates the initial chart. Once the chart is initialized, I set it to not be recreated every time I have data load from this particular ajax call. I can't seem to get it load the series data in correctly and redraw the chart.
var = subchartCreated = false;
viewModel.isDrilldownLoaded.subscribe(function () {
if (!subchartCreated) {
specificChart();
subchartCreated = true;
}
if (subchartCreated === true)
{
for (var i = 0; i < specificChart.series.length; i++) {
specificChart.series[i].remove(true); //forces the chart to redraw
}
}
});
I have two charts, one chart is the initial chart and that one is loading just fine. The second chart is the one of interest and I would like to have it load once and then simply load the series data, remove it from the second chart and then redraw with the new data. This is the click function that I have in the first chart to load the second chart. Currently, it works on the first load, but will not update data beyond that.
point: {
events: {
click: function () {
viewModel.drilldownLoad(this.category);
$('#drilldownButton').removeClass('hidden');
$('#yearlyincident-container').addClass('hidden');
$('#drilldown-container').removeClass('hidden');
$('#incidentInfoGrid').addClass('hidden');
$('#incidentDrillDownGrid').removeClass('hidden');
getDrilldownData(this.category);
}
}
}
I feel like its a relatively easy fix, but I'm just not getting it right. My initial attempts only removed the click functionality of the first chart. Any help with this would be greatly appreciated. Thanks!
Hello im trying to find a way to get the snap property of draggable for Greensock to work without throwprops or livesnap. I would like when you let go of the '.face' for it to snap to the closest spot. It works with livesnap but I don't want to have the jagged dragging of it.
Here is what i'm working with at the moment:
var droppables = $('.face');
var choice = $('.choice');
var gridWidth = 192;
var gridHeight = 256;
var overlapThreshold = '50%';
function onDrop(dragged, dropped) {
TweenMax.fromTo(dropped, 0.2, {opacity:1}, {opacity:0.5, repeat:1, yoyo:true});
}
Draggable.create(droppables, {
type:'x,y',
bounds:$('.content'),
liveSnap:true,
snap: {
x: function(endValue) {
return Math.round(endValue / gridWidth) * gridWidth;
},
y: function(endValue) {
return Math.round(endValue / gridHeight) * gridHeight;
}
},
onDrag: function(e) {
var i = droppables.length;
while (--i > -1) {
if (this.hitTest(choice[i], overlapThreshold)) {
$(droppables[i]).addClass('highlight');
} else {
$(droppables[i]).removeClass('highlight');
}
}
},
onDragEnd:function(e) {
var i = droppables.length;
while (--i > -1) {
if (this.hitTest(choice[i], overlapThreshold)) {
onDrop(this.target, choice[i]);
}
}
Any help would be great.
What you can do is change your conditional logic in the onDragEnd callback and remove everything related to the snap event.
Draggable.create(droppables, {
type:'x,y',
bounds:$('.content'),
onDrag: function(e) {
var i = droppables.length;
for(var j = 0; j < i; j++) {
if (this.hitTest(choice[j], overlapThreshold)) {
$(droppables[j]).addClass('highlight');
} else {
$(droppables[j]).removeClass('highlight');
}
}
},
onDragEnd:function(e) {
var i = droppables.length,
snappedEl = false,
originalOffset = $(this.target).offset();
for(var j = 0; j < i; j++) {
if (this.hitTest(choice[i], overlapThreshold)) {
var targetOffset = $(choice[j]).offset();
onDrop(this.target, choice[i]);
snappedEl = true;
$(this.target).addClass("snapped");
TweenLite.to(this.target, 0.1,{
x:targetOffset.left-originalOffset.left,
y:targetOffset.top-originalOffset.top
});
}
}
if(!snappedEl) {
TweenLite.to(this.target, 0.2, {x:0, y:0});
}
}
}
});
I set up a live sample here:
http://codepen.io/rhernando/pen/e2502a90f4ed69fef0e1e7b8d9c17aae
Also for this type of questions is far better for users to go straight to the GreenSock forums, you'll get a faster and official answer. Not that there's something wrong with coming here for answers, but the GreenSock forums are dedicated to GSAP and you'll get official support from the moderating team that includes the creator of the engine.
Cheers!!
I often have to show serieses with many points and I want to set dataLabels for some points. This works fine, but when the series has too many points, the dataLabel is not visible in the beginning. When I zoom into the series, I can see that it is displayed correctly.
So my question: Is there a way to show the dataLabel always for such a series?
Here is my JSFiddle: http://jsfiddle.net/Charissima/9aB6B/
dataLabel at 51.
$(function() {
var myData = [];
for (var i = 0; i < 50; i++) {
myData.push(i + Math.random() * 3);
}
myData.push(51);
for (var i = 52; i < 400; i++) {
myData.push(i + Math.random() * 3);
}
chart = $('#container').highcharts('StockChart', {
chart : {
zoomType: 'x',
events : {
load : function() {
myChart = this;
mySeries = this.series[1];
},
}
},
plotOptions: {
series: {
dataLabels: {
enabled: true,
formatter: setDataLabels
}
}
},
series: [
{
name: 'Label51',
id : 'dataseries',
color: 'blue',
data: myData
}
]
});
function setDataLabels() {
if (this.y == 51) {
return this.y;
} else {
return null;
}
}
});
This is caused by dataGoruping - disable it and will work fine.