If for example I have a chart with three series in it and the tooltips are set to shared, I would like more control over formatting the tooltips. Currently I use the formatter: somefunction() and create my own html to use in the tooltip that is displayed. Now this works very nicely, but now I would like to be able to know when the formattor function fires which series I am over so that out of the three series in the tooltip I can format the text I show accordingly.
Shared Tooltip:
Header Label
Series 1
Series 2 (If I am hovering over this item I want to bold it in the formatter function)
Series 3
There isn't such info in shared tooltip - simply you can hover empty space on a chart (none of series) and it will be displayed, see: http://jsfiddle.net/LBsL5/
Solution which may work for you is to disable shared tooltip and get values from other series using:
var xIndex = this.series.xData.indexOf(this.x),
allSeries = this.series.chart.series;
Now loop over all series and use allSeries[index].yData[xIndex] to get value from each series.
Of course, if this.series.index (or this.series.options.index ) is the same index above, then generate bold text.
Thanks for the direction on this. I am posting the full code here to implement this. Hopefully it will help others.
// Header for tooltip.
// This row consists of bold text, with the text being the xAxis Label
// that the Series falls in followed by the Chart Title.
var toolTip = '<b>' + this.x + ' ' + chartTitle + '</b><br/>';
// Get the current index in the Series you are hovering over.
var xIndex = this.series.xData.indexOf(this.point.x);
// Get all the Series represented in the Chart.
var allSeries = this.series.chart.series;
// Loop over each Series.
for (var index = 0; index < allSeries.length; index++) {
// Get the value from each Series.
var yDataValue = allSeries[index].yData[xIndex];
// Check if this is the same as index and if it is then you are
// hovering over the point that needs the text in the formatted tooltip in bold for that Series.
if (this.series.index === index || this.series.options.index === index) {
//
// Generate Bold Text here.
//
toolTip = toolTip + '<b>' + allSeries[index].name + ': ' + yDataValue + '</b>';
}
else {
toolTip = toolTip + allSeries[index].name + ': ' + yDataValue;
}
}
Related
In my vueJS application I'm using vis.js time line to show some data,
I have integrated the vis timeline with some randomly generated data.
Following is my code for that,
created() {
var now = moment().minutes(0).seconds(0).milliseconds(0);
var groupCount = 3;
var itemCount = 20;
// create a data set with groups
var names = ['John', 'Alston', 'Lee', 'Grant'];
for (var g = 0; g < groupCount; g++) {
this.groups.push({
id: g,
content: names[g]
});
}
// create a dataset with items
for (var i = 0; i < itemCount; i++) {
var start = now.clone().add(Math.random() * 200, 'hours');
var group = Math.floor(Math.random() * groupCount);
this.items.push({
id: i,
group: group,
content: 'item ' + i +
' <span class="" style="color:green;">(' + names[group] + ')</span>',
start: start,
type: 'box',
className: 'green', //green or yellow
title:'Testing tool tip index' + i
});
}
},
Then I used
<timeline ref="timeline"
:items="items"
:groups="groups"
:options="options"
>
</timeline>
to display the time line in my vue component.
This outputs me something like follows,
Please kindly note I have added some custom css changes to change the initial look and feel of the time line.
Since this is my first experience working with vis, I want to know, how can I change the colors of those bars...
How can I assign random color to those bars instead of all green....
I found the best way to do this was through the item's className property. So as an example, you might assign 'colour_1', 'colour_2' 'colour_3' randomly inside your 'create a dataset with items' loop.
Then provide a matching stylesheet that looks like
.colour_1 {background-color:#7fc97f; border-color:#7fc97f}
.colour_2 {background-color:#beaed4; border-color:#beaed4}
.colour_3 {background-color:#fdc086; border-color:#fdc086}
This mechanism can be extended further with additional classes applied to the container to 'switch in or out' different groups of colours depending on what you want to see.
Here's a screenshot of my (non-random) colourised timeline using this technique.
You /could/ alternatively use the 'template' function override to achieve a similar goal, but I found that the call to 'redraw' was a lot slower than just switching between colour palettes in CSS.
I want to color the bars based on the conditional check.
I want to show the bar color based on the conditional check as follows:
I am displaying the 'expertise level' for the certain time period.
When the expertise column starts from 'Begining' word, they have to show red color for that timeline bar.
When the expertise column starts from 'Advanced' word, they have to show brown color for that timeline bar.
When the expertise column starts from 'Intermediate' word, they have to submit Yellow color for that timeline bar.
Please find the complete demo : https://plnkr.co/edit/XrEgUo9oDJvxAXH03KMA?p=preview
Currently i'm using the below options:
function drawChart() {
var options = {
colors:['red','brown','yellow'],
};
chart.draw(dataTable,options, {
height: (dataTable.getNumberOfRows() * rowHeight) + rowHeight
});
}
Any inputs on how to give timeline chart each milestone with different colors based on the input string .
Whatever string your using to detect what level you are at.
Use:
var totalWords = "foo love bar very much.";
var firstWord =totalWords.replace(/ .*/,'');
To get the first word (intermediate, advanced, etc)
Then use a and if statement to output the color you want
if (firstword == "advanced) {
color = "brown";
} else if(firstword == "intermediate"){
color = "yellow";
}
Firstly define your rows before adding them to the table so that you can iterate over them to construct an array with the corresponding colors prior or rendering the chart.
Then call map on the data array passing this function.
function getRowColor(row) {
let firstWord = row[1].trim().split(' ')[0];
if (firstWord === 'Beginning') return 'red';
if (firstWord === 'Advanced') return 'brown';
if (firstWord === 'Intermediate') return 'yellow';
}
const colors = rows.map(getRowColor);
I've forked your plunker here
I have a d3 area chart with a tooltip that displays the same text in two different divs. The first div, .tooltip.headline.record, displays the selected value in bold. Another div class, .record-label, displays the all of the values at a given point on the x-axis — for both the selected and non-selected paths. Here's a Plunker of the problem.
To illustrate, it currently looks like this:
I've been trying to achieve a result like this:
... or like this:
I've tried the following methods of hiding or removing the duplicative .record-label div, without success — and without error messages to assist in further diagnosis.
function getRecordContent(obj, pos) {
if ( $(".tooltip-headline-record").text() == $(".record-label").text() ) {
$(".record-label").hide();
//$(".record-label").remove();
//console.log("same");
}
return '<li><div class="record-label">' + obj.state + " " + obj.record.toLowerCase() + " " + numFormat(obj.values[pos].y) + '</div></li>'
}
Here, again, is a Plunker that demonstrates the problem I'm trying to solve (see, specifically, the code beginning at line 480:
http://plnkr.co/edit/NfMeTpXzXGTxgNFKPFJe?p=preview
Is this what you're looking for?
Plunkr
Relevant code changes:
The whole dataset was being passed to the getRecordContent function. So I changed that: when hovered over "admissions", pass "transfers" and "codependents". (line: 435)
var filtered_dataset = dataset.filter(function(row){return row.record !== d.record; });
for (var i = 0; i < filtered_dataset.length; i++) {
content += getRecordContent(filtered_dataset[i], idx);
}
Seems like you need to specify the state name as well along with the record. (line 480)
return '<li><span class="record-label">' + obj.state + ' ' + obj.record.toLowerCase() + '</span><span class="record-value">' + numFormat(obj.values[pos].y) + '</span></li>'
Edit:
Changes made for the tooltip to adapt to the main chart as well:
var filtered_dataset = dataset.filter(function(row){return row.record !== d.record && row.state === d.state; });
Changed z-index for the tooltip in main.css (try removing it and hovering close to the jquery slider)
z-index: 2;
Hope this helps. :)
Hello I'm working on the fusion table layer mouseover tool-tip in fixed position. Idea is to display Country flag or any image, stored in fusion table and some other information also stored in fusion table.
And my problem is with flag, link to the flag is displaying but I can't display any images properly.
http://jsbin.com/uHUQERin/1/
Any ideas ?
To display an image replace this part of the code:
var row = fEvent.row;
myHtml = 'mouseover:<br/>';
for (var x in row) {
if (row.hasOwnProperty(x)) {
myHtml += '<b>' + x + "</b>:" + row[x].value + "<br/>";
}
}
document.getElementById('info').innerHTML = myHtml;
With that:
var row = fEvent.row;
myHtml = '<img src="'+row.flag.value+'"/>';
document.getElementById('info').innerHTML = myHtml;
But the basic issue is that what you see on the map is the FusionTip, not the #info-div(it's placed below the map).
Disable the display of the FusionTips and place the #info-div at the desired position.
Fixed version: http://jsbin.com/EpiTODa/1
Of course it would be possible to use the FusionTip to display the flag, but this would require to modify the library, so I wouldn't suggest it.
Ok I have created a JavaScript page where the user can add text, they can set the colour, bold italics, as well as size and font. Size and drop options are selected through drop down boxes.
It looks a bit messy atm, as I am not worried about the looks, just the functionality.
When they add an element which appears in the widget, they can drag the element into position onto an image I have created which is displayed on the screen. Whenever the user is happy with the position of the text, they click save which generates the coordinates and updates the table X and Y coordinates field, At this point, a new row is generated and they can repeat the process of adding a new element. Whenever they are happy, they click save and it will send to a database to store it to be retrieved later.
My problem is everytime I add a new text field, it pushes the element down by a certain amount.
I rectified this by adding a decrementing variable which takes the elementCount (which autoincrements every time they add a new label element) and multiply it by a set amount to decrement by
decr -= (elementCount* 16);
This works fine for the medium text size, however when you start adding different text sizes and font combinations, it will change how much the element gets pushed down so it gets worse and worse every other element you add.
The new element is added like this
elementCount++;
var Text = textArray[textArray.length-1];
var Font = fontArray[fontArray.length-1];
var Color = colorArray[colorArray.length-1];
var Bold = boldArray[boldArray.length-1];
var Size = sizeArray[sizeArray.length-1];
var Italics = italicsArray[italicsArray.length-1];
var X = xCordArray[xCordArray.length-1];
var Y = yCordArray[yCordArray.length-1];
var newdiv = document.createElement('div');
newdiv.innerHTML = "<span><font color='" + Color + "' size = '" + Size + "' face='" + Font + "'><label class = 'drag2' id = 'text" + firstCount + "'> " + Text + "</label></font></span>";
document.getElementById(divName).appendChild(newdiv);
var decr= 32;
decr-= (elementCount* 16);
Y = parseInt(Y) + test;
X = parseInt(X) + 24;
document.getElementById("text" + elementCount).style.left = X + "px";
document.getElementById("text" + elementCount).style.top = Y + "px";
The drag and drop JavaScript code was based on this tutorial
http://luke.breuer.com/tutorial/javascript-drag-and-drop-tutorial.aspx
Is there any way to make it so when you dynamically add a new element , it doesn't automatically push it down the screen by a bit each new element you add. I have tried soo many different options to fix this over the past few days and have had no luck.
Thanks in advance for any help
Edit CSS for the text element
.text1{
position: relative;
left: 0px;
top: 0px;
}
I changed to absolute positioning and placed it inside a relative positioned container and works perfectly now!!