TopoJSON in Leaflet, via Omnivore: reading properties - javascript

While following along a tutorial on choropleth maps in Leaflet I realized that a Shapefile > GeoJSON conversion generated a very large file. TopoJSON proved a better alternative, except for being unable to access the properties for each geometry. I merged data from https://github.com/centraldedados/violencia-domestica into a TopoJSON file converted from a Shapefile, structured like so:
{
"transform": {
"scale": [
0.0025081552497290688,
0.0012125352320998587
],
"translate": [
-31.26818656921381,
30.03017616271984
]
},
"objects": {"PRT_adm1": {
"geometries": [
{
"type": "Polygon",
"arcs": [[
0,
1,
2,
3,
4
]],
"properties": {
"ENGTYPE_1": "District",
"ISO": "PRT",
"NL_NAME_1": null,
"HASC_1": "PT.EV",
"ID_0": 182,
"NAME_0": "Portugal",
"TYPE_1": "Distrito",
"ID_1": 1,
"NAME_1": "Évora",
"CCN_1": 0,
"CCA_1": null,
"dgai_violencia_domestica_2008_2014": {
"Valores": [
{
"Ano": "2009",
"Entidade": [
{"GNR": "216"},
{"PSP": "171"}
]
},
{
"Ano": "2010",
"Entidade": [
{"GNR": "247"},
{"PSP": "162"}
]
},
{
"Ano": "2011",
"Entidade": [
{"GNR": "248"},
{"PSP": "181"}
]
},
{
"Ano": "2012",
"Entidade": [
{"GNR": "277"},
{"PSP": "150"}
]
},
{
"Ano": "2013",
"Entidade": [
{"GNR": "207"},
{"PSP": "169"}
]
},
{
"Ano": "2014",
"Entidade": [
{"GNR": "226"},
{"PSP": "137"}
]
}
],
"Distrito": "Évora",
"Factor_amostra": 0.020521270111203194,
"Somatorio_amostra": 2391
},
"VARNAME_1": null
}
},
...
and would like to access the "dgai_violencia_domestica_2008_2014.Factor_amostra" property of each object, so as to encode a color value.
Is this possible with Leaflet+Omnivore, or would d3 or another library be needed?
A current, broken version of the map lives here, with the relevant code being:
L.mapbox.accessToken = '...';
var map = L.mapbox.map('map', 'mapbox.streets').setView([39.5, -8.60], 7);
// Omnivore will AJAX-request this file behind the scenes and parse it:
// note that there are considerations:
// - The file must either be on the same domain as the page that requests it,
// or both the server it is requested from and the user's browser must
// support CORS.
// Internally this function uses the TopoJSON library to decode the given file
// into GeoJSON.
function getColor(d) {
return d > 0.75 ? '#800026' :
d > 0.50 ? '#FC4E2A' :
d > 0.25 ? '#FD8D3C' :
'#FFEDA0';
}
var pt = omnivore.topojson('dgai_violencia_domestica_2008_2014.topo.json');
function style(geometry) {
return {
fillColor: getColor(geometry.properties.dgai_violencia_domestica_2008_2014.Peso_na_duracao_da_amostra),
weight: 1,
opacity: 1,
color: 'white',
dashArray: '3',
fillOpacity: 1
};
}
pt.setStyle(style);
pt.addTo(map);
A nudge in the right direction, anyone?
Thanks in advance.

Did some testing and as it turns out, the setStyle function won't execute:
pt.setStyle(function (feature) {
console.log('Yay, i am executed!');
return {
'color': 'red'
}
});
Using that Yay, i am executed! never gets logged to the console. Which made me suspect that there's something wrong with the setStyle method of Omnivore. So i tried it with a custom layer:
var geojson = new L.GeoJSON(null);
var pt = omnivore.topojson(url, null, geojson).addTo(map);
geojson.setStyle(function (feature) {
console.log('Yay, i am executed!');
return {
'color': 'red'
};
});
Same thing, Yay, i am executed! never get logged to the console. One thing left to try was the style option of L.GeoJSON:
var geojson = new L.GeoJSON(null, {
'style': function (feature) {
console.log('Yay, i am executed!');
return {
'color': 'red'
};
}
});
var pt = omnivore.topojson(url, null, geojson).addTo(map);
And lo and behold, that does what it's supposed to do. So i tried it with your style and color function and dataset:
function getColor(d) {
return d > 0.75 ? '#800026' :
d > 0.50 ? '#FC4E2A' :
d > 0.25 ? '#FD8D3C' :
'#FFEDA0';
}
function getStyle (feature) {
return {
fillColor: getColor(feature.properties.dgai_violencia_domestica_2008_2014.Peso_na_duracao_da_amostra),
weight: 1,
opacity: 1,
color: 'white',
dashArray: '3',
fillOpacity: 1
};
}
var geojson = new L.GeoJSON(null, {
'style': getStyle
});
var pt = omnivore.topojson(url, null, geojson).addTo(map);
This gives me the following error:
Uncaught TypeError: Cannot read property 'Peso_na_duracao_da_amostra' of undefined
That's because on the third feature, that property is missing. So your dataset is corrupt or incomplete. Hopefully this will help you along, good luck, here's a Plunker of my experiment which works (so far):
http://plnkr.co/edit/P6t96hTaOgSxTc4TPUuV?p=preview

Related

How to color GeoJson polygons using another api?

I have a GeoJson map file with province ids and coordinates , also I am using another api which tells the color of each province id . I want to set fillColor of each polygon accordingly
my GeoJson file (just the first polygon as an example):
[
{
"type" : "FeatureCollection",
"features" : [
{
"type" : "Feature",
"id" : 0,
"regionColor": "orangeColor",
"geometry" : {
"type" : "Polygon",
"coordinates" : [...]
},
"properties" : {
"FID" : 0,
"FID_1" : 0
}
}
]
my API (imported as mockData):
{
"colors": [
{
"id": "0",
"countryColor": "red"
},
{
"id": "1",
"countryColor": "orange"
},
{
"id": "2",
"countryColor": "yellow"
}
]
}
my code :
<template>
<div class="container">
<div id="mapContainer">
</div>
</div>
</template>
<script>
import "leaflet/dist/leaflet.css";
import L from "leaflet";
import geojson from "../components/provinces.json"
import mockData from "./test.json"
export default{
name: "locationMap",
data() {
return{
center: [32.87255939010237, 53.781741816799745],
}
},
methods: {
setupLeafletMap: function () {
const mapDiv = L.map("mapContainer").setView(this.center, 5);
L.tileLayer(
'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
{
attribution: '© <a target="_blank" href="http://osm.org/copyright">OpenStreetMap</a> contributors',
// maxZoom: 18,
}
).addTo(mapDiv);
var myStyle = {
"fillColor": "#818181",
"color": "black",
"weight": 2,
"opacity": 0.65,
"fillOpacity": 0.6
};
L.geoJSON(geojson,{
style: myStyle,
}
}
}
mounted() {
this.setupLeafletMap()
console.log(mockData.colors[1].id)
},
}
</script>
L.geoJSON accepts a style function to dynamically apply styles based on each feature. You can write a style function that maps the feature ID to the color in your dataset. For example:
L.geoJSON(geoJSONData, {
// The style function receives each feature from your GeoJSON dataset.
// You can access the feature's properties to lookup the color.
style: function (feature) {
const fid = feature.properties.FID,
color = mockData.colors.find((color) => parseInt(color.id) === fid);
console.debug(`Feature with id ${fid} has now color ${color.countryColor}`);
return {
fillColor: color.countryColor,
color: "black",
weight: 2,
opacity: 0.65,
fillOpacity: 0.6
};
}
}).addTo(map);
I created an example with your code and some sample data as a reference, check it out here: https://codepen.io/strfx/pen/XWYNrBM
Hope this helps!

How to export the percentage value in amchart V3 export functionality

I'm drawing a pie chart using AmCharts V3 and am using the export plugin to export the data as a file. I'm displaying a percentage contibution of the sale in different countries and would like to also display this percentage when I export my data to a CSV or XLSX file, but I'm not able to do so.
Here is my code
var chart = AmCharts.makeChart("chartdivtaxes", {
type: "pie",
startDuration: 0,
theme: "light",
addClassNames: true,
labelText: "[[percents]]",
innerRadius: "30%",
labelFunction: function(value, valueText, valueAxis) {
valueText = parseFloat(valueText);
var percentageText = valueText
.toFixed(1)
.replace(/(\d)(?=(\d{3})+\.)/g, "$1,");
return percentageText + "%";
},
defs: {
filter: [
{
id: "shadow",
width: "200%",
height: "200%",
feOffset: {
result: "offOut",
in: "SourceAlpha",
dx: 0,
dy: 0
},
feGaussianBlur: {
result: "blurOut",
in: "offOut",
stdDeviation: 5
},
feBlend: {
in: "SourceGraphic",
in2: "blurOut",
mode: "normal"
}
}
]
},
dataProvider: [
{
countryName: "India",
country: "sale in india:",
litres: "800.00"
},
{
countryName: "africa",
country: "sale in africa:",
litres: "800.00"
},
{
countryName: "UK",
country: "sale in UK:",
litres: "800.00"
},
{
countryName: "US",
country: "sale in US:",
litres: "800.00"
}
],
valueField: "litres",
titleField: "country",
balloon: {
fixedPosition: false,
color: "#ffffff",
fillAlpha: 0.9,
fillColor: "#00000"
},
export: {
enabled: true,
divId: "exportLevy",
columnNames: {
litres: "TotalSale",
countryName: "Name"
},
menu: [
{
class: "export-main",
label: "Export",
menu: [
{
format: "XLSX"
},
{
format: "CSV"
}
]
}
],
exportFields: ["countryName", "litres", "percents"]
}
});
There are two ways you can go about this - both of which involve using the processData callback offered by the export plugin.
1) Use processData to add a percent property in your data and manually trigger a download with toCSV or toXLSX. Note that you will need to throw an exception to prevent the plugin from triggering the download multiple times:
var chart = AmCharts.makeChart("...", {
// ...
export: {
// ...
processData: function(data, cfg) {
//only for CSV and XLSX export. Wrap in an ignore call to prevent infinite loop
if ((cfg.format === "CSV" || cfg.format === "XLSX") && !cfg.ignoreThatRequest) {
var sum = data.reduce(function(accumulator, currentDataValue) {
return accumulator + parseFloat(currentDataValue.TotalSale);
}, 0);
data.forEach(function(currentDataValue) {
currentDataValue.percents =
(parseFloat(currentDataValue.TotalSale) / sum * 100).toFixed(1) + "%";
});
//will map to this.toCSV or this.toXLSX
this["to" + cfg.format]({
data: JSON.parse(JSON.stringify(data)),
ignoreThatRequest: true, //set ignore flag as processData will execute again when this is called
exportFields: ["Name", "TotalSale", "percents"]
},
function(output) {
this.download(output, cfg.mimeType, cfg.fileName + "." + cfg.extension);
}
);
throw "Invoked – Use custom handler (stop multiple download)"; //throw an exception to stop the multi-download attempt
}
return data;
}
}
});
Demo of method #1
2) Alternatively, add a dummy percents property in your dataProvider with its value set to null and use processData to fill it in before exporting the chart. This is simpler and doesn't require an exception workaround to prevent multiple downloads:
var chart = AmCharts.makeChart("...", {
// ...
export: {
// ...
processData: function(data, cfg) {
var sum = data.reduce(function(accumulator, currentDataValue) {
return accumulator + parseFloat(currentDataValue.TotalSale);
}, 0);
data.forEach(function(currentDataValue) {
currentDataValue.percents =
(parseFloat(currentDataValue.TotalSale) / sum * 100).toFixed(1) + "%";
});
return data;
}
}
});
Demo of method #2

ng-google-chart custom color for each column in column chart

I'm using the ng-google-charts module to build google charts for my angular application, what I'm trying to do is draw a column chart.
The code works the chart seems to be drawn correctly but I can't figure out how to add a colour in the rows I'm generating so that each column is coloured differently.
Here is my code, looking at google charts documentation it seems that I should be able to assign a hex code for each column but none of the examples I've seen use angular and none of them build their rows as literal objects like I need to do.
var collsArray = [];
var rowsArray = [];
for (var i = 0; i < vm.projects.length ; i++) {
//this is where I build each data row and where I think I need to add the color
rowsArray.push({
"c": [
{
"v": vm.projects[i].name
},
{
"v": vm.projects[i].developers,
"f": vm.projects[i].developers + ' developers working on ' + vm.projects[i].name
}]
});
}
collsArray = [{id: 'project', label: 'Project', type: 'string'},
{id: 'developers', label: 'Developers working', type: 'number'}];
vm.chartProjects = {
"type": "ColumnChart",
"displayed": false,
"data": {
"cols": collsArray,
"rows": rowsArray
},
"options": {
"isStacked": "true",
"fill": 0,
"width": '100%',
"height": '100%',
"displayExactValues": true,
"chartArea": {
"left": "1%",
"top": "1%",
"height": "98%",
"width": "98%"
}
},
"formatters": {},
"view": {}
};
Adding a Style Column Role is the easiest way to color an individual bar.
You could try something like this...
var colorPallette = [
'#7B241C', '#CB4335', '#FF9900', 'Gold', '#28B463',
'#196F3D', '#0D47A1', '#29B6F6', 'Indigo', 'Violet'
];
var collsArray = [];
var rowsArray = [];
collsArray = [
{id: 'project', label: 'Project', type: 'string'},
{id: 'developers', label: 'Developers working', type: 'number'},
{role: 'style', type: 'string'} // style column
];
var colorIndex = -1;
for (var i = 0; i < vm.projects.length ; i++) {
// manage color pallette
colorIndex++;
if (colorIndex === colorPallette.length) {
colorIndex = 0;
}
rowsArray.push({
"c": [
{
"v": vm.projects[i].name
},
{
"v": vm.projects[i].developers,
"f": vm.projects[i].developers + ' developers working on ' + vm.projects[i].name
},
{
"v": colorPallette[colorIndex] // style column
}
]
});
}
This answer shows the various color definitions you could use.
FYI: this option does not work with Material charts...

Why my column chart is getting cropped in highcharts

I have implemented column chart using highchart .
My rightmost column is getting cropped and I am not able to get it fixed .
Please suggest which option is being missed by me .
{
"chart":{
"renderTo":"1_123456_id",
"type":"column",
"marginBottom":100,
"marginTop":100,
"marginRight":400,
"width":1050
},
"leftMetric":"Too Soft",
"rightMetric":"Too Loud",
"activeCount":8,
"passiveCount":0,
"optimal":92,
"totalResponses":25,
"averageText":"4.6",
"plotOptions":{
"series":{
"pointWidth":[
"30"
],
"borderRadius":[
"10"
],
},
"column":{
"pointPlacement":"on",
},
},
"credits":{
"enabled":false
},
"title":{
"text":"VOLUME",
"x":310,
"align":"left",
"style":{
"fontWeight":"bold",
"fontSize":15,
"color":"#000",
"marginRight":100
}
},
"xAxis":[
{
"categories":[
0,
0,
0,
1,
0,
20,
2,
0,
1,
1,
0
],
"tickmarkPlacement":"on",
"tickPositions":[
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11
],
"gridLineDashStyle":"longdash",
"gridLineWidth":1,
"labels":{
"style":{
"fontWeight":"bold",
"fontSize":15
}
}
},
{
"linkedTo":0,
"tickmarkPlacement":"on",
"tickPositions":[
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11
],
"opposite":"true",
"categories":[
0,
1,
2,
3,
4,
5,
4,
3,
2,
1,
0
],
"gridLineDashStyle":"longdash",
"gridLineWidth":1
}
],
"yAxis":{
"min":0,
"max":30,
"labels":{
"enabled":true
},
"title":{
"text":"Responses"
},
"tickInterval":2,
"gridLineColor":"#9ACD9D",
},
"series":[
{
"showInLegend":false,
"name":"speaker",
"data":[
{
"y":0,
"color":"C82506"
},
{
"y":0,
"color":"BC5B0C"
},
{
"y":0,
"color":"F39019"
},
{
"y":1,
"color":"F5D329"
},
{
"y":0,
"color":"#70BF40"
},
{
"y":20,
"color":"#01882A"
},
{
"y":2,
"color":"#70BF40"
},
{
"y":0,
"color":"F5D329"
},
{
"y":1,
"color":"F39019"
},
{
"y":1,
"color":"BC5B0C"
},
{
"y":1,
"color":"C82506"
}
]
}
]
}
LINK TO FIDDLE
EDIT
How can make grid lines to move out of axis on extremes and middle as marked in image
Correct way:
you just need to turn off clip in plotOptions
plotOptions:{
column: {
pointPlacement: "on",
clip: false,
}
}
Here is the Fiddle and also Thanks to Pawel Fus
Tricky way:
Here is what you want. i don't update my previous answer as that may help others.
but as the problem was charts cropped by highchart so i do the reverse and remove the integer number from clip-path= "url(#highcharts-NUMBER) attribute to have the full chart.
<g class="highcharts-series highcharts-tracker" visibility="visible" zIndex="3" transform="translate(51,100) scale(1 1)" style="" clip-path="url(#highcharts-1)">
Here the code to do this:
function showMagic(){
$(".highcharts-series-group").children()
.filter(function() {
var $this = $(this);
var lol = $this.attr("clip-path");
if (lol) {
$this.attr("clip-path","url(#highcharts)");
} else {
return false;
}
});
}
window.onload = showMagic;
Yes a little tricky, but it works! Here is the LIVE DEMO
UPDATE:
This part will be the answer to the update part of question:
we should format labels of xAxis :
"labels": {
"useHTML": true,
"formatter": function () {
if(this.value==0 || this.value==5)
{
return '<p style="margin-top: -20px;" >'+this.value + '<br> | </p> ' ;
}
else
{
return this.value;
}
}
},
Here is the LIVE DEMO
This is because of pointPlacement: "on". so just remove this part of yor code:
"column":{
"pointPlacement":"on",
},
When pointPlacement is "on", the point will not create any padding of the X axis In a column chart.
Here is the fiddle
First remove tickPositions, they are unnecessary when using categories. Then you need to set:
min: -0.5
max: categories.length - 0.5 (10.5 in your case)
startOnTick: false
endOnTick: false
And live example: http://jsfiddle.net/ASJm9/7/

displaying custom tooltip when hovering over a point in flot

From the example here, I kind of know how to create a Flot graph that shows tooltips when hovering. But the examples only show to how to display tooltips containing the x value, y value, label, etc., and I can't figure out how to create more customized tooltips.
Is there someplace I can attach custom data, that I can access when creating the tooltip?
For example, to simplify, let's suppose my code looks like:
var d = [ { label: "Fake!", data: [ [1290802154, 0.3], [1292502155, 0.1] ] } ];
var options = {
xaxis: { mode: "time" },
series: {
lines: { show: true },
points: { show: true }
},
grid: { hoverable: true, clickable: true }
};
$.plot($("#placeholder"), d, options);
Now, when clicking on the first datapoint, I want the tooltip to show "Hello", and when clicking on the second datapoint I want to show "Bye". How do I do this? When binding the plothover event
$(".placeholder").bind("plothover", function (event, pos, item) { /* etc. */ };
I'm not sure what "item" refers to, and how to attach data to it.
You can add data to the series simply by adding it to the data array.
Instead of
$.plot(element, [[1, 2], [2, 4]] ...)
You can
$.plot(element, [[1, 2, "label"], [2, 4, "another label"]] ...)
And then use that information to show a custom label.
See this fiddle for a full example:
http://jsfiddle.net/UtcBK/328/
$(function() {
var sin = [],
cos = [];
for (var i = 0; i < 14; i += 0.5) {
sin.push([i, Math.sin(i), 'some custom label ' + i]);
cos.push([i, Math.cos(i), 'another custom label ' + i]);
}
var plot = $.plot($("#placeholder"), [{
data: sin,
label: "sin(x)"
},
{
data: cos,
label: "cos(x)"
}
], {
series: {
lines: {
show: true
},
points: {
show: true
}
},
grid: {
hoverable: true,
clickable: true
},
yaxis: {
min: -1.2,
max: 1.2
}
});
$("#placeholder").bind("plothover", function(event, pos, item) {
$("#tooltip").remove();
if (item) {
var tooltip = item.series.data[item.dataIndex][2];
$('<div id="tooltip">' + tooltip + '</div>')
.css({
position: 'absolute',
display: 'none',
top: item.pageY + 5,
left: item.pageX + 5,
border: '1px solid #fdd',
padding: '2px',
'background-color': '#fee',
opacity: 0.80
})
.appendTo("body").fadeIn(200);
showTooltip(item.pageX, item.pageY, tooltip);
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="http://people.iola.dk/olau/flot/jquery.flot.js"></script>
<div id="placeholder" style="width:600px;height:300px"></div>
Here is a rough JSFiddle example that I whipped up. Not sure if it's functioning exactly how you like but might spark an idea...
[update]
you'll want to bind to the
$("#placeholder").bind("plotclick", function (event, pos, item) {/* code */});
event for clicking events
[update2] Updated Example
I've adjusted the example to use your test data and to work more with what you have described above. As for the item object it seems that it is generated on the fly so, from what I can tell, you can not add additional data to it. However, you can create an array to cache the item objects when clicked and add additional data to them and use them for the hover event.
This new example does just that, it shows the normal tooltip when nothing is clicked. but once clicked it determines if the point clicked was the first or second and adds an addition property to the item object called alternateText and stores it in an array called itemsClicked.
Now when a point is hovered over it checks to see if there is a cached item object within the array based on the same index of the current item object, which is obtained via item.dataIndex. If there is a matching index in the cache array itemsClicked it will grab the item object from it and use the alternateText property that was added during the click event earlier.
The first point's item object would look something like this:
item : {
dataIndex: 0,
datapoint: [
1290802154,
0.3
],
pageX: 38,
pageY: 82,
series: {/* properties of the series that this point is in */},
seriesIndex: 0
}
Once clicked it would then look like this and be stored in the itemsClicked array:
item : {
alternateText: 'hello',
dataIndex: 0,
datapoint: [
1290802154,
0.3
],
pageX: 38,
pageY: 82,
series: {/* properties of the series that this point is in */},
seriesIndex: 0
}
Please let me know if any of this is helpful or not, if not I'll shut up and stop updating my answer :P
Also you can try following code:
function showTooltip(x, y, contents, z) {
$('<div id="tooltip">' + contents + '</div>').css({
position: 'absolute',
display: 'none',
top: y - 30,
left: x - 110,
'font-weight': 'bold',
border: '1px solid rgb(255, 221, 221)',
padding: '2px',
'background-color': z,
opacity: '0.8'
}).appendTo("body").show();
};
$(document).ready(
$(function() {
var data = [{
"label": "scott",
"data": [
[1317427200000 - 5000000 * 3, "17017"],
[1317513600000 - 5000000 * 5, "77260"]
]
},
{
"label": "martin",
"data": [
[1317427200000 - 5000000 * 2, "96113"],
[1317513600000 - 5000000 * 4, "33407"]
]
},
{
"label": "solonio",
"data": [
[1317427200000 - 5000000, "13041"],
[1317513600000 - 5000000 * 3, "82943"]
]
},
{
"label": "swarowsky",
"data": [
[1317427200000, "83479"],
[1317513600000 - 5000000 * 2, "96357"],
[1317600000000 - 5000000, "55431"]
]
},
{
"label": "elvis",
"data": [
[1317427200000 + 5000000, "40114"],
[1317513600000 - 5000000 * 1, "47065"]
]
},
{
"label": "alan",
"data": [
[1317427200000 + 5000000 * 2, "82504"],
[1317513600000, "46577"]
]
},
{
"label": "tony",
"data": [
[1317513600000 + 5000000, "88967"]
]
},
{
"label": "bill",
"data": [
[1317513600000 + 5000000 * 2, "60187"],
[1317600000000, "39090"]
]
},
{
"label": "tim",
"data": [
[1317513600000 + 5000000 * 3, "95382"],
[1317600000000 + 5000000, "89699"]
]
},
{
"label": "britney",
"data": [
[1317513600000 + 5000000 * 4, "76772"]
]
},
{
"label": "logan",
"data": [
[1317513600000 + 5000000 * 5, "88674"]
]
}
];
var options = {
series: {
bars: {
show: true,
barWidth: 60 * 60 * 1000,
align: 'center'
}
},
points: {
show: true
},
lines: {
show: true
},
grid: {
hoverable: true,
clickable: true
},
yaxes: {
min: 0
},
xaxis: {
mode: 'time',
timeformat: "%b %d",
minTickSize: [1, "month"],
tickSize: [1, "day"],
autoscaleMargin: .10
}
};
$(function() {
$.plot($('#placeholder'), data, options);
});
$(function() {
var previousPoint = null;
$("#placeholder").bind("plothover", function(event, pos, item) {
if (item) {
if (previousPoint != item.datapoint) {
previousPoint = item.datapoint;
$("#tooltip").remove();
var x = item.datapoint[0],
y = item.datapoint[1] - item.datapoint[2];
debugger;
showTooltip(item.pageX, item.pageY, y + " " + item.series.label, item.series.color);
}
} else {
$("#tooltip").remove();
previousPoint = null;
}
})
});
})
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>
<script src="http://people.iola.dk/olau/flot/jquery.flot.js"></script>
<div id="content">
<div class="demo-container">
<div id="placeholder" class="demo-placeholder" style="width:800px;height:600px;"></div>
</div>
</div>

Categories

Resources