Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #
- # This file overloads the ChartJS tooltip because we need more customizability.
- #
- # Note: At the current time it only supports the Pie / Doughnut chart.
- # Note: You are responsible for creating the CSS yourself.
- #
- # @see http://stackoverflow.com/questions/32703404/custom-data-in-label-on-chartjs-pie-chart?noredirect=1
- #
- class ChartJsCustomTooltip
- # The unique ID of this item.
- id: null
- # The tooltip container we're working with.
- tooltip: null
- # The HTML we'll inject into the tooltip. Note that it MUST contain this container div with its ID, or this class
- # won't be able to identify it. Aside from that, fill the container with whatever HTML you need. and use strings in
- # curly braces for replacements. Unidentifiable replaces will be ignored and printed as written in the supplied HTML
- # string.
- html: "<div class='customTooltip' style='display: none;' id='customTooltipContainer_{_id}'></div>"
- # The canvas element on which the chart we are working with is rendered.
- canvasElement: null
- # The ChartJS object we're working with.
- chartElement: null
- # The ChartJS data object from which we'll attempt to find values.
- data: null
- # Sets the HTML we'll be working with.
- # Use curly braces for replaces, i.e. "{label}" will be replaced with the "label" value from @data.
- # replaces starting with an underscore (e.g. "{_id}" are internal ones for this class.
- setHtml: (html) ->
- @html = html
- # As long as myChart.getSegmentsAtEvent() does not return all keys from dataset, we can search an specif dataset
- # entry by "value" and "value" keys. In fact, you could provide an unique ID so it would be a lot easier to
- # implement (findById(id, dataset)), because you could to search by ID, instead of label/value keys together.
- findEntryByLabelAndValue: (label, value) ->
- for item in @data
- return item if item.label is label and item.value is value
- return null
- # Creates an element that we can work with.
- createElement: (e) ->
- segmentData = @chartElement.getSegmentsAtEvent e
- return if not segmentData[0]?
- html = @html
- data = @findEntryByLabelAndValue segmentData[0].label, segmentData[0].value
- matches = html.match /\{[^\}]+\}/g
- for match in matches
- # Remove curly braces to get the actual value.
- matchValue = match.substr 1, match.length - 2
- if data[matchValue]?
- html = html.replace match, data[matchValue]
- html = html.replace '{_id}', @id
- $el = $(html)
- @tooltip = $el
- css = {
- position: "absolute"
- # Fix positioning.
- top: (event.clientY + ($el.outerHeight(true) / 3)) + "px"
- left: (event.clientX - ($el.outerWidth(true) / 2)) + "px"
- }
- $el.css(css).show() # @todo Animate?
- # If we haven't already created the element in the DOM, do so.
- existingElement = $("body").find("#customTooltipContainer_" + @id)
- if existingElement.length is 1
- existingElement.replaceWith $el
- else
- $("body").append $el
- # Displays the custom tool tip.
- displayCustomTooltip: (e) ->
- # @todo Just display data here? What about if the data changes?
- @createElement e
- # Attaches the events displaying and hiding the tooltip when moving the mouse.
- attachEvents: ->
- @canvasElement.on "mousemove", (e) =>
- @displayCustomTooltip e
- @canvasElement.on "mouseout", (e) =>
- @tooltip.hide()
- # Constructor.
- constructor: (canvasElement, chartElement, data) ->
- @canvasElement = canvasElement
- @chartElement = chartElement
- @data = data
- @id = (new Date()).getTime()
- @attachEvents()
Advertisement
Add Comment
Please, Sign In to add comment