I want to change the chart for each city or subcity selected
Asked Answered
C

2

5

I developed a simple application with AngularJS and I want to add a simple chart based on this website Js Charts

This is my data.json:

[
    {
        "name": "city A",
        "elements": [
            {
                "id": "c01",
                "name": "name1",
                "price": "15",
                "qte": "10"
            },
            {
                "id": "c02",
                "name": "name2",
                "price": "18",
                "qte": "11"
            },
            {
                "id": "c03",
                "name": "name3",
                "price": "11",
                "qte": "14"
            }
        ],
        "subsities": [
            {
                "name": "sub A1",
                "elements": [
                    {
                        "id": "sub01",
                        "name": "nameSub1",
                        "price": "1",
                        "qte": "14"
                    },
                    {
                        "id": "sub02",
                        "name": "nameSub2",
                        "price": "8",
                        "qte": "13"
                    },
                    {
                        "id": "sub03",
                        "name": "nameSub3",
                        "price": "1",
                        "qte": "14"
                    }
                ]
            },
            {
                "name": "sub A2",
                "elements": [
                    {
                        "id": "ssub01",
                        "name": "nameSsub1",
                        "price": "1",
                        "qte": "7"
                    },
                    {
                        "id": "ssub02",
                        "name": "nameSsub2",
                        "price": "8",
                        "qte": "1"
                    },
                    {
                        "id": "ssub03",
                        "name": "nameSsub3",
                        "price": "4",
                        "qte": "19"
                    }
                ]
            },
            {
                "name": "sub A3",
                "elements": [
                    {
                        "id": "sssub01",
                        "name": "nameSssub1",
                        "price": "1",
                        "qte": "11"
                    },
                    {
                        "id": "sssub02",
                        "name": "nameSssub2",
                        "price": "2",
                        "qte": "15"
                    },
                    {
                        "id": "sssub03",
                        "name": "nameSssub3",
                        "price": "1",
                        "qte": "15"
                    }
                ]
            }
        ]
    },
    {
        "name": "city B",
        "elements": [
            {
                "id": "cc01",
                "name": "name11",
                "price": "10",
                "qte": "11"
            },
            {
                "id": "cc02",
                "name": "name22",
                "price": "14",
                "qte": "19"
            },
            {
                "id": "cc03",
                "name": "name33",
                "price": "11",
                "qte": "18"
            }
        ]
    },
    {
        "name": "city C",
        "elements": [
            {
                "id": "ccc01",
                "name": "name111",
                "price": "19",
                "qte": "12"
            },
            {
                "id": "ccc02",
                "name": "name222",
                "price": "18",
                "qte": "17"
            },
            {
                "id": "ccc03",
                "name": "name333",
                "price": "10",
                "qte": "5"
            }
        ]
    }
]

I call my data here.

 angular.module('app', [])
        .controller('MainController', ['$scope', '$http', function($scope, $http) {
            $http.get('js/controllers/data.json').then(function(response) {
                $scope.cities = response.data;
                $scope.selectedCity = $scope.cities[0];
                $scope.data = $scope.selectedCity.elements;
            });

            $scope.myJson = {
                "type": "line",
                "plotarea": {
                    "adjust-layout":true /* For automatic margin adjustment. */
                },
                "scale-x": {
                    "label": { /* Add a scale title with a label object. */
                        "text":"Above is an example of a category scale",
                    },
                /* Add your scale labels with a labels array. */
                    "labels":["name1","name2","name3"]
                },
                "series": [
                    {"values":[15,18,11]},//here the prices of city selected
                    {"values":[10,11,14]}//here the qte of city selected
                ]
            };

            $scope.extractSubsities = function(itemSelected) {
                if (itemSelected && itemSelected.elements) {
                    $scope.data = itemSelected.elements;
                }
            }
     }]);

index.html :

<body ng-controller="MainCtrl">
<select ng-model="selectedCity"  ng-change="extractSubsities(selectedCity)" ng-options="item as item.name for item in cities track by item.name" ng-init="selectedCity = cities[0];extractSubsities(selectedCity)">
</select>

