Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scale rewrite for v2.0 #1132

Merged
merged 29 commits into from May 26, 2015
Merged

Conversation

etimberg
Copy link
Member

Overview

This update splits the scale code into separate x and y scales for the line, bar and scatter chart types. The line and bar charts use a "dataset" axis as their only x axis. The scatter chart allows arbitrary numbers of x and y axes.

I created a scale registration system. So far the following scale types are available: "linear", "dataset", and "radialLinear". The last axis type is used by the polar area and radar charts. The hope is that extensions can now provide axis types alone rather than new chart types as well. This means that it will be easier to expand Chart.js to use logarithmic axes.

I've also update the configuration to a more nested state with respect to the scales. More work is necessary to update the global defaults as well. I wrote a config merge function that can better handle nested data.

Sample Config

 var defaultConfig = {
        hoverMode: 'single',
        scales: {
            xAxes: [{
                scaleType: "linear", // scatter should not use a dataset axis
                display: true,
                position: "bottom",
                id: "x-axis-1", // need an ID so datasets can reference the scale

                // grid line settings
                gridLines: {
                    show: true,
                    color: "rgba(0, 0, 0, 0.05)",
                    lineWidth: 1,
                    drawOnChartArea: true, // if true, draw these grid lines on the chart area
                    drawTicks: true, // if true, draw these grid lines as ticks on the axis
                    zeroLineWidth: 1,
                    zeroLineColor: "rgba(0,0,0,0.25)",
                },

                // scale numbers
                beginAtZero: false,
                integersOnly: false,
                override: null,

                // label settings
                labels: {
                    show: true,
                    template: "<%=value%>",
                    fontSize: 12,
                    fontStyle: "normal",
                    fontColor: "#666",
                    fontFamily: "Helvetica Neue",
                },
            }],
            yAxes: [{
                scaleType: "linear", // only linear but allow scale type registration. This allows extensions to exist solely for log scale for instance
                display: true,
                position: "left",
                id: "y-axis-1",

                // grid line settings
                gridLines: {
                    show: true,
                    color: "rgba(0, 0, 0, 0.05)",
                    lineWidth: 1,
                    drawOnChartArea: true,
                    drawTicks: true, // draw ticks extending towards the label
                    zeroLineWidth: 1,
                    zeroLineColor: "rgba(0,0,0,0.25)",
                },

                // scale numbers
                beginAtZero: false,
                integersOnly: false,
                override: null,

                // label settings
                labels: {
                    show: true,
                    template: "<%=value%>",
                    fontSize: 12,
                    fontStyle: "normal",
                    fontColor: "#666",
                    fontFamily: "Helvetica Neue",
                }
            }],
        },

        //Number - Tension of the bezier curve between points
        tension: 0.4,

        //Number - Radius of each point dot in pixels
        pointRadius: 4,

        //Number - Pixel width of point dot border
        pointBorderWidth: 1,

        //Number - amount extra to add to the radius to cater for hit detection outside the drawn point
        pointHoverRadius: 20,

        //Number - Pixel width of dataset border
        borderWidth: 2,

        //String - A legend template
        legendTemplate: "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\"background-color:<%=datasets[i].borderColor%>\"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>",

        tooltipTemplate: "(<%= dataX %>, <%= dataY %>)",
        multiTooltipTemplate: "<%if (datasetLabel){%><%=datasetLabel%>: <%}%>(<%= dataX %>, <%= dataY %>)",

    };

Scale Constructor Registration

Extensions should register scale types in the following way.

Chart.scales.registerScaleType("my scale type name", MyScaleConstructor);

// The constructor can then be retrieved by doing the follwing
var scaleConstructor = Chart.scales.getScaleConstructor("my scale type name");

To use a new scale type, change the scale configuration as follows. The scatter chart will look up the corresponding constructor when building the scales.

scale: {
    scaleType: "my scale type name"
}

Linear Axis

The linear axis limit calculation has been redone to follow the nice number algorithm. http://stackoverflow.com/questions/8506881/nice-label-algorithm-for-charts-with-minimum-ticks

The scale config allows the user to provide a callback function that will determine the label for a given tick mark. The user provides this function as

labels: {
    show: true,
    template: "<%=value%>",
    fontSize: 12,
    fontStyle: "normal",
    fontColor: "#666",
    fontFamily: "Helvetica Neue",
    // tickValue {number} : the numerical value that a label is needed for
    // tickIndex {number} : the index of the tick in the internal ticks array
    // ticksArray {array} : the array of all ticks in the scale
    userCallback: function(tickValue, tickIndex, ticksArray) {
         return tickValue.toString();
    }
}

Zero Point Drawing

As can be seen in the scatter chart images below, the linear axis allows different draw settings for the line that represents the 0 points.

Resize Behaviour

During resizing, the linear chart will dynamically scale the number of ticks rather than rotating text.

Scatter Chart

The scatter chart uses a linear axis by default along the bottom. This axis may be moved to the top of the chart area by changing the position to "top" in the configuration. The data for a scatter chart is an object with two parameters x and y.

Single Y Axis

scatter merge single

Multiple Y Axes

scatter merge multi

Bar Charts

Bar charts also support multiple y axes. In this example, the red and dark blue traces are bound to the left axis while the cyan trace is bound to the right axis.
bar multi axis

Line Charts

Line charts also support multiple y axes.
line merge multi

Issues fixed

This PR should fix the following issues though testing is required and there may be bugs.

…tration. An initial implementation of a linear scale that can be drawn in both horizontal and vertical orientations.
… from the other charts. For now, the config is not changeable.
…f labels to show and as such do not need to rotate
…iguration has a different line colour for the 0 axis
…d merges smarter than simply replacing the default object. Tested by overriding the vertical axis 0 point colour. Also implemented dataset axis binding. If nothing is specified, the dataset is bound to the first x and y axis.
…he axes. This is useful when in a multi axis scenario so that the axis that does not draw grid lines does not have weird lines.
…tting the scales. Since each chart needed to know it's scales, there wasn't much point in registering them into the service. When we support overlapping charts, we can do something fancier
Conflicts:
	src/Chart.Core.js

Fixed the sample files & chart type initialize methods so that this.data does not get set to undefined.
…ultiple y axes. Added an example demonstrating this.
…scales since that was clearer and maintains backwards compatibility.
…hich will allow radialLogarithmic, etc in the future. Updated the polar area and radar charts to use the new scale config. The scales draw, but the points do not. This is no different than the current v2.0 branch
tannerlinsley added a commit that referenced this pull request May 26, 2015
@tannerlinsley tannerlinsley merged commit 48dd1cf into chartjs:v2.0-dev May 26, 2015
@etimberg etimberg deleted the feature/v2.0dev-xy branch June 16, 2015 22:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants