How do I use callbacks on NVD3 Charts - nvd3.js

I have been using NVD3 but have decided to add some on-click events. I found an example using a horizontal bar chart.
vm.qcoptions = {
chart: {
type: 'multiBarHorizontalChart',
//type: 'discreteBarChart',
height: 450,
margin: {
top: 20,
right: 20,
bottom: 50,
left: 55
},
x: function (d) { return d.label; },
y: function (d) { return d.value + (1e-10); },
showValues: true,
valueFormat: function (d) {
return d3.format(',.4f')(d);
},
duration: 500,
xAxis: {
axisLabel: ''
},
yAxis: {
axisLabel: '',
axisLabelDistance: -10
},
callback: function (chart) {
chart.multibar.dispatch.on('elementClick', function (e) {
console.log('elementClick in callback', e.data);
});
}
}
};
The example above works when using the multiBarHorizonatChart, but when I switch to the discreteBarChart it throws this error "Cannot read property 'dispatch' of undefined" at this line
chart.multibar.dispatch.on('elementClick', function (e) {
I have tried to inspect chart and determine what I should in in place of chart.multibar for the bar chart but I am stumped. Can anyone shed any light on this?

You are referring now to the discrete bar chart. You will need to reflect that in the callback function as follows:
chart.discretebar.dispatch.on('elementClick', function (e) {
console.log('elementClick in callback', e.data);
});
I suggest that you always refer to this page with the extended radio button selected in order to see the appropriate property names.

Related

How to add CLICK events on AMCHARTS 5 labels (x and y axis)?

I am trying to add basic interactivity to my AMCHARTS 5 labels. Take this chart as an example:
I need to be able to click on the names at the left of the chart. That is actually yAxis because I use an inverted chart.
In the function that creates the series, I placed this code:
series.columns.template.events.once("click", function(ev) {
console.log("Clicked on a column", ev.target);
});
And it makes my bars to be clickable. I don't know how to refer to the labels on the left.
Labels as interactive elements in amCharts 5 are tricky. Basically, it's super hard to determine hover/click over just text because it's impossible to completely eradicate antialising, and the actual colored area is super tiny.
Therefore, if we need tooltip to be interactive - have a hover tooltip or handle click events - we need to add a background to it.
The background does not necessarily have to be visible: we can just set its fillOpacity: 0 to make it completely transparent.
Source: Labels – amCharts 5 Documentation
After the declaration and initialization of your yAxis, you can put this piece of code:
yAxis.get("renderer").labels.template.setup = target => {
target.setAll({
cursorOverStyle: "pointer",
background: am5.Rectangle.new(root, {
fill: am5.color(0x000000),
fillOpacity: 0
})
});
};
yAxis.get("renderer").labels.template.events.on("click", e => {
console.log(e.target.dataItem.dataContext.category);
});
Full example:
am5.ready(() => {
let root = am5.Root.new("chartdiv");
let chart = root.container.children.push(am5xy.XYChart.new(root, {}));
let data = [{
category: "Category 1",
value: 10
}, {
category: "Category 2",
value: 20
}, {
category: "Category 3",
value: 15
}];
let yAxis = chart.yAxes.push(am5xy.CategoryAxis.new(root, {
categoryField: "category",
renderer: am5xy.AxisRendererY.new(root, {
inversed: true,
cellStartLocation: 0.1,
cellEndLocation: 0.9
})
}));
yAxis.data.setAll(data);
yAxis.get("renderer").labels.template.setup = target => {
target.setAll({
cursorOverStyle: "pointer",
background: am5.Rectangle.new(root, {
fill: am5.color(0x000000),
fillOpacity: 0
})
});
};
yAxis.get("renderer").labels.template.events.on("click", e => {
console.log(e.target.dataItem.dataContext.category);
});
let xAxis = chart.xAxes.push(am5xy.ValueAxis.new(root, {
min: 0,
renderer: am5xy.AxisRendererX.new(root, {})
}));
let series = chart.series.push(am5xy.ColumnSeries.new(root, {
name: "Series",
xAxis: xAxis,
yAxis: yAxis,
valueXField: "value",
categoryYField: "category"
}));
series.data.setAll(data);
});
#chartdiv {
width: 100%;
height: 350px;
}
<script src="https://cdn.amcharts.com/lib/5/index.js"></script>
<script src="https://cdn.amcharts.com/lib/5/xy.js"></script>
<div id="chartdiv"></div>

console error when changing line color in a HighCharts scatterplot

I've adopted this solution to change the line color when hovering a series in a HighCharts scatterplot (JSFiddle demo here):
$(function () {
$('#container').highcharts({
chart: {
type: 'scatter',
},
plotOptions: {
scatter: {
lineWidth:1,
marker: {
radius: 1,
symbol:'circle',
fillColor: '#800000',
states: {
hover: {
enabled: true,
radius:0,
radiusPlus:2,
lineColor: '#ff0000',
fillColor: '#ff0000'
}
}
},
events: {
mouseOver: function () {
this.chart.series[this.index].update({
color: 'red'
});
},
mouseOut: function () {
this.chart.series[this.index].update({
color: "#b0b0b0"
});
}
}
}
},
series: [{
name: 'A',
color: "#b0b0b0",
data: [[38,42],[39,39],[35,45],[35,54],{x:36,y:35,marker:{radius:8,symbol:'circle'}}
]
}, {
name: 'B',
color: "#b0b0b0",
data: [[46,56],[47,67],[48,69],[50,55],{x:52,y:57,marker:{radius:8,symbol:'circle'}}
]
}]
});
});
The script works but running the web console I see that every hovering of a series causes a TypeError: g.firePointEvent is not a function error.
In another one of my scripts the error is TypeError: hoverPoint.firePointEvent is not a function.
Is this a bug of HighCharts or is it possible to avoid it?
The issue is caused by the update which is called before your action. As a result you try to refer to updated point, before end of it. The solution is use attr() method and change SVG color on path.
events: {
mouseOver: function() {
this.chart.series[this.index].graph.attr({
stroke: 'red'
});
},
mouseOut: function() {
this.chart.series[this.index].graph.attr({
stroke: '#b0b0b0'
});
}
}
Demo:
http://jsfiddle.net/53ob1pu2.

nvd3 angular-nvd3 d3 Displaying chart legend vertically

I'm creating a pie chart using nvd3 and angular-nvd3. I've got my legend displayed but it's in a row across the top.
I'd like to display it in a column down the left side.
I found http://embed.plnkr.co/TJqjjkHaD2S0VjsGmN3c/preview but when I use the options found in the .js file then all that does is change the look of the legend, not the placement.
The css file is empty and there doesn't seem to be inline css in the html. So I'm unsure how they placed the position of the legend on the right in a column.
I do see legendPosition: 'right' but when I use legendPosition: 'left' then the entire pie chart disappears.
So at the least how do I display in a column, and it would be great if I could change it to the left.
Options object:
$scope.patientsChart = {
chart: {
type: 'pieChart',
height: 500,
x: function (d) {
var PatientStatuses = ["Unknown", "Green- Healthy", "Yellow - Fair", "Red - Unhealthy"];
return PatientStatuses[d.Key -1];
},
y: function (d) { return d.Value.length; },
showLabels: true,
duration: 500,
labelThreshold: 0.01,
labelSunbeamLayout: true,
showLegend: false,
legend: {
margin: {
top: 5,
right: 35,
bottom: 5,
left: 0
}
},
pie: {
dispatch: {
//elementClick: function (e) { console.log(e) }
}
},
color: function (d) {
var colors = ['#4066b9', '#009446', '#eba323', '#ee2726'];
return colors[d.Key - 1];
}
}
};
Directive for angular-nvd3:
<nvd3 options="FEV1Chart" data="patients"></nvd3>
If you want to rotateLabels in xAxis just add "rotateLabels: -45"
For example,
xAxis: {
axisLabel: 'Hours',
axisLabelDistance: 20,
showMaxMin: false,
rotateLabels: -45
},

How to get the datasource information from Kendo UI dragend event?

This is the code for the line chart which has drag function to highlight some data. I would like to get the datasource information in the dragEnd event,currently I am just getting screenX and screenY values.
function createChart(data) {
$("#TimeSeriesPlot").kendoChart({
title: {
text: series_name.toUpperCase()
},
dataSource :{
data:data.timeseries,
},
series: [{
type: "line",
field:"v",
categoryField:"ts",
}],
valueAxis: {
labels: {
format: "{0}"
},title:{
text: "value"
},
line: {
visible: false
},
},
categoryAxis: {
labels: {
type: "date",
},
tooltip: {
visible: true,
// shared:true,
template: "${category} - ${value}"
},
plotAreaClick: onPlotAreaClick,
seriesClick:onSeriesClick ,
dragStart:onDragStart ,
drag:onDrag,
dragEnd:onDragEnd
});
}
}
function onSeriesHover(e) {
console.log(kendo.format("Series hover :: {0} ({1}): {2}",
e.series.name, e.category, e.value));
}
function onSeriesClick(e){
// console.log(selected_anamolies);
// console.log(e.category);
selected_anamolies.push("ts",e.category);
selected_anamolies.push("v",e.value);
}
function onDragStart(e){
// console.log("dragstart"+e.axisRanges.ts);
// console.log("dragstart"+e.sender._highlight._points[0].value);
// console.log("dragstart"+e.sender._highlight._points[0].category);
}
function onDrag(e){
var Rect = kendo.geometry.Rect;
var draw = kendo.drawing;
prevloc=e.originalEvent.x.startLocation;
currentloc=e.originalEvent.x.location;
var rect=new Rect([prevloc,50],[currentloc-prevloc,150]);
var path = draw.Path.fromRect(rect,{ stroke: null,fill:{color:"#d3f1fb",opacity:0.2}});
var chart = e.sender;
// var surface = draw.Surface.create($("#surface"));
chart.surface.draw(path);
//
}
function onDragEnd(e){
console.log(dragEnd)
}

Jq-Plot x-Axis Spacing

I am having an issue using a line chart getting the calculated labels in the x-axis to space properly. If I want to have 5 data points with a few missing (e.g. [1,50.1],[2,49.2],[5,20.4],[6,17],[7,23.3]), the x-axis will show 1 then 2 then a space where 3 and 4 should have been then 5, 6, and 7. What I would like is to have the 5th data point beside the 2nd data point (in the position where the 3rd data point would ideally be). Basically I am trying to hide a data point yet keep the x-axis value in the grid.
Any assistance is much appreciated.
Try this:
<script type="text/javascript">
$(document).ready(function () {
var plot2 = $.jqplot('chart2', [[[1,50],[2,49],[5,20],[6,17],[7,23]]], {
title: 'Plot',
axesDefaults: {
labelRenderer: $.jqplot.CanvasAxisLabelRenderer
},
axes: {
xaxis: {
label: "X Axis",
pad: 0,
ticks:[1,2,5,6,7] //you can create this dynamically
},
yaxis: {
label: "Y Axis"
}
}
});
});
UPDATE:
<script type="text/javascript">
$(document).ready(function () {
var producciones = [];
for (var i = 0; i < 2000; i++) { producciones.push(new Number(i),new Number(i)) }
var plot2 = $.jqplot('chart2', [producciones], {
title: 'Plot',
axesDefaults: {
labelRenderer: $.jqplot.CanvasAxisLabelRenderer
},
axes: {
xaxis: {
label: "X Axis",
pad: 0,
numberTicks: 100
},
yaxis: {
label: "Y Axis"
}
}
});
});

Resources