<select ng-show="selectedCity.subsities" ng-model="selectedSubCity"  ng-change="extractSubsities(selectedSubCity)" ng-options="item2 as item2.name for item2 in selectedCity.subsities track by item2.name">
  <option style="" value=""></option>
</select>

<table>
  <tr ng-repeat="item3 in data track by item3.id">
    <td>{{ item3.id }}</td>
    <td>{{ item3.name }}</td>
    <td>{{ item3.price }}</td>
  </tr>
</table>

<zingchart id = "myChart" zc-json = "myJson" zc-height = 500 zc-width = 600 ></zingchart>
</body>

the result:

enter image description here

I want to extract from the the attribute name element's city

I want to change the chart for each city or subcity selected. For example if I select the subcity is sub A1 I need to get a chart like :

enter image description here

Please help me !

UPDATE :

I tried to use only one source file of data

[{
        "type": "line",
        "plotarea": {
            "adjust-layout": true
        },
        "scale-x": {
            "label": {
                "text": "échelle essence gazoile"
            },

            "labels": ["sub01", "sub02", "sub02"]
        },
        "series": [{
            "values": [1, 8, 1]
        }, {
            "values": [14, 13, 14]
        }],

        "name": "city A",
        "elements": [{
          "id": "c01",
          "name": "name1",
          "price": "15",
          "qte": "10"
        }, {
          "id": "c02",
          "name": "name2',
          "price": "18,
          "qte": "11"
        }, {
          "id": "c03",
          "name": "name3",
          "price": "11",
          "qte": "14"
        }],
        "subsities": [{
          "name": "sub A1",
          "elements": [{
            "id": "sub01",
            "name": "nameSub1",
            "price": "1",
            "qte": "14"
          }, {
            "id": "sub02",
            "name": "nameSub2",
            "price": "8",
            "qte": "13"
          }, {
            "id": "sub03",
            "name": "nameSub3",
            "price": "1",
            "qte": "14"
          }]
        }, {
          "name": "sub A2",
          "elements": [{
            "id": "ssub01",
            "name": "nameSsub1",
            "price": "1",
            "qte": "7"
          }, {
            "id": "ssub02",
            "name": "nameSsub2",
            "price": "8",
            "qte": "1"
          }, {
            "id": "ssub03",
            "name": "nameSsub3",
            "price": "4",
            "qte": "19"
          }]
        }, {
          "name": "sub A3",
          "elements": [{
            "id": "sssub01",
            "name": "nameSssub1",
            "price": "1",
            "qte": "11"
          }, {
            "id": "sssub02",
            "name": "nameSssub2",
            "price": "2",
            "qte": "15"
          }, {
            "id": "sssub03",
            "name": "nameSssub3",
            "price": "1",
            "qte": "15"
          }]
        }]
      }, {
        "name": "city B",
        "elements": [{
          "id": "cc01",
          "name": "name11",
          "price": "10",
          "qte": "11"
        }, {
          "id": "cc02",
          "name": "name22",
          "price": "14",
          "qte": "19"
        }, {
          "id": "cc03",
          "name": "name33",
          "price": "11",
          "qte": "18"
        }]
      }, {
        "name": "city C",
        "elements": [{
          "id": "ccc01",
          "name": "name111",
          "price": "19",
          "qte": "12"
        }, {
          "id": "ccc02",
          "name": "name222",
          "price": "18",
          "qte": "17"
        }, {
          "id": "ccc03",
          "name": "name333",
          "price": "10",
          "qte": "5"
        }]
      }];

I called my data here :

angular.module('app', []).controller('MainController', ['$scope', '$http', function($scope, $http) {

      $http.get('js/controllers/data.json').then(function(response) { 
      $scope.cities = response.data; 
      $scope.myJson=response.data;
      $scope.selectedCity = $scope.cities[0];
      $scope.data = $scope.selectedCity.elements;
  }, function(error) { console.log(error); });

  $scope.name = 'World';
  $scope.data;

  $scope.extractSubsities = function(itemSelected) {
    if(itemSelected && itemSelected.elements){
        $scope.data = itemSelected.elements;
    }

  }

 }]);

index.html :

