Coder Social home page Coder Social logo

glavin001 / ember-c3 Goto Github PK

View Code? Open in Web Editor NEW
81.0 9.0 62.0 12.81 MB

:chart_with_upwards_trend: Ember addon library for C3, a D3-based reusable chart library.

Home Page: http://glavin001.github.io/ember-c3/

License: MIT License

JavaScript 79.08% HTML 2.97% SCSS 1.47% Handlebars 16.48%
chart javascript ember c3 d3

ember-c3's Introduction

Ember-C3

npm version Ember Observer Score Join the chat at https://gitter.im/Glavin001/ember-c3

Ember component library for C3, a D3-based reusable chart library.

See the demo here

Compatibility

  • Ember.js v3.13 or above
  • Ember CLI v3.24 or above
  • Node.js v12 or above
  • ember-auto-import >= 2 (BREAKING CHANGE!)
  • Embroider compatabile

Installation

ember install ember-c3

Usage

Component usage and properties are below. The code for these example charts and more is in the dummy app source code.


Combination
image
Timeseries
ember-c3-timeseries-4
Gauge Pie Donut
ember-c3-gauge-2 ember-c3-pie-1 ember-c3-donut-1

Basic

Where this.model is your C3 data and chart options:

<C3Chart @data={{this.model}} />

Advanced

See http://c3js.org/examples.html for examples of how to use C3.

Component Arguments

The arguments match the corresponding C3 options found in the C3 Documentation. As documented, most C3 settings (i.e. bar, axis, size, etc) can be included in the data object.

Arguments break out the settings to simplify chart configuration. Note: The chart type must be assigned in the chart data object.

Properties marked with an asterisk (*) will update the chart when the property changes. See examples in the dummy app.

Property Description Example
c3chart Assigns the generated C3 chart object to the passed property. Any C3 API method can be used with this property chart.hide("data1")
data* C3 data object. data is mutable after the chart is created
axis* C3 axis object. See C3 examples for combining with data object. Chart axis are mutable after the chart is created
bar Used to assign bar chart properties
pie Used to assign pie chart properties
donut Used to assign donut chart properties
gauge Used to assign gauge chart properties
line Used to assign line chart properties
area Used to assign area chart properties
point Used to assign data point properties
grid Used to show, hide and modify the graph grid. See docs
legend Show, hide and modify the legend position. See docs
tooltip Show, hide and modify the tooltip. See docs
subchart Show, hide and modify C3 sub charts. See docs
zoom Set C3 zoom features. See docs
size Control chart size. See docs size: {width: 640 }
padding Set padding around graph. See docs padding: { top: 20}
title Set chart title title: { text: "This is my chart" }
interaction Enable or disable interactions interaction: { enabled: false }
color* Used to assign color properties. Chart colors are mutable after chart creation
dtitle Dynamically change the chart title. See details below
transition Equivalent to transition.duration. Default duration is 350ms. Transition times less than 300ms may not render properly. Use chart.load() and .unload() if shorter times are required
unloadDataBeforeChange When set to true existing data will be unloaded before new data is loaded. Useful for pie and donut chart data changes. You can manually load/unload data using chart.load() and chart..unload()

dtitle

The dtitle property is used to dynamically change a chart's title. C3 doesn't natively support this without forcing a chart redraw which can cause side effects.

The title can be set by targeting the .c3-title class but that doesn't provide abstraction from C3's internals.

dtitle gives you some control over side effects using a parameter to control how the graph is refreshed. An object with the new title and a refresh parameter is used to indicate whether all properties should be refreshed or only the chart title.

Setting refresh to false will only refresh the title and ignore changes to the data, colors and axis properties. A short example is below. See the drill down example in the dummy app to see how dttile is used and potential side effects.

The chart's initial title is set using the title parameter.

<C3Chart
  @data={{this.graphData}}
  @title={{this.title}}
  @dtitle={{this.dtitle}}
/>

<button {{on 'click' this.changeTitle}}>Change Title</button>
import Controller from '@ember/controller';
import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking';

export default class ApplicationController extends Controller {
  @tracked title = { text: 'Coffee Brewing' };
  @tracked dtitle;

  get graphData() {
    return {
      columns: [
        ['Cold Brewed', 12],
        ['Drip', 67],
        ['French Press', 14],
        ['Iced', 38],
        ['Percolated', 64]
      ],
      type: 'pie'
    };
  }

  @action
  changeTitle() {
    this.dtitle = { text: 'Making coffee!', refresh: false };
  }
}

C3 Methods

