Search code examples
javascriptajaxchartszingchart

ZingChart X-axis labels showing as numbers instead of strings


I am using the ZingChart library to graph results from an API call. When I pass in a normal array for the "values" field of the chart data object, everything works fine. However, when I pass in an array made from Object.keys(titleSet) (where titleSet is a normal Javascript object), the graph displays as follows:

Example Chart

As you can see, the x-axis is now labeled with numbers instead of the array of strings. But when I print out the the result of Object.keys(titleSet) vs. passing in a normal array, they both appear to be the same in the console. Can anyone help me figure out what I'm doing wrong?

//List of movies inputted by the user
var movieList = [];
var movieSet = {};

var IMDBData = {
  "values": [], 
  "text": "IMDB",
};
var metascoreData = {
  "values": [], 
  "text": "Metascore"
};
var RTMData = {
  "values": [], 
  "text": "Rotten Tomatoes Meter"
};
var RTUData = {
  "values": [],
   "text": "Rotten Tomatoes User"
};

var chartData = { 
  "type":"bar",
  "legend":{
    "adjust-layout": true
  },
  "plotarea": {
    "adjust-layout":true
  },
  "plot":{ 
    "stacked": true,
    "border-radius": "1px",
    "tooltip": {
      "text": "Rated %v by %plot-text"
    },
    "animation":{
      "effect":"11",
      "method":"3",
      "sequence":"ANIMATION_BY_PLOT_AND_NODE",
      "speed":10
    } 
  },
  "scale-x": {
    "label":{ /* Scale Title */
      "text":"Movie Title",
    },
    "values": Object.keys(movieSet) /* Needs to be list of movie titles */
  },
  "scale-y": {
    "label":{ /* Scale Title */
      "text":"Total Score",
    }
  },
  "series":[metascoreData, IMDBData, RTUData, RTMData]
};


var callback = function(data)
{
  var resp = JSON.parse(data);

  movieSet[resp.Title] = true;

  //Render
  zingchart.render({ 
    id:'chartDiv',
    data:chartData,
  });
};

Solution

  • Full Disclosure, I'm a member of the ZingChart team.

    Thank you for updating your question. The problem is you have defined your variable movieSet before the variablechartData. When parsing the page, top down, it is executing Object.keys({}) on an empty object when creating the variable chartData. You should just directly assign it into your config later on chartData['scale-x']['values'] = Object.keys(moviSet).

    var callback = function(data)
    {
      var resp = JSON.parse(data);
    
      movieSet[resp.Title] = true;
    
      //Render
      zingchart.render({ 
        id:'chartDiv',
        data:chartData,
      });
    };
    

    There is a problem with the above code as well. It seems you are calling render on the chart every time you call this API. You should have one initial zingchart.render() and then from there on out use our API. I would suggest setdata method as it replaces a whole new JSON packet or modify method.

    I am making some assumptions on how you are handling data. Regardless, check out the following demo

    var movieValues = {};
    
    var myConfig = {
     	type: "bar", 
     	scaleX:{
     	  values:[]
     	},
    	series : [
    		{
    			values : [35,42,67,89,25,34,67,85]
    		}
    	]
    };
    
    zingchart.render({ 
    	id : 'myChart', 
    	data : myConfig, 
    	height: 300, 
    	width: '100%' 
    });
    
    var callback = function(data) {
      movieValues[data.title] = true;
      myConfig.scaleX.values = Object.keys(movieValues);
      zingchart.exec('myChart', 'setdata', {
        data:myConfig
      })
    }
    
    var index = 0;
    var movieNamesFromDB = ['Sausage Party', 'Animal House', 'Hot Rod', 'Blazing Saddles'];
    setInterval(function() {
      if (index < 4) {
        callback({title:movieNamesFromDB[index++]});
      }
    },1000)
    <!DOCTYPE html>
    <html>
    	<head>
    	<!--Assets will be injected here on compile. Use the assets button above-->
    		<script src= "https://cdn.zingchart.com/zingchart.min.js"></script>
    		<script> zingchart.MODULESDIR = "https://cdn.zingchart.com/modules/";
    </script>
    	<!--Inject End-->
    	</head>
    	<body>
    		<div id='myChart'></div>
    	</body>
    </html>

    If you noticed in the demo, the length of scaleX.values determines how many nodes are shown on the graph. If you change values to labels this wont happen.