/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF 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 Ember from 'ember'; export default Ember.Component.extend({ data: [], xAxisTickFormatter: null, yAxisTickFormatter: null, xAxisText: '', yAxisText: '', enableTooltip: true, onBarChartClickCallback: Ember.K, hideTootlipOnBarChartClick: true, initChart() { this.height = 400; this.barWidth = 30; this.width = Math.max(500, 40 * this.data.length); }, drawChart() { var margin = {top: 20, right: 20, bottom: 100, left: 100}, axisLabelPadding = 10, width = this.width - margin.left - margin.right - axisLabelPadding, height = this.height - margin.top - margin.bottom - axisLabelPadding, xAxisText = this.xAxisText? this.xAxisText : '', yAxisText = this.yAxisText? this.yAxisText : '', data = this.data, self = this; var xScale = d3.scale.ordinal().rangeRoundBands([0, width], 0.1); var yScale = d3.scale.linear().range([height, 0]); var xAxis = d3.svg.axis() .scale(xScale) .orient("bottom") .tickFormat(function(tick) { if (self.isFunction(self.xAxisTickFormatter)) { return self.xAxisTickFormatter(tick); } else { return tick; } }); var yAxis = d3.svg.axis() .scale(yScale) .orient("left") .tickFormat(function(tick) { if (self.isFunction(self.yAxisTickFormatter)) { return self.yAxisTickFormatter(tick); } else { return tick; } }); var svg = d3.select(this.element) .append("svg") .attr("class", "simple-bar-chart") .attr("width", width + margin.left + margin.right + axisLabelPadding) .attr("height", height + margin.top + margin.bottom + axisLabelPadding) .append("g") .attr("transform", "translate("+(margin.left+axisLabelPadding)+","+(margin.top)+")"); xScale.domain(data.map(function(d) { return d.label; })); yScale.domain([0, d3.max(data, function(d) { return d.value; })]); var gx = svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis); gx.selectAll("text") .style("text-anchor", "end") .attr("dx", "-.8em") .attr("dy", "-.3em") .attr("transform", "rotate(-60)"); gx.append("text") .attr("transform", "translate("+(width/2)+","+(margin.bottom)+")") .style("text-anchor", "middle") .text(xAxisText); var gy = svg.append("g") .attr("class", "y axis") .call(yAxis); gy.append("text") .attr("transform", "translate("+(-margin.left)+","+(height/2)+")rotate(-90)") .style("text-anchor", "middle") .text(yAxisText); var barWidth = this.barWidth; var minBarWidth = Math.min(barWidth, xScale.rangeBand()); var bars = svg.selectAll("bar") .data(data) .enter().append("rect") .attr("x", function(d) { var padding = 0; var rangeBand = xScale.rangeBand(); if ((rangeBand - barWidth) > 0) { padding = (rangeBand - barWidth) / 2; } return xScale(d.label) + padding; }) .attr("width", minBarWidth) .attr("y", function() { return yScale(0); }) .attr("height", function() { return height - yScale(0); }) .on('click', function(d) { if (self.enableTooltip && self.hideTootlipOnBarChartClick) { self.hideTootlip(); } if (self.isFunction(self.onBarChartClickCallback)) { self.onBarChartClickCallback(d); } }); bars.transition() .duration(1000) .delay(100) .attr("y", function(d) { return yScale(d.value); }) .attr("height", function(d) { return height - yScale(d.value); }); if (this.enableTooltip) { this.bindTooltip(bars); } }, bindTooltip(bars) { var self = this; var tooltip = this.tooltip; if (tooltip) { bars.on("mouseenter", function(d) { tooltip.html(d.tooltip); self.showTooltip(); }).on("mousemove", function() { tooltip.style("left", (d3.event.pageX + 5) + "px") .style("top", (d3.event.pageY - 25) + "px"); }).on("mouseout", function() { self.hideTootlip(); }); } }, initTooltip() { this.tooltip = d3.select("body") .append("div") .attr("class", "tooltip simple-barchart-tooltip") .style("opacity", 1); this.hideTootlip(); }, hideTootlip() { if (this.tooltip) { this.tooltip.style("display", "none"); } }, showTooltip() { if (this.tooltip) { this.tooltip.style("display", "block"); } }, isFunction(func) { return Ember.typeOf(func) === "function"; }, didInsertElement() { this.initChart(); if (this.enableTooltip) { this.initTooltip(); } this.drawChart(); }, willDestroyElement() { if (this.tooltip) { this.tooltip.remove(); } } });