c3.js - How to manually trigger the hover of a donut arc? - d3.js

I'm using c3.js and have a donut chart that has custom text inside the donut as you hover over each category. I got that all working great.
I have some custom elements relating to the chart but are detached from the chart completely... if user hovers on those custom elements, i need to trigger a hover over a specific donut arc so the "onmouseover" triggers and the middle of donut gets updated as well.
var chart = c3.generate({
data: {
columns: [
['data1', 30],
['data2', 120],
],
type: 'donut',
onmouseover: (d) => {
// does stuff to middle of donut not included here
console.log("onmouseover", d);
}
},
donut: {
title: "custom data here"
},
});
// i want to highlight and run onmouseover for specific chart arc
$('.custom-bars .bar').hover(
function() {
var id = $(this).data('id');
console.log('trigger ' + id + ' arc hover state');
}, function() {
// remove hover
}
);
.custom-bars .bar {
background: #ccc;
margin-bottom: 10px;
padding: 10px;
display: inline-block;
cursor: pointer;
}
<div class="custom-bars">
<div class="bar bar1" data-id="data1">data1 related stuff</div>
<div class="bar bar2" data-id="data2">data2 related stuff</div>
</div>
<div id="chart" style="width:100%; height: 350px;"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/c3/0.3.0/c3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.12/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
so when someone hovers over .bar1 I want to manually trigger data1 column on the chart so it highlights that arc and runs the "onmouseover" callback which updates the middle of the donut and everything else I need to do. The handling of generating chart and custom-bars will be in separate class methods.

https://jsfiddle.net/pelluche/2adtw71o/30/
Thanks to Ruben I think I figured out how to manually trigger a donut arc. I updated my fiddle. chart.focus() trigger the highlight but it doesn't run the onmouseover, so to grab it's values you can use chart.data.shown(). If someone knows a way to trigger the onmouseover of that arc please let me know.
$('.custom-bars .bar').hover(
function() {
var id = $(this).data('id');
var arcData = chart.data.shown(id);
chart.focus(id);
console.log(arcData);
}, function() {
chart.revert();
}
);

Related

D3: passing object in style method is not working

I am using D3 for the exercise. However, I am having trouble passing an object to the .style() method:
var myStyles = [
'#268BD2',
'#BD3613',
'#D11C24',
'#C61C6F',
'#595AB7',
'#2176C7'
];
This below piece of code is working
d3.selectAll('.item')
.data(myStyles)
.style('background',function(d){return d});
But none of the below two code pieces are working
d3.selectAll('.item')
.data(myStyles)
.style({'background':function(d){return d}});
d3.selectAll('.item')
.data(myStyles)
.style({'color':'white','background':function(d){return d}});
Please explain what is wrong here.
You can apply objects in styles and attributes by using d3-selection-multi.
First, you have to reference the mini library:
<script src="https://d3js.org/d3-selection-multi.v0.4.min.js"></script>
Then, you have to use styles, not style:
.styles({'color':'white','background':function(d){return d}});
You can see the code working in this fiddle, in which I'm using an object to set the styles: https://jsfiddle.net/gerardofurtado/o54rtrqc/1/
For attributes, use attrs instead of attr.
Here is the API.
I'm also working through the Lynda.com course. Here's an example of the "Binding data to the DOM" exercise using D3 version 4:
JSFiddle
HTML:
<!--
Added these two scripts:
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-selection-multi.v0.4.min.js"></script>
-->
<div class="container">
<h2>D3 Graphic</h2>
<section id="chart">
<div class="item">Darth Vader</div>
<div class="item">Luke Skywalker</div>
<div class="item">Han Solo</div>
<div class="item">Obi-Wan Kenobi</div>
<div class="item">Chewbacca</div>
<div class="item">Boba Fett</div>
</section>
</div>
JS:
var myStyles = [{
width: 200,
color: '#A57706'
}, {
width: 300,
color: '#BD3613'
}, {
width: 150,
color: '#D11C24'
}, {
width: 350,
color: '#C61C6F'
}, {
width: 400,
color: '#595AB7'
}, {
width: 250,
color: '#2176C7'
}];
d3.selectAll('.item')
.data(myStyles)
.styles({
'color': 'white',
'background': function(d) {
return d.color;
},
width: function(d) {
return d.width + 'px';
}
})

Kendo Display Multiple Bar Charts on Web Page

