Set tooltip position on the last value on the graph - javascript

There are some way to set the position for the tooltip in c3js, because the tooltip is always at the right side of the vertical line, but when the cursor is on the last value then it changes position towards left side or state in the graph without leaving it.
I know that this is normal tooltip behavior on c3js but I want that the tooltip to keep its position on the right side for the last value
you can see the example on this link
var chart = c3.generate({
data: {
columns: [
['data1', 300, 350, 300, 0, 0, 0],
['data2', 130, 100, 140, 200, 150, 50]
],
types: {
data1: 'area',
data2: 'area-spline'
}
},
axis: {
y: {
padding: {bottom: 0},
min: 0
},
x: {
padding: {left: 0},
min: 0,
show: false
}
}
});
any ideas?

You can set the tooltip position using this code:
http://c3js.org/reference.html#tooltip-position
tooltip: {
position: function (data, width, height, element) {
var top = d3.mouse(element)[1] + 15;
return {top: top, left: parseInt(element.getAttribute('x')) + parseInt(element.getAttribute('width'))}
}
}
However how it works when the tooltip pokes out the side of the chart I don't know, it may just be cutoff. You could add a margin of 100px to the right if needed I suppose but that makes your chart smaller.

Related

C3.js - Adding Spacing between the X-axis and Legend in Bar Graphs

I have a C3.js bar graph and I am trying to add some spacing in between the x-axis and legend in order to avoid the following visual unpleasantry:
I have already tried to do the following and it has had no effect on the graph:
#stacked_bar_chart_container .c3-axis-x {
margin-bottom: 5px;
}
I have even tried to do the same thing with .c3-legend-item but with a margin-top: 5px; instead, but it has still had no effect.
I would also like to note that by removing #stacked_bar_chart_container (the div container that this graph is binded to) there was still no effect either.
You can adjust the space between the chart and bottom legend by using padding: {bottom: 20}, which will add additional 20px between chart and legend. If you place the legend on the right side, you can use padding: {right: 20}.
Because padding will make your chart smaller, you may want to adjust the height or width of your chart by using size: {height: 480} or size: {width: 640}, respectively.
I have created a fiddle example http://jsfiddle.net/6jztrbk7/
This is the example JavaScript code:
var chart = c3.generate({
data: {
columns: [
['data1', -30, 200, 200, 400, -150, 250],
['data2', 130, 100, -100, 200, -150, 50],
['data3', -230, 200, 200, -300, 250, 250],
type: 'bar',
groups: [
['data1', 'data2']
]
},
grid: {
y: {
lines: [{value:0}]
}
},
legend: {
position: 'bottom'
},
size: {
height: 300 //adjust chart height
},
padding: {
bottom: 20 //adjust chart padding bottom
}
});

c3 chart not displaying changes on axis

I am trying to display the following chart with the required options on x and y axis but changes on axis are not working. The chart is being displayed but Y axis has not the min, max attributes, position is not the one I passed... What is wrong?
<div id="chart2"></div>
<script>
var chart = c3.generate({
bindto: '#chart2',
data: {
url: "../static/CSV/Chart_data/grades_access.csv",
x:'AC_GRADE',
type: 'scatter'
},
axis: {
y: {
label: "Average grade",
position: "outer-middle",
padding: {top: 200, bottom: 0},
min:0,
max:10
},
x: {
label: "Access grade",
position: "outer-center",
padding: {top: 200, bottom: 0},
min:0,
max:10
}
},
size: {
height: 400,
width: 800
},
zoom: {
enabled: true
}
});
</script>
Well, actually a lot of wrongly defined params.
1. Label position should be defined like this
axis: {
x: {
label: {
text: 'Your X Axis',
position: 'outer-center'
}
}
}
2. Padding affects on min and max so you should set it to 0 if you want.
3. Padding for x axis should use left and right properties.
Maybe something else, just check the http://c3js.org/reference.html thoroughly.

How to add an image on top of the canvas in header using pdfmake?

I am using node to create a PDF. I am trying to make a header that looks similar to this:
The white part is the logo, and the background is blue-ish. So far I only have the background using canvas (actually a rectangle), but I can't seem to fit an image on top of it.
I tried to define the header like this:
header: { canvas: [
{ image: `PATH_TO_LOGO`,
width: 100, },
{
type: 'rect',
x: 0,
y: 0,
w: 850, // landscape
h: 120,
color: '#0067B9',
},
],
},
But the logo doesn't show. I looked at documentation, but haven't had much luck. Is this even the correct approach?
You need to add margin to your image. Try something like this:
header: [
{
canvas: [
{
type: 'rect',
x: 0,
y: 0,
w: 850, // landscape
h: 120,
color: '#0067B9'
}
]
},
{
image: `PATH_TO_LOGO`,
width: 100,
margin: [0, -120, 0, 0] // -120 is your rect height
},
]

Customized tooltip for C3JS

I have created a chart using C3.JS. It has bar graph with line graph like as shown below
The graph is working fine but I have a requirement that I need a line graph to be shown within the tooltip along with other data points.
The line graph is coming but the other data points are missing (x, data1, data2). In addition tooltip should come only on mouse click not mouse over also by default when the page loads the tooltip should appear for the last bar.
Current my tooltip shows only with the line graph like as shown below without the other data points(x, data1, data2)
But I expect my tooltip to appear like as shown below
My code is as given below
Can anyone please help me on this
Working JSFiddle
function generateGraph(tooltip, data1, data2) {
// if the data is same as before don't regenrate the graph - this avoids flicker
if (tooltip.data1 &&
(tooltip.data1.name === data1.name) && (tooltip.data1.value === data1.value) &&
(tooltip.data2.name === data2.name) && (tooltip.data2.value === data2.value))
return;
tooltip.data1 = data1;
tooltip.data2 = data2;
// remove the existing chart
if (tooltip.chart) {
tooltip.chart = tooltip.chart.destroy();
tooltip.selectAll('*').remove();
}
// create new chart
tooltip.chart = c3.generate({
bindto: tooltip,
padding: {
right: 15
},
size: {
width: 200,
height: 200
},
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250, 160],
['data2', 50, 20, 10, 40, 15, 25, 34]
]
},
tooltip: {
show: false
}
});
// creating a chart on an element sets its position attribute to relative
// reset it to absolute (the tooltip was absolute originally) for proper positioning
tooltip.style('position', 'absolute');
tooltip.style('background-color', 'white');
}
var chart = c3.generate({
data: {
columns: [
['x', 1000, 200, 150, 300, 200],
['data1', 1000, 200, 150, 300, 200],
['data2', 400, 500, 250, 700, 300], ],
axes: {
'data1': 'y2'
},
type: 'bar',
types: {
'data1': 'line'
}
},
tooltip: {
contents: function (d, defaultTitleFormat, defaultValueFormat, color) {
// this creates a chart inside the tooltips
var content = generateGraph(this.tooltip, d[0], d[1])
// we don't return anything - see .html function below
}
}
});
// MONKEY PATCHING (MAY break if library updates change the code that sets tooltip content)
// we override the html function for the tooltip to not do anything (since we've already created the tooltip content inside it)
chart.internal.tooltip.html = function () {
// this needs to return the tooltip - it's used for positioning the tooltip
return chart.internal.tooltip;
}
Live Demo:
http://jsfiddle.net/blackmiaool/y7Lhej4m/
Instead of overriding the .html function of tooltip, I use contents and css to customize the tooltip.
js:
contents: function (d, defaultTitleFormat, defaultValueFormat, color) {
generateGraph(this.tooltip, d[0], d[1]);
var tip = this.tooltip[0][0].querySelector(".c3-tooltip");//find previous tooltip
if (tip) {
tip.parentElement.removeChild(tip);//remove it
}
return this.getTooltipContent.apply(this, arguments) + this.tooltip.html();//concat default tooltip and customized one
}
css:
.c3-tooltip-container {
max-height: none !important;
}
.c3-tooltip {
box-shadow: none;
width: 100%;
}
.c3-tooltip tr {
border-left: none !important;
border-right: none !important;
}
.c3-tooltip td.name {
border-left: none !important;
}
.c3-tooltip tr:first-child {
display: none;
}
.c3-tooltip-container .c3-chart-line {
opacity: 1 !important;
}

