简体   繁体   中英

Formatting Data for Ember Charts.

Im using ember-charts for an app to present multiple different charts from the same models. Ember-charts takes data formatted in a specific way; an array of objects like in the code below.
I have been using computed properties to format the data to ember-charts liking.
This works.
but given that there will be many charts, and that the way to format the data is quite similar, I'm unhappy with the amount of duplicated code and was wondering if anyone has a better way to format the data for ember-charts.
Im using Ember 2.4 and ember-cli-mirage right now to generate my models.

Controller:

import Ember from 'ember';

export default Ember.Controller.extend({
    sqByU: Ember.computed("model.[]", function() {
        let arr = [], model = this.get('model');
        model.content.map(function(item) {
            let d = item._data;
            arr.pushObjects([
                { "label": 'Manufacturing', "group": d.location, "value": d.manufacturing },
                { "label": 'Warehouse', "group": d.location, "value": d.warehouse },
                { "label": 'Research & Development', "group": d.location, "value": d.rAndD },
                { "label": 'Mechanical Support', "group": d.location, "value": d.mechSupport },
                { "label": 'Office', "group": d.location, "value": d.office }
            ]);
        });
        return arr;
    }),
    annualFacilityCost: Ember.computed("model.[]", function() {
        let arr = [], model = this.get('model');
        model.content.map(function(item) {
            let d = item._data;
            let facilCost = d.opexSpend/(d.manufacturing + d.warehouse + d.rAndD + d.mechSupport + d.office);
            arr.pushObjects([
                {"label": 'IFMA Benchmark', "group": d.location, "value": d.ifmaBenchmark },
                {"label": 'Facility Cost', "group": d.location, "value": facilCost }
            ]);
        });
        return arr;
    }),
});

Templates:

<div class="col-md-4">
    {{#box-reg title="Square Foot by Utilization"}}
        {{vertical-bar-chart maxBarThickness=100 selectedSeedColor="rgb(13,71,161)" stackBars=true data=sqByU }}
    {{/box-reg}}
</div>
<div class="col-md-4">
    {{#box-reg title="BSC Total Annual Facility Cost/SF"}}
        {{vertical-bar-chart maxBarThickness=100 selectedSeedColor="rgb(13,71,161)" data=annualFacilityCost }}
    {{/box-reg}}
</div>

So, given that controllers are on the way out I dont really want to be using them so what Ive come up with is this:

change the outer component:
templates/components/chart-wrapper.hbs

<div class="col-md-4">
    {{box-reg title="Title" model=model type="vertBar" data="sqByU" stackBars=true}}
</div>

Then add the inner component to the above components template:
templates/components/chart-comp.hbs

{{#if vertBar}}
    {{vertical-bar-chart maxBarThickness=100 selectedSeedColor="rgb(13,71,161)" stackBars=stackBars data=graphData }}
{{/if}}
{{#if pie}}
    {{pie-chart data=graphData sortKey="label" selectedSeedColor="rgb(41,98,255)" minSlicePercent=0 maxNumberOfSlices=15}}
{{/if}}

then in the component:
components/chart-wrapper.js

import Ember from 'ember';

export default Ember.Component.extend({
    classNames: "box",
    stackBars: false,
    graphData: Ember.computed("model.[]", function() {
        let model = this.get('model');
        let graph = this.get('data');
        let sqByU = [], annualFacilityCost = [], area;
        model.content.map(function(item) {
            let d = item._data;
            area = d.manufacturing + d.warehouse + d.rAndD + d.mechSupport + d.office;
            sqByU.pushObjects([
                { "label": 'Manufacturing', "group": d.location, "value": d.manufacturing },
                { "label": 'Warehouse', "group": d.location, "value": d.warehouse },
                { "label": 'Research & Development', "group": d.location, "value": d.rAndD },
                { "label": 'Mechanical Support', "group": d.location, "value": d.mechSupport },
                { "label": 'Office', "group": d.location, "value": d.office }
            ]);
            annualFacilityCost.pushObjects([
                {"label": 'IFMA Benchmark', "group": d.location, "value": d.ifmaBenchmark },
                {"label": 'Facility Cost', "group": d.location, "value": d.opexSpend/area }
            ]);
        });
        if (graph === "sqByU") { 
            return sqByU; 
        }
        if (graph === "annualFacilityCost") { 
            return annualFacilityCost; 
        }
    }),
    vertBar: Ember.computed('type', function(){
        return this.get('type') === 'vertBar';
    }),
    pie: Ember.computed('type', function(){
        return this.get('type') === 'pie';
    }),
});

so one solution that Ive moved to is to setupController in the `

import Ember from 'ember';

export default Ember.Route.extend({
    model() {
        return this.store.findAll('plant');
    },
    setupController: function(controller, model) {
        this._super(controller, model);
        let sqByU = [], annualFacilityCost = [], area;
        model.content.map(function(item) {
            let d = item._data;
            area = d.manufacturing + d.warehouse + d.rAndD + d.mechSupport + d.office;
            sqByU.pushObjects([
                { "label": 'Manufacturing', "group": d.location, "value": d.manufacturing },
                { "label": 'Warehouse', "group": d.location, "value": d.warehouse },
                { "label": 'Research & Development', "group": d.location, "value": d.rAndD },
                { "label": 'Mechanical Support', "group": d.location, "value": d.mechSupport },
                { "label": 'Office', "group": d.location, "value": d.office }
            ]);
            annualFacilityCost.pushObjects([
                {"label": 'IFMA Benchmark', "group": d.location, "value": d.ifmaBenchmark },
                {"label": 'Facility Cost', "group": d.location, "value": d.opexSpend/area }
            ]);
        });
        controller.set('sqByU', sqByU);
        controller.set('annualFacilityCost', annualFacilityCost);
    }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM