UNPKG

gethue

Version:

Hue is an Open source SQL Query Editor for Databases/Warehouses

222 lines (195 loc) 6.53 kB
// 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. import $ from 'jquery'; import d3v3 from 'd3v3'; import * as ko from 'knockout'; import HueColors from '../../../utils/hueColors'; import huePubSub from '../../../utils/huePubSub'; ko.bindingHandlers.partitionChart = { render: function (element, valueAccessor) { huePubSub.publish('charts.state'); const MIN_HEIGHT_FOR_TOOLTIP = 24; const _options = valueAccessor(); const _data = _options.transformer(valueAccessor().datum); const _w = $(element).width(), _h = 300, _x = d3v3.scale.linear().range([0, _w]), _y = d3v3.scale.linear().range([0, _h]); if ($(element).find('svg').length > 0) { $(element).find('svg').empty(); } const _tip = d3v3 .tip() .attr('class', 'd3-tip') .html(d => { if (d.depth === 0) { return _options.tooltip || ''; } else if (d.depth > 0 && d.depth < 2) { return d.name + ' (' + d.value + ')'; } else { return d.parent.name + ' - ' + d.name + ' (' + d.value + ')'; } }) .offset([-12, 0]); const _svg = $(element).find('svg.tip').length > 0 ? d3v3.select($(element).find('svg.tip')[0]) : d3v3.select($(element)[0]).append('svg'); _svg.attr('class', 'tip').style('height', '0px'); _svg.call(_tip); const _vis = $(element).find('svg').length > 0 ? d3v3.select($(element).find('svg')[0]) : d3v3.select($(element)[0]).append('svg'); _vis .attr('class', 'partitionChart') .style('width', _w + 'px') .style('height', _h + 'px') .attr('width', _w) .attr('height', _h); const _partition = d3v3.layout.partition().value(d => { return d.size; }); const g = _vis .selectAll('g') .data(_partition.nodes(_data)) .enter() .append('svg:g') .attr('transform', 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 || d.depth === 0 ) { _tip.attr('class', 'd3-tip').show(d); } if (typeof this.__data__.parent === 'undefined') { return; } d3v3.select(this).select('rect').classed('mouseover', true); }) .on('mouseout', function (d, i) { if ( element.querySelectorAll('rect')[i].getBBox().height < MIN_HEIGHT_FOR_TOOLTIP || d.depth === 0 ) { _tip.attr('class', 'd3-tip').show(d); _tip.hide(); } d3v3.select(this).select('rect').classed('mouseover', false); }); if (typeof _options.zoomable == 'undefined' || _options.zoomable) { g.on('click', click).on('dblclick', d => { if (typeof _options.onClick != 'undefined' && d.depth > 0) { huePubSub.publish('charts.state', { updating: true }); _options.onClick(d); } }); } else { g.on('click', d => { if (typeof _options.onClick != 'undefined' && d.depth > 0) { huePubSub.publish('charts.state', { updating: true }); _options.onClick(d); } }); } let _kx = _w / _data.dx, _ky = _h / 1; const _colors = [HueColors.cuiD3Scale('gray')[0]]; g.append('svg:rect') .attr('width', _data.dy * _kx) .attr('height', d => { return d.dx * _ky; }) .attr('class', d => { return d.children ? 'parent' : 'child'; }) .attr('stroke', () => { return HueColors.cuiD3Scale('gray')[3]; }) .attr('fill', d => { let _fill = _colors[d.depth] || _colors[_colors.length - 1]; if (d.obj && _options.fqs) { $.each(_options.fqs(), (cnt, item) => { $.each(item.filter(), (icnt, filter) => { if (JSON.stringify(filter.value()) === JSON.stringify(d.obj.fq_values)) { _fill = HueColors.cuiD3Scale('gray')[3]; } }); }); } return _fill; }); g.append('svg:text') .attr('transform', transform) .attr('dy', '.35em') .style('opacity', d => { return d.dx * _ky > 12 ? 1 : 0; }) .text(d => { if (d.depth < 2) { return d.name + ' (' + d.value + ')'; } else { return d.parent.name + ' - ' + d.name + ' (' + d.value + ')'; } }); d3v3.select(window).on('click', () => { 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]); const t = g .transition() .delay(250) .duration(d3v3.event.altKey ? 7500 : 750) .attr('transform', d => { return 'translate(' + _x(d.y) + ',' + _y(d.x) + ')'; }); t.select('rect') .attr('width', d.dy * _kx) .attr('height', d => { return d.dx * _ky; }); t.select('text') .attr('transform', transform) .style('opacity', d => { return d.dx * _ky > 12 ? 1 : 0; }); d3v3.event.stopPropagation(); } function transform(d) { return 'translate(8,' + (d.dx * _ky) / 2 + ')'; } if (_options.onComplete) { _options.onComplete(); } }, init: function (element, valueAccessor) { ko.bindingHandlers.partitionChart.render(element, valueAccessor); }, update: function (element, valueAccessor) { ko.bindingHandlers.partitionChart.render(element, valueAccessor); } };