Position an inset legend at the top-center

According to the C3 documentation, legend.inset.postition only supports top-left, top-right, bottom-left and bottom-right positions. I would like to have my legend positioned at the top-center.
Here is the JS that creates the plot:
var chart = c3.generate({
data: {
columns: [
['data1', 100, 200, 50, 300, 200, 50, 250, 100, 200, 400, 50],
['data2', 400, 500, 250, null, 300, 50, 200, 450, 300, 300, 100]
],
},
legend: {
position: 'inset',
inset: {
anchor: 'top-left', // how do I implement 'top-center'?
x: 40,
y: 2,
step: 1
}
}
});
I have attempted to re-position the element after the chart has been rendered via figuring out its current position. However, none of the SVG elements appear to have attributes that enable this kind of introspection:
var legend = d3.select(".c3-legend-background");
console.log("style[width]: " + legend.style("width")); // style[width]: auto
console.log("attr[x]: " + legend.attr("x")); // attr[x]: null
console.log("attr[y]: " + legend.attr("y")); // attr[y]: null
Wouldn't you just set the x value of the inset object to the correct value to get it to center across the top?
This would depend on your wide your chart if and how wide your legend is. So the calculation would be (ChartWidth - LegendWidth) / 2.
The legend object is then something like:
legend: {
position:'inset',
inset: {
anchor: 'top-left',
x: 200 // put the result of your calculation here
}
}
Here's a rough example: http://jsfiddle.net/jrdsxvys/11/

Categories