If you assign a controller property to the c3chart property, you can use most of C3's api methods. Not all the methods have been tested.

{{! templates/application.hbs }}
<C3Chart @data={{this.baseData}} @c3chart={{this.chart}} />

<button {{on 'click' this.loadUS}}>US Cars</button>
<button {{on 'click' this.loadGerman}}>German Cars</button>
<button {{on 'click' this.resetData}}>Reset</button>
// controllers/application.js
import { action } from '@ember/object';
import Controller from '@ember/controller';

export default class ApplicationController extends Controller {
  chart = null;

  baseData = {
    columns: [
      ['US', 64],
      ['German', 36]
    ],
    type: 'donut'
  };

  modelsGerman = [
    ['Mercedes', 12],
    ['Volkswagon', 54],
    ['BMW', 34]
  ];

  modelsUS = [
    ['Ford', 35],
    ['Chevy', 26],
    ['Tesla', 2],
    ['Buick', 10],
    ['Dodge', 27]
  ];

  @action
  resetData() {
    this.chart.load(this.baseData);
    this.chart.unload([
      'Mercedes',
      'Volkswagon',
      'BMW',
      'Ford',
      'Chevy',
      'Tesla',
      'Buick',
      'Dodge'
    ]);
  }

  @action
  loadUS() {
    this.chart.load({ columns: this.modelsUS });
    this.chart.unload('US', 'German');
  }

  @action
  loadGerman() {
    this.chart.load({ columns: this.modelsGerman });
    this.chart.unload('US', 'German');
  }
}

C3 Events

C3 emits two types of events - chart and data events. Chart events are assigned callback functions using component arguments.

Data events must be assigned to an action in the data object.

Chart events supported by ember-c3.

Events Description Example
oninit Triggered when chart is initialized @oninit={{this.init}}
onrendered Triggered when chart is rendered or redrawn @onrendered={{this.render}}
onmouseover Triggered when mouse enters the chart @onmouseover={{this.mouseover}}
onmouseout Triggered when mouse leaves the chart @onmouseout={{this.mouseout}}
onresize Triggered when screen is resized @onresize={{this.resize}}
onresized Triggered when resizing is completed @onresized={{this.resized}}

Callback functions will receive the C3 chart object which can be used to modify the chart or as data source for other operations. The @oninit event does not receive the chart object because the chart has not been created yet. See the chart events example can be used in the dummy app.

C3 data events such as onclick, onmouseover and onmouseout are assgined callback functions in the chart configuration or data settings. Data events supply the data names and values based on mouse location.

A data event example is shown below. Note that data callbacks require bind. See the dummy app for more examples.

{{! templates/application.hbs }}
<C3Chart @data={{this.data}} @oninit={{this.setup}} />
// controllers/application.js
import { action } from '@ember/object';
import Controller from '@ember/controller';
import { bind } from '@ember/runloop';

export default class ApplicationController extends Controller {
  get data() {
    // iris data from R
    return {
      columns: [
        ['data1', 30],
        ['data2', 120],
        ['data3', 10],
        ['data4', 45],
        ['data5', 90]
      ],
      type: 'pie',
      // override component onclick event handler
      // bind is required for data events
      onclick: bind(this, this.onClick)
    };
  }

  // oninit chart event
  @action
  setup() {
    console.log('chart inited');
  }

  // data event - triggered when pie slice is clicked
  onClick(data, elem) {
    alert(`Data ${data.name} has a value of ${data.value}`);
  }
}

Accessing D3

You can use the D3 library in your application by importing it where needed

import d3 from 'd3';

See the D3 example in the dummy app.

Helpful Links

See the Contributing guide for details.

License

This project is licensed under the MIT License.

ember-c3's People

Contributors

aaronrenner avatar andyo0729 avatar backspace avatar baltazore avatar benjaminrh avatar bravo-kernel avatar dipil-saud avatar ef4 avatar egeriis avatar frozenfire92 avatar glavin001 avatar jeff-phillips-18 avatar jsvg avatar justintocoding avatar maxwondercorn avatar potomak avatar raphaelgera avatar robdel12 avatar shingara avatar tehviking avatar wwilsman avatar yratanov avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ember-c3's Issues

How to use flush() and destroy()

How to use flush() and destroy() method in the ember c3 chart?
My chart is not refreshing based on the updated values.

Snippets

