Horizontal Bar Chart

A simple horizontal bar chart

main
run-button
run-button
reset-button
loadData('/static/cars.json').then((data) => {
  	// The schema for the data
  	const schema = [
        { name: 'Name', type: 'dimension' },
        { name: 'Maker', type: 'dimension' },
        { name: 'Miles_per_Gallon', type: 'measure', defAggFn: 'max' },
        { name: 'Displacement', type: 'measure', defAggFn: 'max' },
        { name: 'Horsepower', type: 'measure', defAggFn: 'avg' },
        { name: 'Weight_in_lbs', type: 'measure', defAggFn: 'min' },
        { name: 'Acceleration', type: 'measure', defAggFn: 'avg' },
        { name: 'Origin', type: 'dimension' },
        { name: 'Cylinders', type: 'dimension' },
        { name: 'Year', type: 'dimension' },
    ];
    
    const DataModel = muze.DataModel;     
    
  	// Create a new DataModel instance with data and schema
  	let dm = new DataModel(data, schema);
  	// Perform the groupBy operation followed by binning. This is performed from outside as groupBy needs to happen before sorting.
  	dm = dm.groupBy(['Year']).sort([["Acceleration", 'ASC']]);
  
  	// Define a custom mark named 'labeledBar'. There are two labels, one from the dimension plotted in y axis another one from the bar length.
  	muze.layerFactory.composeLayers('labeledBar', [
      	{ // Draws the bar layer
            name: 'simplebar',
            mark: 'bar',
            encoding: {
                x: 'labeledBar.encoding.x',
                y: 'labeledBar.encoding.y',
                color: 'labeledBar.encoding.color',
            }
        },
      	{ // Layer for drawing the axis lables on the left hand side
            mark: 'text',
            interactive: false,
            encoding: {
                x: 'labeledBar.encoding.x',
                y: 'labeledBar.encoding.y',
                text: 'labeledBar.encoding.axisText',
            },
            encodingTransform: (points, layer, dependencies) => { // after the plots physical dimensions are resolved, encoding transform is used to
                // further change the points
              const barHeight = layer.axes().y.getUnitWidth();

                let pad = 0;
                for (let i = 0; i < points.length; i++) {
                    let updateAttrs = points[i].update;
                    let textSize = dependencies.smartLabel.getOriSize(points[i].text);
                    updateAttrs.x = textSize.width / 2 + 5;
					updateAttrs.y +=  barHeight/2 - textSize.height/2 + 1;
                  //  updateAttrs['alignment-baseline'] = 'middle';
					points[i].color = '#fff';
                }
                return points;
            }
    	},
      	{ // Layer for drawing the values of bars on the right hand side
            mark: 'text',
            interactive: false,
            encoding: {
                x: 'labeledBar.encoding.x',
                y: 'labeledBar.encoding.y',
                text: {
                  field: 'labeledBar.encoding.valueText.field',
                  formatter: (value) => value.toFixed(2)
                }
            },
         	encodingTransform: (points, layer, dependencies) => {// after the plots physical dimensions are resolved, encoding transform is used to
                // further change the points
               const barHeight = layer.axes().y.getUnitWidth();
                let pad = 0;
                for (let i = 0; i < points.length; i++) {
            		let updateAttrs = points[i].update;
                    let textSize = dependencies.smartLabel.getOriSize(points[i].text);
                    updateAttrs.x += textSize.width / 2 + 5;
					updateAttrs.y +=  barHeight/2 - textSize.height/2 + 1;
                //    updateAttrs['alignment-baseline'] = 'middle';
					points[i].color = '#000';
                }
                return points;
            }
        }
    ]);
  
  	// Create a global environment to share common configs across charts
  	const env = muze();
  	// Create a canvas from the global environment
  	const canvas = env.canvas();
	canvas
    	.data(dm)
		.rows(["Year"]) // Year goes in y-axis
      	.columns(['Acceleration']) // Acceleration goes in x-axis
  		.config({
    		axes: { // Dont show the y axis as we are showing the labels on the bars itself
            	y: {
                	show: false
                }
            },
      		border: { // Hide the layout borders for better visibility
            	showValueBorders: {
            		left: false,
              		bottom: false
            	}
            }
    	})
  		.layers([{
            mark: 'labeledBar', // Use that custom mark to pass encoding values
            encoding: {
            	axisText: {
                    field: 'Year'
                },
              	valueText: {
                	field: 'Acceleration'
                }
            }

        }])
      	.width(800)
  	  	.height(500)
  		.title('Bar chart with axis labels inside the plot area', { position: 'top', align: 'center' })
  		.subtitle('Acceleration vs Year', { position: 'top', align: 'center' })
      	.mount('#chart-container') // Set the chart mount point
});