Skip to content

Instantly share code, notes, and snippets.

@rousan
Last active November 10, 2017 06:37
Show Gist options
  • Save rousan/9380e370d763d597f234598182d5f374 to your computer and use it in GitHub Desktop.
Save rousan/9380e370d763d597f234598182d5f374 to your computer and use it in GitHub Desktop.
Interactive Charts using Vue-FusionCharts wrapper

VueJS is a progressive JavaScript framework for building user interfaces and FusionCharts provides a VueJS binding, so we can use this binding to render our interactive charts.

Including Interactivity Between Charts

Assume that you have a dashboard with a pie 2D and a column 2D chart to plot sales data for Harry’s retail and wholesale stores. The pie 2D chart plots collective sales for the retail and wholesale stores; the column 2D chart plots sales for individual stores. Harry wants his charts to be interactive in a way that when the Retail pie slice is clicked, the column 2D chart shows data for only all retail stores, and likewise for the wholesale stores.

The dashboard looks as shown below:

The complete code for this dashboard is given at the end of this article, after all steps have been explained.

Step 1: Preparing the data

The FusionCharts library currently accepts JSON and XML data only. As such, we need to convert data in a format accepted by the library. For this example, we will use JSON data.

var completeData = [
    {
        label: "Bakersfield Central",
        category: "Retail",
        value: "880000",
        city: "NYC"
    },
    {
        label: "Garden Groove harbour",
        category: "General",
        value: "730000",
        city: "London"
    },
    {
        label: "Los Angeles Topanga",
        value: "590000",
        category: "Retail",
        city: "NYC"
    },
    {
        label: "Compton-Rancho Dom",
        value: "520000",
        category: "Retail",
        city: "NYC"
    },
    {
        label: "Daly City Serramonte",
        value: "330000",
        category: "General",
        city: "Mumbai"
    }
];

/** Column Chart's 'dataSource' **/
var revenueChartDataSource = {
    chart: {
        caption: "Harry's SuperMart",
        subCaption: "Top 5 stores in last month by revenue",
        theme:"fint"
    },
    data: completeData
};

/** Pie Chart's 'dataSource' **/
var categoryChartDataSource = {
    chart: {
        caption: "Categories of Harry's SuperMart",
        theme:"fint",
        enablemultislicing: "0"
    },
    data: [
        {
            label: "General",
            value: 0
        },
        {
            label: "Retail",
            value: 0
        }
    ]
};

/** Building data for Pie Chart based on the category of the mart stores **/
for (var i = 0, len = completeData.length; i < len; i++) {
    if (completeData[i].category === "General") {
        categoryChartDataSource.data[0].value += 1;
    }
    else {
        categoryChartDataSource.data[1].value += 1;
    }
}

Step 2: Defining an Event’s Behavior for a Filter

Data plotted on the column chart should be filtered based on the pie slice clicked, as directed by the snippet below:

var revenueChartOptions = {
     /** FusionCharts Configs **/
};

function handleUserInput(filterValue) {
    if (filterValue.length !== 0) {
        const rows = [];
        completeData.forEach(function(mart) {
            if (mart.category === filterValue) {
                rows.push(mart);
            }
        });
        return rows;
    }
    else {
        return completeData;
    }
}

var categoryChartOptions = {

    /** FusionCharts Configs **/

    events: {

        /***
        ** Slicing event of Pie Chart
        ***/
        slicingStart: function (evtObj, argObj) {
            if (!argObj.slicedState) {
                revenueChartOptions.dataSource.data = handleUserInput(argObj.data.categoryLabel);
            } else {
                revenueChartOptions.dataSource.data = handleUserInput('');
            }
        }
    }
};

Step 3: Render the chart

The HTML code to create this chart is given below:

<div id="app">
    <fusioncharts
    :options="categoryChartOptions"
    ></fusioncharts>
    <br/>
    <br/>
    <fusioncharts
    :options="revenueChartOptions"
    ></fusioncharts>
</div>

The VueJS code for this chart is given below:

Vue.use(VueFusionCharts);

const app = new Vue({
    el: '#app',
    data: {
        revenueChartOptions: revenueChartOptions,
        categoryChartOptions: categoryChartOptions
    }
});

Example

Now, coming back to the dashboard example referred to in the beginning of the article. The complete code to render the dashboard is given below:

<div id="app">
    <fusioncharts
    :options="categoryChartOptions"
    ></fusioncharts>
    <br/>
    <br/>
    <fusioncharts
    :options="revenueChartOptions"
    ></fusioncharts>
</div>
/** Raw data **/
var completeData = [
    {
        label: "Bakersfield Central",
        category: "Retail",
        value: "880000",
        city: "NYC"
    },
    {
        label: "Garden Groove harbour",
        category: "General",
        value: "730000",
        city: "London"
    },
    {
        label: "Los Angeles Topanga",
        value: "590000",
        category: "Retail",
        city: "NYC"
    },
    {
        label: "Compton-Rancho Dom",
        value: "520000",
        category: "Retail",
        city: "NYC"
    },
    {
        label: "Daly City Serramonte",
        value: "330000",
        category: "General",
        city: "Mumbai"
    }
];

/** Column Chart's 'dataSource' **/
var revenueChartDataSource = {
    chart: {
        caption: "Harry's SuperMart",
        subCaption: "Top 5 stores in last month by revenue",
        theme:"fint"
    },
    data: completeData
};

/** Pie Chart's 'dataSource' **/
var categoryChartDataSource = {
    chart: {
        caption: "Categories of Harry's SuperMart",
        theme:"fint",
        enablemultislicing: "0"
    },
    data: [
        {
            label: "General",
            value: 0
        },
        {
            label: "Retail",
            value: 0
        }
    ]
};

/** Building data for Pie Chart based on the category of the mart stores **/
for (var i = 0, len = completeData.length; i < len; i++) {
    if (completeData[i].category === "General") {
        categoryChartDataSource.data[0].value += 1;
    }
    else {
        categoryChartDataSource.data[1].value += 1;
    }
}

var revenueChartOptions = {
    width: 500,
    height: 300,
    type: "column2d",
    dataFormat: "json",
    dataSource: revenueChartDataSource
};

function handleUserInput(filterValue) {
    if (filterValue.length !== 0) {
        const rows = [];
        completeData.forEach(function(mart) {
            if (mart.category === filterValue) {
                rows.push(mart);
            }
        });
        return rows;
    }
    else {
        return completeData;
    }
}

var categoryChartOptions = {
    width: 500,
    height: 300,
    type: "pie2d",
    dataFormat: "json",
    dataSource: categoryChartDataSource,
    
    events: {
        /** Slicing event of Pie Chart **/
        slicingStart: function (evtObj, argObj) {
            if (!argObj.slicedState) {
                revenueChartOptions.dataSource.data = handleUserInput(argObj.data.categoryLabel);
            }
            else {
                revenueChartOptions.dataSource.data = handleUserInput('');
            }
        }
    }
};


Vue.use(VueFusionCharts);

const app = new Vue({
    el: '#app',
    data: {
        revenueChartOptions: revenueChartOptions,
        categoryChartOptions: categoryChartOptions
    }
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment