| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017 |
- // Licensed to Cloudera, Inc. under one
- // or more contributor license agreements. See the NOTICE file
- // distributed with this work for additional information
- // regarding copyright ownership. Cloudera, Inc. licenses this file
- // to you under the Apache License, Version 2.0 (the
- // "License"); you may not use this file except in compliance
- // with the License. You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- ko.HUE_CHARTS = {
- TYPES: {
- LINECHART: "lines",
- BARCHART: "bars",
- POINTCHART: "points",
- PIECHART: "pie",
- MAP: "map"
- }
- };
- ko.bindingHandlers.pieChart = {
- update: function (element, valueAccessor) {
- var _options = valueAccessor();
- var _data = _options.transformer(_options.data);
- $(element).css("marginLeft", "auto");
- $(element).css("marginRight", "auto");
- if (typeof _options.maxWidth != "undefined") {
- var _max = _options.maxWidth * 1;
- $(element).width(Math.min($(element).parent().width(), _max));
- }
- if ($(element).find("svg").length > 0 && _data.length == 0) {
- $(element).find("svg").empty();
- }
- if (_data.length > 0 && isNaN(_data[0].value)) {
- _data = [];
- $(element).find("svg").empty();
- }
- if ($(element).is(":visible")) {
- nv.addGraph(function () {
- var _chart = nv.models.growingPieChart()
- .x(function (d) {
- return d.label
- })
- .y(function (d) {
- return d.value
- })
- .height($(element).width())
- .showLabels(true).showLegend(false);
- var _d3 = ($(element).find("svg").length > 0) ? d3.select($(element).find("svg")[0]) : d3.select($(element)[0]).append("svg");
- _d3.datum(_data)
- .transition().duration(150)
- .each("end", _options.onComplete != null ? _options.onComplete : void(0))
- .call(_chart);
- if (_options.fqs) {
- $.each(_options.fqs(), function (cnt, item) {
- if (item.field() == _options.field()) {
- _chart.selectSlices($.map(item.filter(), function(it) {return it.value();}));
- }
- });
- }
- nv.utils.windowResize(_chart.update);
- $(element).height($(element).width());
- $(element).parents(".card-widget").on("resize", function () {
- if (typeof _options.maxWidth != "undefined") {
- var _max = _options.maxWidth * 1;
- $(element).width(Math.min($(element).parent().width(), _max));
- }
- $(element).height($(element).width());
- _chart.update();
- });
- return _chart;
- }, function () {
- var _d3 = ($(element).find("svg").length > 0) ? d3.select($(element).find("svg")[0]) : d3.select($(element)[0]).append("svg");
- _d3.selectAll(".nv-slice").on("click",
- function (d, i) {
- if (typeof _options.onClick != "undefined") {
- chartsUpdatingState();
- _options.onClick(d);
- }
- });
- });
- }
- }
- };
- ko.bindingHandlers.barChart = {
- update: function (element, valueAccessor) {
- barChartBuilder(element, valueAccessor(), false);
- }
- };
- ko.bindingHandlers.timelineChart = {
- update: function (element, valueAccessor) {
- barChartBuilder(element, valueAccessor(), true);
- }
- };
- ko.bindingHandlers.lineChart = {
- update: function (element, valueAccessor) {
- lineChartBuilder(element, valueAccessor());
- }
- };
- ko.bindingHandlers.leafletMapChart = {
- update: function (element, valueAccessor) {
- var _options = valueAccessor();
- var _data = _options.transformer(valueAccessor().datum);
- function getMapBounds(lats, lngs) {
- lats = lats.sort();
- lngs = lngs.sort();
- return [
- [lats[lats.length - 1], lngs[lngs.length - 1]], // north-east
- [lats[0], lngs[0]] // south-west
- ]
- }
- if ($(element).data("map") != null) {
- try {
- $(element).data("map").remove();
- }
- catch (err) {
- if (typeof console != "undefined") {
- console.error(err);
- }
- }
- }
- var _lats = [];
- _data.forEach(function (item) {
- if (item.lat != null && $.isNumeric(item.lat)) {
- _lats.push(item.lat);
- }
- });
- var _lngs = [];
- _data.forEach(function (item) {
- if (item.lng != null && $.isNumeric(item.lng)) {
- _lngs.push(item.lng);
- }
- });
- if ($(element).parents(".tab-pane").length > 0){
- $(element).height($(element).parents(".tab-pane").height() - 100);
- }
- else {
- $(element).height(300);
- }
- if (((_options.visible != null && _options.visible) || _options.visible == null || typeof _options == "undefined") && _data.length > 0) {
- $(element).show();
- }
- else {
- $(element).hide();
- }
- var _map = null;
- if (element._map != null) {
- element._leaflet = false;
- element._map.remove();
- }
- if (_lats.length > 0 && _lngs.length > 0) {
- try {
- if (_map == null) {
- _map = L.map(element);
- L.tileLayer("http://{s}.tile.osm.org/{z}/{x}/{y}.png", {
- attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
- }).addTo(_map);
- }
- _map.fitBounds(getMapBounds(_lats, _lngs));
- _data.forEach(function (item) {
- if (item.lng != null && item.lat != null) {
- var _addMarker = false;
- try {
- var _latLngObj = L.latLng(item.lat, item.lng);
- _addMarker = true;
- }
- catch (e){
- if (typeof console != "undefined") {
- console.error(e);
- }
- }
- if (_addMarker){
- var _marker = L.marker([item.lat, item.lng]).addTo(_map);
- if (item.label != null) {
- _marker.bindPopup(item.label);
- }
- }
- }
- });
- if (_options.onComplete != null) {
- _options.onComplete();
- }
- }
- catch (err) {
- $.jHueNotify.error(err.message);
- }
- }
- element._map = _map;
- }
- };
- ko.bindingHandlers.mapChart = {
- render: function (element, valueAccessor) {
- var _options = valueAccessor();
- $(element).empty();
- $(element).css("position", "relative");
- $(element).css("marginLeft", "auto");
- $(element).css("marginRight", "auto");
- if (typeof _options.maxWidth != "undefined") {
- var _max = _options.maxWidth * 1;
- $(element).width(Math.min($(element).parent().width(), _max));
- }
- $(element).height($(element).width() / 2.23);
- var _scope = typeof _options.data.scope != "undefined" ? String(_options.data.scope) : "world";
- var _data = _options.transformer(_options.data);
- var _maxWeight = 0;
- $(_data).each(function (cnt, item) {
- if (item.value > _maxWeight) _maxWeight = item.value;
- });
- var _chunk = _maxWeight / _data.length;
- var _mapdata = {};
- var _maphovers = {};
- var _fills = {};
- var _noncountries = [];
- if (_options.isScale) {
- _fills["defaultFill"] = HueColors.WHITE;
- var _colors = HueColors.scale(HueColors.LIGHT_BLUE, HueColors.DARK_BLUE, _data.length);
- $(_colors).each(function (cnt, item) {
- _fills["fill_" + cnt] = item;
- });
- $(_data).each(function (cnt, item) {
- var _place = item.label.toUpperCase();
- if (_place != null) {
- _mapdata[_place] = {
- fillKey: "fill_" + (Math.floor(item.value / _chunk) - 1),
- id: _place,
- cat: item.obj.cat,
- value: item.obj.value,
- selected: item.obj.selected
- };
- _maphovers[_place] = item.value;
- }
- else {
- _noncountries.push(item);
- }
- });
- }
- else {
- _fills["defaultFill"] = HueColors.LIGHT_BLUE;
- _fills["selected"] = HueColors.DARK_BLUE;
- $(_data).each(function (cnt, item) {
- var _place = item.label.toUpperCase();
- if (_place != null) {
- _mapdata[_place] = {
- fillKey: "selected",
- id: _place,
- cat: item.obj.cat,
- value: item.obj.value,
- selected: item.obj.selected
- };
- _maphovers[_place] = item.value;
- }
- else {
- _noncountries.push(item);
- }
- });
- }
- var _map = null;
- function createDatamap(element, options, fills, mapData, nonCountries, mapHovers) {
- _map = new Datamap({
- element: element,
- fills: fills,
- scope: _scope,
- data: mapData,
- onClick: function (data) {
- if (typeof options.onClick != "undefined") {
- chartsUpdatingState();
- options.onClick(data);
- }
- },
- done: function (datamap) {
- var _bubbles = [];
- if (options.enableGeocoding) {
- $(nonCountries).each(function (cnt, item) {
- HueGeo.getCityCoordinates(item.label, function (lat, lng) {
- _bubbles.push({
- fillKey: "selected",
- label: item.label,
- value: item.value,
- radius: 4,
- latitude: lat,
- longitude: lng
- });
- _map.bubbles(_bubbles, {
- popupTemplate: function (geo, data) {
- return '<div class="hoverinfo" style="text-align: center"><strong>' + data.label + '</strong><br/>' + item.value + '</div>'
- }
- });
- });
- });
- }
- },
- geographyConfig: {
- hideAntarctica: true,
- borderWidth: 1,
- borderColor: HueColors.DARK_BLUE,
- highlightOnHover: true,
- highlightFillColor: HueColors.DARK_BLUE,
- highlightBorderColor: HueColors.BLUE,
- selectedFillColor: HueColors.DARKER_BLUE,
- selectedBorderColor: HueColors.DARKER_BLUE,
- popupTemplate: function (geography, data) {
- var _hover = '';
- if (data != null) {
- _hover = '<br/>' + mapHovers[data.id];
- }
- return '<div class="hoverinfo" style="text-align: center"><strong>' + geography.properties.name + '</strong>' + _hover + '</div>'
- }
- }
- });
- if (options.onComplete != null) {
- options.onComplete();
- }
- }
- createDatamap(element, _options, _fills, _mapdata, _noncountries, _maphovers)
- $(element).parents(".card-widget").one("resize", function () {
- ko.bindingHandlers.mapChart.render(element, valueAccessor);
- });
- },
- init: function (element, valueAccessor) {
- ko.bindingHandlers.mapChart.render(element, valueAccessor)
- },
- update: function (element, valueAccessor) {
- ko.bindingHandlers.mapChart.render(element, valueAccessor);
- }
- };
- function lineChartBuilder(element, options) {
- var _datum = options.transformer(options.datum);
- $(element).height(300);
- if ($(element).find("svg").length > 0 && (_datum.length == 0 || _datum[0].values.length == 0)) {
- $(element).find("svg").empty();
- }
- if (_datum.length > 0 && _datum[0].values.length > 0 && (isNaN(_datum[0].values[0].x) || isNaN(_datum[0].values[0].y))) {
- _datum = [];
- $(element).find("svg").empty();
- }
- if ($(element).is(":visible")) {
- nv.addGraph(function () {
- var _chart = nv.models.lineWithBrushChart();
- if (_datum.length > 0 && _datum[0].values.length > 10) {
- _chart.enableSelection();
- }
- if (options.showControls != null) {
- _chart.showControls(false);
- }
- _chart.onSelectRange(function (from, to) {
- chartsUpdatingState();
- options.onSelectRange(from, to);
- });
- _chart.xAxis.showMaxMin(false);
- _chart.yAxis
- .tickFormat(d3.format(",0f"));
- var _d3 = ($(element).find("svg").length > 0) ? d3.select($(element).find("svg")[0]) : d3.select($(element)[0]).append("svg");
- _d3.datum(_datum)
- .transition().duration(150)
- .each("end", options.onComplete != null ? options.onComplete : void(0))
- .call(_chart);
- nv.utils.windowResize(_chart.update);
- return _chart;
- }, function () {
- var _d3 = ($(element).find("svg").length > 0) ? d3.select($(element).find("svg")[0]) : d3.select($(element)[0]).append("svg");
- _d3.selectAll(".nv-line").on("click",
- function (d, i) {
- if (typeof options.onClick != "undefined") {
- chartsUpdatingState();
- options.onClick(d);
- }
- });
- });
- }
- }
- function barChartBuilder(element, options, isTimeline) {
- var _datum = options.transformer(options.datum);
- $(element).height(300);
- var _isPivot = options.isPivot != null ? options.isPivot : false;
- if ($(element).find("svg").length > 0 && (_datum.length == 0 || _datum[0].values.length == 0)) {
- $(element).find("svg").empty();
- }
- if (_datum.length > 0 && _datum[0].values.length > 0 && isNaN(_datum[0].values[0].y)) {
- _datum = [];
- $(element).find("svg").empty();
- }
- if ($(element).is(":visible")) {
- nv.addGraph(function () {
- var _chart;
- var insertLinebreaks = function (d) {
- var _el = d3.select(this);
- var _mom = moment(d);
- if (_mom != null && _mom.isValid()) {
- var _words = _mom.format("hh:mm:ss YYYY-MM-DD").split(" ");
- _el.text("");
- for (var i = 0; i < _words.length; i++) {
- var tspan = _el.append("tspan").text(_words[i]);
- if (i > 0) {
- tspan.attr("x", 0).attr("dy", "15");
- }
- }
- }
- };
- if (isTimeline) {
- if ($(element).find("svg").length > 0 && $(element).find(".nv-discreteBarWithAxes").length > 0) {
- $(element).find("svg").empty();
- }
- _chart = nv.models.multiBarWithBrushChart();
- if (_datum.length > 0 && _datum[0].values.length > 10) {
- _chart.enableSelection();
- }
- _chart.onSelectRange(function (from, to) {
- chartsUpdatingState();
- options.onSelectRange(from, to);
- });
- _chart.xAxis.tickFormat(d3.time.format("%Y-%m-%d %H:%M:%S"));
- _chart.multibar.hideable(true);
- _chart.multibar.stacked(typeof options.stacked != "undefined" ? options.stacked : false);
- _chart.onStateChange(options.onStateChange);
- _chart.onChartUpdate(function () {
- _d3.selectAll("g.nv-x.nv-axis g text").each(insertLinebreaks);
- });
- }
- else {
- var _isDiscrete = false;
- for (var j = 0; j < _datum.length; j++) {
- for (var i = 0; i < _datum[j].values.length; i++) {
- if (isNaN(_datum[j].values[i].x * 1)) {
- _isDiscrete = true;
- break;
- }
- }
- }
- if (_isDiscrete && ! _isPivot) {
- if ($(element).find("svg").length > 0 && $(element).find(".nv-multiBarWithLegend").length > 0) {
- $(element).find("svg").empty();
- }
- _chart = nv.models.growingDiscreteBarChart()
- .x(function (d) {
- return d.x
- })
- .y(function (d) {
- return d.y
- })
- .staggerLabels(true);
- }
- else {
- if ($(element).find("svg").length > 0 && $(element).find(".nv-discreteBarWithAxes").length > 0) {
- $(element).find("svg").empty();
- }
- _chart = nv.models.multiBarWithBrushChart();
- if (_datum.length > 0 && _datum[0].values.length > 10) {
- _chart.enableSelection();
- }
- if (_isPivot){
- _chart.hideSelection();
- }
- else {
- _chart.xAxis.showMaxMin(false).tickFormat(d3.format(",0f"));
- }
- _chart.multibar.hideable(true);
- _chart.multibar.stacked(typeof options.stacked != "undefined" ? options.stacked : false);
- _chart.onStateChange(options.onStateChange);
- _chart.onSelectRange(function (from, to) {
- chartsUpdatingState();
- options.onSelectRange(from, to);
- });
- }
- }
- _chart.transitionDuration(0);
- _chart.yAxis
- .tickFormat(d3.format(",0f"));
- var _d3 = ($(element).find("svg").length > 0) ? d3.select($(element).find("svg")[0]) : d3.select($(element)[0]).append("svg");
- _d3.datum(_datum)
- .transition().duration(150)
- .each("end", function () {
- if (options.onComplete != null) {
- options.onComplete();
- }
- if (isTimeline) {
- _d3.selectAll("g.nv-x.nv-axis g text").each(insertLinebreaks);
- }
- }).call(_chart);
- $.each(options.fqs(), function (cnt, item) {
- if (item.field() == options.field) {
- _chart.selectBars($.map(item.filter(), function(it) {return it.value();}));
- }
- if (item.field().indexOf(":") > -1){
- _chart.selectBars({
- field: item.field(),
- selected: $.map(item.filter(), function(it) {return it.value();})
- });
- }
- });
- nv.utils.windowResize(_chart.update);
- return _chart;
- }, function () {
- var _d3 = ($(element).find("svg").length > 0) ? d3.select($(element).find("svg")[0]) : d3.select($(element)[0]).append("svg");
- _d3.selectAll(".nv-bar").on("click",
- function (d, i) {
- if (typeof options.onClick != "undefined") {
- chartsUpdatingState();
- options.onClick(d);
- }
- });
- });
- }
- }
- ko.bindingHandlers.partitionChart = {
- update: function (element, valueAccessor) {
- var MIN_HEIGHT_FOR_TOOLTIP = 24;
- var _options = valueAccessor();
- var _data = _options.transformer(valueAccessor().datum);
- var _w = $(element).width(),
- _h = 300,
- _x = d3.scale.linear().range([0, _w]),
- _y = d3.scale.linear().range([0, _h]);
- var _tip = d3.tip()
- .attr("class", "d3-tip")
- .html(function (d) {
- if (d.depth < 2) {
- return d.name + " (" + d.value + ")";
- }
- else {
- return d.parent.name + " - " + d.name + " (" + d.value + ")";
- }
- })
- .offset([-12, 0])
- var _svg = d3.select(element).append("svg:svg");
- _svg.call(_tip);
- var _vis = ($(element).find("svg").length > 0) ? d3.select($(element).find("svg")[0]) : d3.select($(element)[0]).append("svg");
- _vis.attr("class", "partitionChart")
- .style("width", _w + "px")
- .style("height", _h + "px")
- .append("svg:svg")
- .attr("width", _w)
- .attr("height", _h);
- var _partition = d3.layout.partition()
- .value(function (d) {
- return d.size;
- });
- var g = _vis.selectAll("g")
- .data(_partition.nodes(_data))
- .enter().append("svg:g")
- .attr("transform", function (d) {
- return "translate(" + _x(d.y) + "," + _y(d.x) + ")";
- })
- .on("mouseover", function (d, i) {
- if (element.querySelectorAll("rect")[i].getBBox().height < MIN_HEIGHT_FOR_TOOLTIP) {
- _tip.attr("class", "d3-tip").show(d);
- }
- if (this.__data__.parent == undefined) return;
- d3.select(this).select("rect").classed("mouseover", true)
- })
- .on("mouseout", function (d, i) {
- if (element.querySelectorAll("rect")[i].getBBox().height < MIN_HEIGHT_FOR_TOOLTIP) {
- _tip.attr("class", "d3-tip").show(d);
- _tip.hide();
- }
- d3.select(this).select("rect").classed("mouseover", false)
- });
- if (typeof _options.zoomable == "undefined" || _options.zoomable) {
- g.on("click", click)
- .on("dblclick", function (d, i) {
- if (typeof _options.onClick != "undefined") {
- chartsUpdatingState();
- _options.onClick(d);
- }
- });
- }
- else {
- g.on("click", function (d, i) {
- if (typeof _options.onClick != "undefined") {
- chartsUpdatingState();
- _options.onClick(d);
- }
- });
- }
- var _kx = _w / _data.dx,
- _ky = _h / 1;
- var _colors = HueColors.scale(HueColors.DARK_BLUE, HueColors.BLUE, 5)
- g.append("svg:rect")
- .attr("width", _data.dy * _kx)
- .attr("height", function (d) {
- return d.dx * _ky;
- })
- .attr("class", function (d) {
- return d.children ? "parent" : "child";
- })
- .attr("stroke", HueColors.DARK_BLUE)
- .attr("fill", function (d, i) {
- return _colors[d.depth];
- });
- g.append("svg:text")
- .attr("transform", transform)
- .attr("dy", ".35em")
- .style("opacity", function (d) {
- return d.dx * _ky > 12 ? 1 : 0;
- })
- .text(function (d) {
- if (d.depth < 2) {
- return d.name + " (" + d.value + ")";
- }
- else {
- return d.parent.name + " - " + d.name + " (" + d.value + ")";
- }
- });
- d3.select(window)
- .on("click", function () {
- click(_data);
- });
- function click(d) {
- _tip.hide();
- if (!d.children) return;
- _kx = (d.y ? _w - 40 : _w) / (1 - d.y);
- _ky = _h / d.dx;
- _x.domain([d.y, 1]).range([d.y ? 40 : 0, _w]);
- _y.domain([d.x, d.x + d.dx]);
- var t = g.transition()
- .duration(d3.event.altKey ? 7500 : 750)
- .attr("transform", function (d) {
- return "translate(" + _x(d.y) + "," + _y(d.x) + ")";
- });
- t.select("rect")
- .attr("width", d.dy * _kx)
- .attr("height", function (d) {
- return d.dx * _ky;
- });
- t.select("text")
- .attr("transform", transform)
- .style("opacity", function (d) {
- return d.dx * _ky > 12 ? 1 : 0;
- });
- d3.event.stopPropagation();
- }
- function transform(d) {
- return "translate(8," + d.dx * _ky / 2 + ")";
- }
- }
- };
- function chartsUpdatingState() {
- $(document).find("svg").css("opacity", "0.5");
- }
- var tipBuilder = function () {
- var direction = d3_tip_direction,
- offset = d3_tip_offset,
- html = d3_tip_html,
- node = initNode(),
- svg = null,
- point = null,
- target = null
- function tip(vis) {
- svg = getSVGNode(vis)
- point = svg.createSVGPoint()
- document.body.appendChild(node)
- }
- // Public - show the tooltip on the screen
- //
- // Returns a tip
- tip.show = function () {
- var args = Array.prototype.slice.call(arguments)
- if (args[args.length - 1] instanceof SVGElement) target = args.pop()
- var content = html.apply(this, args),
- poffset = offset.apply(this, args),
- dir = direction.apply(this, args),
- nodel = d3.select(node), i = 0,
- coords
- nodel.html(content)
- .style({ opacity: 1, "pointer-events": "all" })
- while (i--) nodel.classed(directions[i], false)
- coords = direction_callbacks.get(dir).apply(this)
- nodel.classed(dir, true).style({
- top: (coords.top + poffset[0]) + "px",
- left: (coords.left + poffset[1]) + "px"
- })
- return tip
- }
- // Public - hide the tooltip
- //
- // Returns a tip
- tip.hide = function () {
- nodel = d3.select(node)
- nodel.style({ opacity: 0, "pointer-events": "none" })
- return tip
- }
- // Public: Proxy attr calls to the d3 tip container. Sets or gets attribute value.
- //
- // n - name of the attribute
- // v - value of the attribute
- //
- // Returns tip or attribute value
- tip.attr = function (n, v) {
- if (arguments.length < 2 && typeof n === "string") {
- return d3.select(node).attr(n)
- } else {
- var args = Array.prototype.slice.call(arguments)
- d3.selection.prototype.attr.apply(d3.select(node), args)
- }
- return tip
- }
- // Public: Proxy style calls to the d3 tip container. Sets or gets a style value.
- //
- // n - name of the property
- // v - value of the property
- //
- // Returns tip or style property value
- tip.style = function (n, v) {
- if (arguments.length < 2 && typeof n === "string") {
- return d3.select(node).style(n)
- } else {
- var args = Array.prototype.slice.call(arguments)
- d3.selection.prototype.style.apply(d3.select(node), args)
- }
- return tip
- }
- // Public: Set or get the direction of the tooltip
- //
- // v - One of n(north), s(south), e(east), or w(west), nw(northwest),
- // sw(southwest), ne(northeast) or se(southeast)
- //
- // Returns tip or direction
- tip.direction = function (v) {
- if (!arguments.length) return direction
- direction = v == null ? v : d3.functor(v)
- return tip
- }
- // Public: Sets or gets the offset of the tip
- //
- // v - Array of [x, y] offset
- //
- // Returns offset or
- tip.offset = function (v) {
- if (!arguments.length) return offset
- offset = v == null ? v : d3.functor(v)
- return tip
- }
- // Public: sets or gets the html value of the tooltip
- //
- // v - String value of the tip
- //
- // Returns html value or tip
- tip.html = function (v) {
- if (!arguments.length) return html
- html = v == null ? v : d3.functor(v)
- return tip
- }
- function d3_tip_direction() {
- return "n"
- }
- function d3_tip_offset() {
- return [0, 0]
- }
- function d3_tip_html() {
- return " "
- }
- var direction_callbacks = d3.map({
- n: direction_n,
- s: direction_s,
- e: direction_e,
- w: direction_w,
- nw: direction_nw,
- ne: direction_ne,
- sw: direction_sw,
- se: direction_se
- }),
- directions = direction_callbacks.keys()
- function direction_n() {
- var bbox = getScreenBBox()
- return {
- top: bbox.n.y - node.offsetHeight,
- left: bbox.n.x - node.offsetWidth / 2
- }
- }
- function direction_s() {
- var bbox = getScreenBBox()
- return {
- top: bbox.s.y,
- left: bbox.s.x - node.offsetWidth / 2
- }
- }
- function direction_e() {
- var bbox = getScreenBBox()
- return {
- top: bbox.e.y - node.offsetHeight / 2,
- left: bbox.e.x
- }
- }
- function direction_w() {
- var bbox = getScreenBBox()
- return {
- top: bbox.w.y - node.offsetHeight / 2,
- left: bbox.w.x - node.offsetWidth
- }
- }
- function direction_nw() {
- var bbox = getScreenBBox()
- return {
- top: bbox.nw.y - node.offsetHeight,
- left: bbox.nw.x - node.offsetWidth
- }
- }
- function direction_ne() {
- var bbox = getScreenBBox()
- return {
- top: bbox.ne.y - node.offsetHeight,
- left: bbox.ne.x
- }
- }
- function direction_sw() {
- var bbox = getScreenBBox()
- return {
- top: bbox.sw.y,
- left: bbox.sw.x - node.offsetWidth
- }
- }
- function direction_se() {
- var bbox = getScreenBBox()
- return {
- top: bbox.se.y,
- left: bbox.e.x
- }
- }
- function initNode() {
- var node = d3.select(document.createElement("div"))
- node.style({
- position: "absolute",
- opacity: 0,
- pointerEvents: "none",
- boxSizing: "border-box"
- })
- return node.node()
- }
- function getSVGNode(el) {
- el = el.node()
- if (el != null) {
- if (el.tagName != null && el.tagName.toLowerCase() == "svg")
- return el
- return el.ownerSVGElement
- }
- }
- // Private - gets the screen coordinates of a shape
- //
- // Given a shape on the screen, will return an SVGPoint for the directions
- // n(north), s(south), e(east), w(west), ne(northeast), se(southeast), nw(northwest),
- // sw(southwest).
- //
- // +-+-+
- // | |
- // + +
- // | |
- // +-+-+
- //
- // Returns an Object {n, s, e, w, nw, sw, ne, se}
- function getScreenBBox() {
- var targetel = target || d3.event.target,
- bbox = {},
- matrix = targetel.getScreenCTM(),
- tbbox = targetel.getBBox(),
- width = tbbox.width,
- height = tbbox.height,
- x = tbbox.x,
- y = tbbox.y,
- scrollTop = document.documentElement.scrollTop || document.body.scrollTop,
- scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft
- point.x = x + scrollLeft
- point.y = y + scrollTop
- bbox.nw = point.matrixTransform(matrix)
- point.x += width
- bbox.ne = point.matrixTransform(matrix)
- point.y += height
- bbox.se = point.matrixTransform(matrix)
- point.x -= width
- bbox.sw = point.matrixTransform(matrix)
- point.y -= height / 2
- bbox.w = point.matrixTransform(matrix)
- point.x += width
- bbox.e = point.matrixTransform(matrix)
- point.x -= width / 2
- point.y -= height / 2
- bbox.n = point.matrixTransform(matrix)
- point.y += height
- bbox.s = point.matrixTransform(matrix)
- return bbox
- }
- return tip
- };
- d3.tip = tipBuilder;
|