I'm using Kendo UI and trying to display multiple charts on a single web page. Everything works until I try to add a second bar chart. One of the charts does not display and just shows a generic chart image (it looks like it is not finding the data but if I reorder they reverse what is happening). I can display multiple line charts. Any ideas about what might be happening?
Below is my html for the two charts without the SVG info:
<div kendo-chart="" k-options="vm.barChartOptions" ng-show="this.dataItem.visible" class="move k-block ng-scope k-chart" id="costPerPound" style="float: left; margin: 5px 0px; position: relative;" data-uid="b543ff9a-ee57-4ce7-a39d-8f69a0505a2b" role="option" aria-selected="false" data-role="chart"></div>
<div kendo-chart="" k-options="vm.barChartOptions" ng-show="this.dataItem.visible" class="move k-block ng-scope k-chart" id="numShipments" style="float: left; margin: 5px 0px; position: relative;" data-uid="97094bf1-4366-4974-b92f-edf36d1980f4" role="option" aria-selected="false" data-role="chart"></div>
Here are is the k-options info. As you can see I am setting most of my information at render.
vm.barChartOptions = {
dataSource: vm.chartData_datasource,
series: [
{
}
],
valueAxis: {
line: {
visible: false
},
labels: {
rotation: "auto"
}
},
tooltip: {
visible: true,
template: "#= series.name #: #= value #"
},
render: function (e) {
var chart = e.sender;
var chartData = vm.findChartData(e);
if (chartData != null) {
chartData.categoryAxisField = vm.firstToLower(chartData.categoryAxisField);
chart.options.title.text = chartData.title;
chart.options.name = chartData.htmlID;
chart.options.categoryAxis.field = chartData.categoryAxisField;
chart.options.categoryAxis.labels.format = chartData.categoryAxisLabel;
chart.options.legend.position = chartData.legendPosition;
chart.options.seriesDefaults.type = chartData.chartType;
for (var i = 0; i < chart.options.series.length; i++) {
chart.options.series[i].type = chartData.chartType;
chart.options.series[i].field = vm.firstToLower(chartData.dataField);
}
}
}
}
I had same issue. It can be resolved by just providing different name
to each chart.

Kendo UI Ajax Request

I'm using Kendo UI Grid with an action link into a client-template column. This action link call an data edit view. See example:
c.Bound(p => p.sID).ClientTemplate(#Html.ImageActionLink(Url.Content("~/Content/images/edit3.png"), "Edit", "Edit", new { id = "#= sID #" }, new { title = "Edit", id = "Edit", border = 0, hspace = 2 }).ToString()
).Title("").Width(70).Filterable(false).Groupable(false).Sortable(false);
My question is how can I configure the grid in order to show an ajax loader when the action link is clicked, until the edit view is rendered?
you can create relative div and insert there your grid and loader wrapper:
<div class="grid-wrapper">
<div class="loading-wrapper">
<div class='k-loading-image loading'></div>
<!-- k-loading-image is standart kendo class that show loading image -->
</div>
#(Html.Kendo().Grid()....)
</div>
css:
.grid-wrapper {
position: relative;
}
.loading-wrapper {
display: none;
position: absolute;
width: 100%;
height: 100%;
z-index: 1000;
}
.loading {
position: absolute;
height: 4em;
top: 50%;
}
add to imageActionLink in htmlAttributes object class named "edit" (for example), and write click event handler:
$(document).on('click', '.edit', function (e) {
$('.loading-wrapper').show();
$.ajax({
// ajax opts
success: function(response) {
// insert your edit view received by ajax in right place
$('.loading-wrapper').hide();
}
})
});
you can do this like :
c.Bound(p => p.sID).Template(#Edit).Title("Edit").Encoded(false);
//encoded false = Html.Raw

Add Legend to jVectorMap

I am updating our application to use jVectorMap instead of a Flash. Some of the maps need the countries to be colored differently. This is pretty simple to create.
<div id="world-map-color" style="width: 900px; height: 600px;"></div>
<script>
var myData = {
"AF": 36.63,
"RU": 11.58,
"US": 158.97
};
$('#world-map-color').vectorMap({
backgroundColor: "#FFFFFF",
regionStyle: {
initial: { fill: "#7C96A1" },
hover: { fill: "#A0D1DC" }
},
series: {
regions: [{
values: myData,
scale: ['#B0ADF7', '#0D0885'],
normalizeFunction: 'polynomial'
}]
}
});
</script>
The resulting map:
However, I'd like to add some kind of legend/key to say what the scale of the colors are. Something like the following:
Additionally, that example legend (from Flash) allowed the user to change the scaling for the colors using those arrows on the top. So it'd be nice if that was possible as well.
Does anyone know if any parts of these are possible?
The most basic thing is necessary to achieve is the generation of the colorful scale. For that see the similar question I have answered recently.

Making the jqPlot area smaller

Hi I have got a pie chart which is generated using jqPlot. But the jqPlot area is covering the whole width of the page. I want to show that only at the left half of the page. Can any on please provide me a little help to do this.
My code is given below-
var plot2 = jQuery.jqplot ('month_record', [data],
{
title: "Records saved per month in the previous year",
seriesDefaults: {
// Make this a pie chart.
renderer: jQuery.jqplot.PieRenderer,
rendererOptions: {
// Put data labels on the pie slices.
showDataLabels: true,
startAngle:-90,
dataLabels: monthRecord,
dataLabelFormatString:'%d',
}
},
legend: { show: true, location: 'e' }
}
);
jqPlot uses the height/width of the container <div> to set the plot dimensions.
<div id="chart" style="width: 400px; height: 260px;" class="jqplot-target">
<!-- plot will render here with the above dimensions -->
</div>

Resources