I implemented this example from dc.js examples here.
Also, I added .brushOn(true) option to my chart. After my brushing, I need to get selected information.
My filter function:
.on('filtered', function(chart){
console.log(runDimension.top(Infinity));
})
Unfortunately, I can't call onFiltered event with brushing.
I added one more listener for brushend event and get here empty object:
var b = chart.brush();
b.on('brushend.custom', function() {
console.log(runDimension.top(Infinity));
});
How can I get selected information with brushOn(true)?
P.S I use this branch of dc.js with version 2.1.0-dev, because I need grouped charts.
Related
I have a simple line graph made with chartjs with a legend. By default, when the user clicks the legend then it shows/hides the dataset that the user clicked. I have a callback function that I would like to call, but when I assign the callback function to the legend, then the original functionality of showing/hiding the datasets is not present anymore. Is there a way for me to add my callback function without getting rid of the default functionality? Below is how my current legend onClick looks, "vm.legendOnclickCallback()" simply calls a console.log statement for now, for testing. My filter function is used to get rid of a bar (named dayBar) from the legend.
legend: {
labels: {
filter: function (item, chart) {
return !item.text.includes('dayBar');
}
},
onClick: vm.legendOnclickCallback
}
The docs show how to do this. You can call the default handler in your custom function:
var defaultLegendClickHandler = Chart.defaults.global.legend.onClick;
defaultLegendClickHandler(e, legendItem);
In my project I need to save the data to .txt or .xml or .json file. I could not find any answer from vis.js website/issues blog. It might be simple, do not know. Really helpful if anyone help me out with example code. Thank you so much in advance.
function saveData(data,callback) {
data.id = document.getElementById('node-id').value;
data.label = document.getElementById('node-label').value;
clearPopUp();
callback(data);
}
If I understand you correctly, you are looking for a way to save data and options of a graph. In my graph editor adaptation for TiddlyWiki Classic I use the following method to extract data (the full implementation can be found in the repo, see config.macros.graph.saveDataAndOptions, here's a simplified one):
config.macros.graph.saveDataAndOptions = function(network,newOptions) {
newOptions = newOptions || {};
// get nodes and edges
var nodes = network.body.data.nodes._data; // contains id, label, x,y, custom per-node options and doesn't contain options from options.nodes; presumably contains option values set when network was created, not current ones (it is so for x,y)
// no suitable getter unfortunately
var edges = network.body.data.edges._data; // map; for edges to/from? certain node use network.getConnectedNodes(id)
// network.body.data.edges._data is a hash of { id: , from: , to: }
// get node positions, options
var positions = network.getPositions(), // map
options = // get options stored previously
// merge newOptions into options
for(var nodeId in nodes) {
// nodes[nodeId].x is the initial value, positions[nodeId].x is the current one
if(positions[nodeId]) { // undefined for hidden
nodes[nodeId].x = positions[nodeId].x;
nodes[nodeId].y = positions[nodeId].y;
}
storedNode = copyObjectProperties(nodes[nodeId]);
storedNodes.push(storedNode);
}
//# do whatever you need with storedNodes, edges and options
// (pack them with JSON.stringify, store to a file etc)
};
However, while this works ok for storing data, this only helps to save options passed for storing explicitly which can be not very nice for some cases. I use this method in manipulation helpers and on dragEnd (network.on("dragEnd",this.saveToTiddlerAfterDragging), config.macros.graph.saveToTiddlerAfterDragging = function(stuff) { config.macros.graph.saveDataAndOptions(this,{ physics: false }); };). I haven't recieved any better suggestions, though.
If you need to get data and options reactively and setting such helper to handle certain edit events can't solve your problem, then I suggest wrapping nodes, edges and options as vis.DataSet and save those when needed. This is related too.
To answer the question about events/other ways to use such methods. Here's how I use them:
I save data after drag&drop moving of nodes, this is done using an event handler. Namely, I introduced
config.macros.graph.saveToTiddlerAfterDragging = function(stuff) {
config.macros.graph.saveDataAndOptions(this,{ physics: false });
};
(when drag&drop is used, physics should be switched off, otherwise coordinates won't be preserved anyway) and then I use
network.on("dragEnd",this.saveToTiddlerAfterDragging);
so that changes are saved.
As for saving after adding/editing a node/edge, I apply saving not by an event (although it's nice thinking, and you should try events of DataSet, since there's no special graph events for that). What I do is I add an elaborated hijack to the manipulation methods. Take a look at the source I've linked after the
var mSettings = options.manipulation;
line: for each manipulation method, like options.manipulation.addNode I hijack it so that its callback is hijacked to call config.macros.graph.saveDataAndOptions in the end. Here's a simplified version of what I'm doing:
var nonSaving_addNode = options.manipulation.addNode;
options.manipulation.addNode = function(data,callback) {
// hijack callback to add saving
arguments[1] = function() {
callback.apply(this,arguments); // preserve initial action
config.macros.graph.saveDataAndOptions(network); // add saving
};
nonSaving_addNode.apply(this,arguments);
}
The thing is, addNode is actually called when the add node button is clicked; though, I'm using a customized one to create a popup and apply changes once user is happy with the label they chose.
I am trying to catch an onlick event on a bubble in bubble chart. I want to log the label of clicked bubble into the console. I have written a function to do the job which actually looks like this
$("#myChart").click(function(evt) {
var activePoints = myBubbleChart.getElementAtEvent(evt);
console.log(activePoints.label);
});
Every time I click on a bubble this function logs "undefined" into console. I have even tried getBarsAtEvent and getSegmentsAtEvent none of them worked. What's wrong in my code? And can anybody please tell me how can I get the label value of bubble which I clicked?
Chart.js options have a built-in onClick property (see documentation).
It works like this :
options: {
onClick: function(e) {
var element = this.getElementAtEvent(e);
// If you click on at least 1 element ...
if (element.length > 0) {
// Logs it
console.log(element[0]);
// Here we get the data linked to the clicked bubble ...
var datasetLabel = this.config.data.datasets[element[0]._datasetIndex].label;
// data gives you `x`, `y` and `r` values
var data = this.config.data.datasets[element[0]._datasetIndex].data[element[0]._index];
}
}
}
Check this jsFiddle for a full example.
Getting the name of the clicked item, the current dataset, or the item in the current dataset is straightforward:
onClick: (e, i) => {
const bubbleSelected = i[0];
console.log(this.widget.data.bubblesData[bubbleSelected.datasetIndex].tooltipData[bubbleSelected.index]);
}
Parameter i contains an array of clicked elements which contains the following:
With these image data, knowing which dataset you have selected and which element of the dataset you have clicked, you can, from an array of data, obtain the data, names or whatever you want from the current dataset of the current position.
In my case I had in bubblesData a list of datasets (datasetIndex) and in each dataset an object called tooltipData with a list of data for each element of the dataset (index).
If you want to see how to also modify the tooltip to show it like this visit this link: Chart JS Show HTML in Tooltip
Documentation:
https://www.chartjs.org/docs/latest/configuration/interactions.html
https://stackoverflow.com/a/44160605/11770490
I have integrated dhtmlxGantt in a Laravel5 project and everything is working as expected. But I want to modify it to store charts for more than one project. For that I want to add extra field called "project_id" and load data through a filter.
I have tried modifying the Controller with the following code :
$connector->render_links(
GanttLink::where('user_id', '=', 1)->get(),
"id",
"source,target,type"
);
$connector->render_table(
GanttTask::where('user_id', '=', 1)->get(),
"id",
"start_date,duration,text,progress,parent"
);
This solution allowed me to load the chart from the data base in the way I wanted. But It does not save the changes back to the database. I went through the dhtmlxGantt documentations but did not get any solution for this.
I found these links in my research and might be helpful.
Link 1: Changing values before saving
Link 2: Filtering results based on a parameter
Please help me to modify my project in a way which allows to work (Load and Edit) on different charts.
Finally I found a solution. Firstly, you need to add project_id column to the database table, then add the column to connector configuration:
$connector->render_table(new GanttTask(), "id", "start_date,duration,text,progress,parent,project_id");
Then you have to do some modifications to the client-side code. Use something like,
var project_id = "<?php echo $project['id']; ?>";
in order to take the variable into the <script>..</script>
Then modify your code by adding these two client-side handlers:
gantt.attachEvent("onBeforeTaskDisplay", function (id, task) {
if (task.project_id == project_id) {
return true;
}
return false;
});
and
gantt.attachEvent("onBeforeTaskAdd", function (id, task) {
task.project_id = project_id;
});
First handler filters the results in the way you want before displaying the chart, and second handler attaches the project_id property before adding the task. Now you have a dhtmlxGatt which can display multiple projects.
drawBarChart = function (data) {
//few statements goes here which sets options which are being passed to chartDraw i.e. t.options.chart.options
gChart = new google.visualization.BarChart(chartingPlace);
//setTimeout(function () {
// t.options.chart.options.height = ((t.chart.size.height) - 40) + "px";
////console.log(JSON.stringify(t.options.chart.options));
//google.visualization.events.addListener(gChart, 'ready', function () {
// grab a few details before redirecting
google.visualization.events.addListener(gChart, 'select', function () {
var selectedItem = gChart.getSelection()[0];
console.log(gChart.getSelection());
if (selectedItem) {
var topping = data.getValue(selectedItem.row, 0);
alert('The user selected ' + topping);
}
// });
});
gChart.draw(data, t.options.chart.options);
}
My app having a number of charts displaying for different scenarios. My requirement is, click on a bar from google bar chart and open a new tab associated with the name of the bar. For this purpose, I tried using direct 'select' event on bar chart as follows:
google.visualization.events.addListener(gChart, 'select', function () {
var selectedItem = gChart.getSelection()[0];
console.log(gChart.getSelection());
if (selectedItem) {
var topping = data.getValue(selectedItem.row, 0);
alert('The user selected ' + topping);
}
});
But I could not get, this returned empty array for gChart.getSelection(), so I tried the code with 'ready' event mentioned in as first code above.
It works, but not output is not consistent. sometimes it gives empty array and sometimes with selected object.
I am still not able to find why it is showing this kind of behavior
More info: my application is having different tabs, showing number of bar,line,area,combo charts on it. getSelection() works well with line chart but not able to get the consistent output with bars.
Any help is appreciable.
Please do not mark it as duplicate, as I have gone through other similar questions but they does not answer my issue, I do not have that privilege so I could not comment in replies asking for more clarification.
Similar question here : google visualization-Click event on barchart isStacked: true
Please help!
Thank you in advance!
Updates :
I could not get any answer or any response from here.
This is really very disappointing.
Solution:
This is how i worked out the solution for this problem :
The getSelection could not work for me so i tried click event on bar text. Through the click event i could get the text on bar and i linked it to opn new tab.
If anyone need solution in code, please let me know.
Thank you.
Please go through below code snippet, I corrected or you can say organised the code in different way. If you need further explanation please let me know.
google.visualization.events.addListener(googleChartObj, 'select', function () {
var selectedBar = googleChartObj.getSelection();
////console.log(selectedBar);
data.getRowLabel(selectedBar[0].row);
/// for Bar charts, normally row-parameters are used
/// manipulate on 'data' which refers to data-table to get desired results
});