<body ng-controller="MainCtrl">
<select ng-model="selectedCity"  ng-change="extractSubsities(selectedCity)" ng-options="item as item.name for item in cities track by item.name" ng-init="selectedCity = cities[0];extractSubsities(selectedCity)">
  </select>

      <select ng-show="selectedCity.subsities" ng-model="selectedSubCity"  ng-change="extractSubsities(selectedSubCity)" ng-options="item2 as item2.name for item2 in selectedCity.subsities track by item2.name">
       <option style="" value=""></option>
       </select>

      <table>
        <tr ng-repeat="item3 in data track by item3.id">
          <td>{{ item3.id }}</td>
          <td>{{ item3.name }}</td>
          <td>{{ item3.price }}</td>
        </tr>
          </table>
    </div>
 <zingchart id = "myChart" zc-json = "myJson" zc-height = 500 zc-width = 600 ></zingchart>
    </body>

But still doesn't work it couldn't load the chart

I have as an error :

TypeError: Cannot read property 'type' of undefined

UPDATE 2 :

I set this up in a plunkr: plnkr.

UPDATE 3

Please can you tell me how can I remove this Powered by ZingChart

enter image description here

Combustion answered 16/5, 2016 at 14:35 Comment(17)
And what the problem you have?Archerfish
I want to change the chart for each city or subcity selectedCombustion
@Archerfish please do you have any idea ?Combustion
first question: why you use $scope.myJson variable to display, but you modify $scope.data by $scope.extractSubsities function?Archerfish
@Archerfish you mean that I can move it into my data json and use only $scope.data instead of $scope.myJson ?!!Combustion
I mean that you need to use the same variable in both cases. If you can add the structure of your data that might help.Archerfish
Does it display the chart on the load? (if you could create jsfiddle - that might help)Archerfish
@Archerfish No it doesn't load it :(Combustion
I believe that in your json you have an array, but you need an objectArcherfish
Yes MaKCblMKo :(Combustion
you have a few different issues, I think, just in the way you are handling your data. You really should set this up in a plunkr. To get your chart to switch values, you need to do something like ng-click="myJson=item" in the tr tag or use ng-change if you want to use the dropdown.Landlubber
At first sight (haven't even read it all), you have a typo in "id": "c02", "name": "name2', "price": "18, "qte": "11" You are opening double quotes in name2, and closing with a single quote.Downbow
yes I fix it thanks @DownbowCombustion
@Archerfish I set this in a plnkr plnkr.co/edit/NLO0xqyy7L7DHM4onOtQ?p=previewCombustion
@Landlubber set this in a plnkr plnkr.co/edit/NLO0xqyy7L7DHM4onOtQ?p=previewCombustion
@Combustion The powered by ZingChart can be removed with a license key after purchasing the library for commercial use. Otherwise the library is free to use with the watermark. zingchart.com/buyNeutral
So i must buy it there is no why ok thanks for your answerCombustion
A
5

Well, If I understand you right then you need something following:

angular.module("myApp",['zingchart-angularjs'])
   .controller('MainController', ['$scope', '$http', function($scope, $http) {
      $scope.chartBase = {
        "type": "line",
        "plotarea": {
          "adjust-layout": true /* For automatic margin adjustment. */
        },
        "scale-x": {
          "label": { 
            "text": "Above is an example of a category scale" /* Add a scale title with a label object. */
          },
          "labels": ["name1", "name2", "name3"] /* Add your scale labels with a labels array. */
        },
        "series": [{
            "values": [15, 18, 11] //here the prices of city selected
          },{
            "values": [10, 11, 14] //here the qte of city selected
          }]
      };
      $scope.chartData = angular.copy($scope.chartBase);

      $http.get('data.json')
           .then(function(response) {
             $scope.cities = response.data; // save the request data
             $scope.selectedCity = $scope.cities[0]; // select the first one
             $scope.changeCity(); // update chart
            }, function(error) { console.log(error); });

      $scope.changeCity = function() {
        if($scope.selectedSubCity || $scope.selectedCity){ // if something has been selected
            $scope.data = ($scope.selectedSubCity || $scope.selectedCity).elements; // update elements field

            // initialize the array to be displayed in chart
            var labels = [];
            var price = {
              "values": []
            };
            var qte = {
              "values": []
            };

            // fill the arrays to be displayed from the selected city (sub city)
            angular.forEach($scope.data, function(item, index) {
              labels.push(item.name);
              price.values.push(item.price);
              qte.values.push(item.qte);
            });

            // put selected values to the field that is used to render the chart
            $scope.chartData["scale-x"].labels = labels;
            $scope.chartData.series = [ price, qte ];
        }
      }
   }]);

I modified a bit you controller (and html page). Here is an example - plunker.

The difficulties (as I can see) were in your data.json file. It has a weird structure. It combines the chart parameters and the data itself. (in my example I removed chart parameters from it and hardcoded them inside the controller. but it's not necessary).

Hope it will help.

Archerfish answered 17/5, 2016 at 20:7 Comment(6)
There is a small problem that a vertical line is not in order, if you see when you click on the city A the vertical line start with 15 , 18 , 11 , 10 and then 14 it doesn't keep the values in order. I need to have the values in order like 10, 11, 14, 15 and 18Combustion
@Combustion - The dataset is being being read as an array of strings rather than numeric values, e.g. ["10", "11", "14"] rather than [10,11,14]. I added a parseInt in the changeCity function : plnkr.co/edit/i3UPTW99RFRFZ8E6NuZq?p=previewNeutral
@Neutral you're amazing just I need to parse a Float one (parseFloat), thank you so muchCombustion
@Neutral please can you take a look at UPDATE 3Combustion
@Neutral Please take a look at this question maybe you have an idea #37376196Combustion
@Neutral Please take a look at this question maybe you have an idea #37376196Combustion
L
3

ZingChart wants you to give it values in arrays, or an array of arrays if you want to have it plot multiple lines in the chart. Your data is getting loaded correctly, so all you have to do is push the values you want into their respective arrays and pass that array of arrays to the chart.

I added ng-change="extractSubsities(selectedCity)" to your select box so that it will update the chart whenever you change the selection.

Then adding a simple forEach to your extractSubsities function to generate the arrays from the currently selected data gets you what I believe you are looking for.

$scope.extractSubsities = function(itemSelected) {
if(itemSelected && itemSelected.elements){
    $scope.data = itemSelected.elements;
    $scope.myData = itemSelected.elements
    console.log(itemSelected.elements)
    var price = []
    var qte = []
    itemSelected.elements.forEach(function(v) {
      price.push(v.price)
      qte.push(v.qte)
    })
    $scope.myData = [price, qte]
}

}

zingchart directive should look like this: <zingchart id = "myChart" zc-values = "myData" zc-height = 500 zc-width = 600 ></zingchart> Plunkr: Click here

Landlubber answered 17/5, 2016 at 20:11 Comment(8)
There is a small problem that a vertical line is not in order, if you see when you click on the city A the vertical line start with 15 , 18 , 11 , 10 and then 14 it doesn't keep the values in order. I need to have the values in order like 10, 11, 14, 15 and 18Combustion
OK, but that is just a matter of sorting the arrays - a very basic problem, to which I am confident stackoverflow has plenty of good answers to. Google would also get you an answer to that problem quickly. Your original post was regarding getting the chart working, which my answer does do.Landlubber
#1063507Landlubber
Can you please edit your answer and fix this in your Plunkr pleaseCombustion
No, sorry. Stack Overflow is for help, not a free code writing service. I already fixed the problem you asked for help with. A simple thing like sorting an array is something you need to learn to do if you are writing JavaScript. I even provided you the link above. It's worth the 10 minutes it takes to research and learn how to do it. I addressed the problem you asked about. You should accept the answer.Landlubber
I will try to understand it and then back to you @LandlubberCombustion
The dataset is being being read as an array of strings rather than numeric values, e.g. ["10", "11", "14"] rather than [10,11,14]. ZingChart is treating the values as strings rather than the desired numeric values. Sorting is not the issue.Neutral
@Neutral ZingChart is treating them as strings because they are strings in the dataset. He desires them to be sorted ascending, so he would need to do that. If the numbers are in fact strings in the dataset, he can simply convert it with the Number() method as they are pushed into the array, and then run a-b sort on that.Landlubber

© 2022 - 2024 — McMap. All rights reserved.