jsonData: computed('abc', function() { return { type: 'bar', labels: true, json: this.get('abc'), keys: { x: 'x-axis', value: ['totalABCs'] }, }),

this.get('abc') is dynamic values gets updates when new data load but charts not refreshing.

Please help and thanks in advance.

Fastboot support

When trying to use ember-c3 along Fastboot I get the following runtime error:

Error: Could not find module `d3` imported from `(require)`
    at missingModule (/Users/benoror/workspace/nimbox/tmp/broccoli_merge_trees-output_path-WSLosZ18.tmp/assets/vendor/loader/loader.js:219:1)
[...]

AFAIK the reason is that bower (requireJS) dependencies are deprecated.

Maybe is just a matter of using a shim like ember-d3 or ember-c3-shim ?

Data binding for params other than `data`

Hi @Glavin001, kudos for such a great addon ๐Ÿ˜„

I have a use case where I need data binding for the donut chart title:

screen shot 2016-04-05 at 11 48 14

similarly to the Gauge's example:

screen shot 2016-04-05 at 11 49 21

I infer that data binding is not triggered because only the data parameter is observed: https://github.com/Glavin001/ember-c3/blob/master/addon/components/c3-chart.js#L193, while Gauge's title is extracted from data parameter itself, Donut's title is not (donut param)

I'm somewhat new to Ember, maybe you can hint me if there's a workaround for this, or maybe I'd be happy to work on a PR for it.

Thanks in advance, cheers!

How can I make use of d3 functions when loading ember-c3?

Hello and thank you for this plugin.

I am trying to make use of d3.js functionality inside a controller but can't do it and don't want to install ember-d3 to avoid duplications. WIth a previous version of ember-c3 (0.3.1) I could normally use d3 functions inside a controller but now I can't.

Any ideas how to do this?

Axis not showing when LiquidFire is active

The main container of the app is loaded in a {{ liquid-outlet }} and I have a view which loads a C3 chart using ember-c3. The chart doesn't show the axis on load, but after clicking on one of the items on the legend the axis appear.

20160602-130824_capture

If I replace {{ liquid-outlet }} with {{ outlet }} everything works just fine, so I believe it's an issue with either how it is wrapped ( liquid-child within a liquid-container) or with the CSS used to style the wrappers. Just to be clear, I'm using LiquidFire to animate route transitions, not the chart itself or changes in data.

This is the main app template:

{{site-navbar}}

{{liquid-outlet}}

{{site-footer}}

The route template:

<div id="smart-chart" class="ui container">
  <h1 class="ui center aligned header">Driver Score</h1>
  {{ c3-chart data=model }}
</div>

And the route handler:

import Ember from "ember";

export default Ember.Route.extend( {
  model() {
    return {
      columns: [
        ['data1', 30, 20, 50, 40, 60, 50],
        ['data2', 200, 130, 90, 240, 130, 220],
        ['data3', 300, 200, 160, 400, 250, 250],
        ['data4', 200, 130, 90, 240, 130, 220],
        ['data5', 130, 120, 150, 140, 160, 150],
        ['data6', 90, 70, 20, 50, 60, 120],
      ],
      type: 'bar',
      types: {
        data3: 'spline',
        data4: 'line',
        data6: 'area',
      },
      groups: [
        ['data1', 'data2']
      ]
    };
  },
} );

Could not find module `c3`

Hello!

I'm currently having an issue while trying to upgrade from 0.2.3 to 0.3.1 where the c3 module cannot be found.

image

I have also reproduced this in a new Ember 2.10.1 project. Removing import c3 from 'c3'; from the addon stops the error from occurring and the charts start working. I think this is how 0.2.3 behaved as it didn't import the module either.

Is there something I'm missing or should the addon not import the c3 module directly? Will be happy to open a PR if that's the case.

Version number typo

For what it's worth, the version number in 0.1.5 in line number 4 of build/lib.js is 0.1.4 when it should be 0.1.5.

Ember.C3.VERSION = '0.1.4';

Bryan

Data with JSON type doesn't update with binding.

chartShouldLoadData: function() {
      var _this = this;
      var chart = this.get('chart');
      var currentIds = this.get('data.columns').mapBy('firstObject');
      var unloadIds = chart.data().mapBy('id').filter(function(id) {
        return currentIds.indexOf(id) < 0;
      });
      chart.load({columns: _this.get('data.columns'), unload: unloadIds});
    }.observes('data')

this.get('data') doesn't always have a columns property when the data is loaded in from JSON. Are JSON data types not supported by the components?

Publish new release

Would you mind publishing a new release on bower, would be nice to have the willDestroyElement hook setup. Thanks for the addon!

Removing a data-set from time-series graph.

When working with a single graph with dynamic content - how do you remove an existing line?

I'm working with a time-series graph with day intervals on the x axis. Over that period, you might be interested in a,b or c, but you won't necessarily want them on the graph at the same time.

If I update the 'data' object passed into the c3-chart, it is only an additive procedure - is there a method to remove a pre-rendered line?

Time Series NaN errors

Hello! I've been unable to get the c3 time series example working. The chart loads, but there are no data points or x-axis values, and many NaN errors in the console. Is my syntax wrong?

this in the .hbs

{{c3-chart
        data=model
        axis=axis
    }}

and this in the route

App.SensorsRoute = Ember.Route.extend({
    model: function() {
        return {

            x: 'x',
            columns: [
                ['x', '2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04', '2013-01-05', '2013-01-06'],
                ['data1', 30, 200, 100, 400, 150, 250],
                ['data2', 130, 340, 200, 500, 250, 350]
            ]

        };
    },
    axis: function() {
        return{

            x: {
                type: 'timeseries',
                tick: {
                    format: '%Y-%m-%d'
                }
            }

        };
    }
});

Thanks!

Upgrades are coming

This issue addresses upcoming changes to ember-c3 and opens a discussion on possible future features. It will also be used as a tracker.

Most of the items proposed are already in existing PRs or forks. This issue spells out the major changes that are mostly complete, in progress or planned. Please provide feedback. Help is welcome

  • Merge PRs #64 and #69
  • Move C3 from Bower to NPM - (pr #75)
  • Create a minimal set of tests (pr #79) - rendering tests
  • chart event tests (pr #82)
  • data event tests (pr #82)
  • Bump c3 to latest version (pr #79)
  • Upgrade ember to more current version. The current version is on 1.13, the latest LTS is now 3.4.
    PR #75 upgrades to version 3.1 and the fork is on 3.3. The preference would be 3.4 LTS which would work down to ember 2.4 (pr #79 - v3.3) (pr #83)
  • Expose the c3 chart as a component property. This would allow advanced use of c3 without adding a lot of additional properties to the component. In some instances, this may not be DDAU but creates a larger API for edge cases (fork)
  • Update the README/documentation to reflect changes and new component properties (pr #79)
  • Add additional examples of using c3. Many of the issues raised are how to do something in c3
    with the addon. In many cases, changing how data is presented to the component will make the graphs look or work differently. Most of the c3 documentation examples can already be done with the addon
  • Update gh-pages demo app with new dummy app. Change readme as needed to point to new exampes

After these changes are completed the remaining open PRs will be closed. Some of the features are included in other PRs or the PRs may no longer be needed. Updated and new PRs are welcome after the next version is published.

Issues that are resolved with the updates will be closed. Due to the age, most others will be closed with a note pointing to the new version(s) and they can resubmit if the issue still exists.

Future
This is a request for future ideas...

Building with grunt

Hi Galvin,

After building the app with grunt, the blank server instance opens on localhost:9002 in my browser. Any idea on how to get it displaying the graph on localhost:9002. Many thanks

P.S. I'm new to Yeoman-Bower-Grunt but very enthusiastic about it and eager to learn with a bit of help. Any suggestions on a very good tutorial?

dataDidChange fires twice

Hey @Glavin001, thanks for creating this library!

I noticed today that the dataDidChange method fires twice after initial render for all subsequent data attribute changes. It looks like you're registering the observer a second time in the didInsertElement method.

This has caused rendering issues with the C3 library because chart.load is invoked twice in quick succession.

What is the use case for notifying components of changes from the controller with 'notifyPropertyChange'? Couldn't we just pass in 'data' and trigger chart.load in a 'didReceiveAttrs' life cycle hook? I think a good fix for this bug would be to delete 'didInsertElement' entirely.

I have a bug demo repo set up here: https://github.com/andrewmtoy/ember-c3-bug-demo.

I believe that this pull request is solving this issue using the debouncer method.

Let me know what you think or if you'd like me to create pull request with these changes.

Thanks!
Andrew

very slow rendering

I'm using this addon to draw a timeseries chart consisting of 4 graphs (360 points each). The 360 y-values of each of the 4 graphs are computed based on other user input properties. The 4 graphs are independent of each other (e.g., a certain input-property change may cause only y-values of one of the graphs to change). In ember, I created 5 computed properties, one for the y-values of each graph, and the fifth computed property (named 'plotData') that depends on the other 4. The last computed property builds the entire 'data' structure needed by C3. I use the addon like this: {{c3-chart data='plotData'}}.

Because I'm changing 'plotData' every time one of the 4 computed properties change, I think C3 is re-rendering the entire chart every time, which may be causing the slowness. Is there anyway to get C3 to re-render only the graph that's changed?

C3 Chart Re-Render Issue.

C3 chart re-rendering while we switch browser tab reason being original bar color lost. Do we have any mechanism to prevent chart re-rendering either implicitly or explicitly?

Chart events not exposed - Feature request

As a C3 user/developer it would be nice to have the chart actions linked to the ember action chain. This would provide interaction with other components on the view eg:

A group selection on the chart could trigger a refresh of a table showing the data details.

This would involve catching the 'once' method callback in D3 and emitting it as an Ember action.

Thanks

Chris (expatriate Canadian in San Diego)

New release?

Any chance we could get a new release now that the handlebars dependency has been removed? I'm using rails-assets to get this library, and it doesn't allow specifying a commit.

State of the project?

I love this project but see that it hasn't been maintained for a while. @Glavin001 if you don't have the opportunity to maintain the project, I'd like to create a new project based on this one. Minimally, I would move it to the latest ember LTS and move from Bower to NPM for the C3 dependency.

Installing it manually (without bower)

I'm assuming if you want to install this manually you simply download the lib.js file located under the /lib/ folder? And then just include it with c3.js/c3.css files?

Unable to update axis labels

Hey, i've been struggling to update the axis labels of my chart.
I did notice that there is no observer for the axis labels, is this currently not possible?
Or am I just missing something entirely here?

Ember-CLI support?

Whenever you get back to working on this, i'd love to see ember-cli support for this.

Change chart style

Hey there , great package this one.

I've set it up and it's playing nicely , but i can't change the chart style , for instance make the dots disappear and such.

While everything renders nicely , colors and spcific types and such , the options given outside the data :{},... are not rendered :( any ideas ?

I even tried it with your example controllers, still nothing!

Thanks tons!

here's my controller:
https://gist.github.com/frcake/4746d54f17d2979527b24c1bc9185b52

Uncaught TypeError: Cannot read property 'getItem' of undefined

Hi there,
We are happily using c3 for our charting fun times, but every time we click on a bar chart we get that error. Unfortunately the c3 js is minified so we can't see why.
This happens in our charts ( bar and line ) and also in your demo charts ( bar and line ) as well, but you don't do anything on click ( just hover ) .. whereas we are trying to do something on click .. but this error is spoiling our fun at the moment.
Any ideas? Suggestions.

How to get underlying chart?

Wrapping this in a component and we need access to the underlying chart to do manipulation. this.get('chart') or this.get('c3chart') returns as undefined. Digging in to the code, I can't tell where the underlying c3 chart object is exposed as a property. Am I crazy?

Tag new version v0.1.6

Would you mind updating the tag on this project?

We need the action hooks in our project. It would be greatly appreciated.

Thanks for the work, this is a great addon.

Update to newest version of c3/d3

Hello,

I've seen it was an issue in the past, but is there a way to update to the latest d3/c3 libraries?

Even better, would it be able for us to upgrade on our own on-demand?

Thanks for your time!

How to transform chart type

First of all, this is a superb project. It is exactly what I've been looking for in my reporting app.

I'm wondering how I can transform a pie graph into a bar graph. I see that with C3, one calls chart.transform('bar'). Is there a way right now to do this in Ember-C3? I looked at the code but didn't see anything obvious.

I tried this in my Ember template, but it ends up showing two charts on top of or interlaced with each other after I change the controller properties cited below:

{{#if isChartTypeBar}}
  {{c3-chart data=contentChart legend=chartLegendSettings tooltip=chartTooltipFormat axis=chartCatAxisBar}}
{{/if}}
{{#if isChartTypePie}}
  {{c3-chart data=contentChart legend=chartLegendSettings tooltip=chartTooltipFormat pie=chartPieFormat}}
{{/if}}

Then I realized I could clean up my code, and I changed my template to have merely a single {{c3-chart ...}} object with all the proper component properties for every possible chart type, like this:

{{c3-chart
  data=contentChart
  axis=chartAxis
  bar=chartBarFormat
  pie=chartPieFormat
  legend=chartLegendSettings
  tooltip=chartTooltipFormat
}}

When I changed the "type" value within the "data" property in my controller. It still gave me a multiple charts piled on top of each other.

Any thoughts on this?

Bryan

Empty data causes other component blocking errors

If you have an empty data object passed you will get the following error

Uncaught Error: url or json or rows or columns is required. 

This error will block any other components from rendering properly

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.