Visualforce 图表

Visualforce 图表是一组组件,它们提供了一种简单直观的创建方式 Visualforce 页面中的图表和 自定义组件。

什么是 Visualforce Charting?

Visualforce 图表为您提供了一种简单的方法 根据您直接从 SOQL 查询创建的数据集创建自定义业务图表, 或者通过在您自己的 Apex 代码中构建数据集。通过组合和配置单个数据 系列中,您可以编写图表,以对您有意义的方式显示您的数据 组织。

呈现 Visualforce 图表 使用 JavaScript 的客户端。这允许图表是动画的和视觉上令人兴奋的,并且图表 数据可以异步加载和重新加载,这可以使页面感觉更灵敏。

为什么要使用 Visualforce Charting?

使用 Visualforce 图表时 标准 Salesforce 图表和仪表板 是不够的,或者当您希望编写组合图表和数据表的自定义页面时 以对组织更有用的方式。

Visualforce Charting 的替代品

Salesforce 提供了许多 仪表板和报表,支持各种业务图表。这些图表可以更简单 进行创建和自定义,因为它们不需要在 Visualforce 或 Apex 中编程。

Visualforce 图表旨在 灵活,但也易于使用。它通常提供条形图、折线图、面积图和饼图的变化 用于商业图形,以及雷达图、仪表图和散点图,以实现更专业 制图。如果您需要不同的图表类型,或者想要添加高级用户或页面交互, 您可能希望改用 JavaScript 图表库进行调查。这是更多的工作, 但允许更大的定制。例如,请参阅集成 Visualforce 和 Google Charts。在 Visualforce 页面中使用 JavaScript 提供了有关如何在 Visualforce 中使用 JavaScript 库的更多信息。

Visualforce 图表限制和 考虑

本部分列出了 Visualforce Charting 的注意事项和已知限制。

  • Visualforce 图表仅在 支持可缩放矢量图形 (SVG) 的浏览器。有关详细信息,请参阅 WC3 SVG 工作 组。
  • Visualforce 图表使用 JavaScript 绘制图表。Visualforce 图表不会显示在呈现为 PDF 的页面中。
  • 电子邮件客户端通常不支持在邮件中执行 JavaScript。不要在电子邮件中使用 Visualforce 图表,或者 电子邮件模板。
  • Visualforce 图表发送错误和 消息发送到 JavaScript 控制台。使 JavaScript 调试工具(如 Firebug)保持活动状态 在开发过程中。
  • 目前不支持动态(顶点生成的)图表组件。

Visualforce Charting 的工作原理

定义了 Visualforce 图表 使用一系列图表组件,然后将这些组件链接到要在 图表。使用 Visualforce 创建图表 以下内容:

  1. 编写一个 Apex 方法,用于查询、计算和包装图表数据以发送到 浏览器。
  2. 使用 Visualforce 图表组件定义图表。

当包含图表的页面加载时,图表数据绑定到图表组件,并且 生成绘制图表的 JavaScript。当 JavaScript 执行时,图表会被绘制进去 浏览器。

一个简单的图表示例

Visualforce 图表要求您创建一个图表容器组件,该组件 包含至少一个数据系列组件。您可以选择添加 附加系列组件、图表轴以及标签组件 例如图例、图表标签和数据点的工具提示。下面是一个简单的饼图和创建它的标记:

<apex:page controller="PieChartController" title="Pie Chart">
    <apex:chart height="350" width="450" data="{!pieData}">
        <apex:pieSeries dataField="data" labelField="name"/>
        <apex:legend position="right"/>
    </apex:chart>
</apex:page>

组件 定义图表容器,并将组件绑定到数据源, 控制器 方法。描述要在返回的数据中访问的标签和数据字段, 标记每个数据点并调整其大小。<apex:chart>getPieData()<apex:pieSeries>下面是关联的控制器:

public class PieChartController {
    public List<PieWedgeData> getPieData() {
        List<PieWedgeData> data = new List<PieWedgeData>();
        data.add(new PieWedgeData('Jan', 30));
        data.add(new PieWedgeData('Feb', 15));
        data.add(new PieWedgeData('Mar', 10));
        data.add(new PieWedgeData('Apr', 20));
        data.add(new PieWedgeData('May', 20));
        data.add(new PieWedgeData('Jun', 5));
        return data;
    }

    // Wrapper class
    public class PieWedgeData {

        public String name { get; set; }
        public Integer data { get; set; }

        public PieWedgeData(String name, Integer data) {
            this.name = name;
            this.data = data;
        }
    }
}

这个控制器刻意简单;你通常 发出一个或多个 SOQL 查询以收集数据。以下是示例所说明的要点:

  • 方法 返回简单对象的 List,使用的内部类 PieWedgeData 作为包装器。列表中的每个元素都用于创建数据点。getPieData()
  • PieWedgeData 类只是一组属性,本质上是 用作 name= store。value
  • 图表系列组件定义 PieWedgeData 类中用于确定的属性 系列中的每一点。在这个简单的例子中,没有 神秘,但在具有多个系列和轴的图表中,此约定 允许在一个 List 对象中高效返回整个数据集。<apex:pieSeries>

提供图表数据

Visualforce 图表通过 data 属性绑定到其数据源 在组件上。

<apex:chart>可以通过几种不同的方式提供数据:

  • 作为表示 控制器方法参考
  • 作为表示 JavaScript 函数
  • 作为表示 JavaScript 数组

通过控制器方法提供图表数据

向图表提供数据的最直接方法是使用 Visualforce 表达式,该表达式 引用控制器方法。只需在属性中引用控制器即可。

<apex:chart>data

在服务器端,编写一个返回对象列表的控制器方法,该方法可以 是您自己的 Apex 包装器对象,如简单图表示例、sObject 或对象中所示。该方法在服务器端进行评估,并将结果序列化为 JSON。在 客户端,这些结果由 直接使用 ,没有进一步的处理机会。AggregateResult<apex:chart>

为了用 sObjects 来说明这种技术,这里有一个简单的控制器,它返回一个 商机列表,以及其金额的条形图:

public class OppsController {
    
    // Get a set of Opportunities
    public ApexPages.StandardSetController setCon {
        get {
            if(setCon == null) {
                setCon = new ApexPages.StandardSetController(Database.getQueryLocator(
                      [SELECT name, type, amount, closedate FROM Opportunity]));
                setCon.setPageSize(5);
            }
            return setCon;
        }
        set;
    }
    
    public List<Opportunity> getOpportunities() {
         return (List<Opportunity>) setCon.getRecords();
    }
}
<apex:page controller="OppsController">
    <apex:chart data="{!Opportunities}" width="600" height="400">
        <apex:axis type="Category" position="left" fields="Name" title="Opportunities"/>
        <apex:axis type="Numeric" position="bottom" fields="Amount" title="Amount"/>
        <apex:barSeries orientation="horizontal" axis="bottom" 
            xField="Name" yField="Amount"/>
    </apex:chart>
    <apex:dataTable value="{!Opportunities}" var="opp">
        <apex:column headerValue="Opportunity" value="{!opp.name}"/>
        <apex:column headerValue="Amount" value="{!opp.amount}"/>
    </apex:dataTable>
</apex:page>

关于此示例,有两件重要事项需要注意:

  • Visualforce 图表 组件从 List of Opportunity sObjects 中访问数据属性 与简单图表示例中使用的简单 Data 对象相同。
  • 在 JavaScript 中,用作数据属性的对象字段名称区分大小写 而 Apex 和 Visualforce 中的字段名称是 区分大小写。请注意在轴和数据系列组件的 、 和 属性中使用精确的字段名称,或者 图表将静默失败。fieldsxFieldyField

使用 JavaScript 提供图表数据 功能

使用 JavaScript 远程处理或外部(非 Salesforce)访问数据 数据源,则为组件提供 JavaScript 函数的名称,该函数提供 数据。该 JavaScript 函数必须在 Visualforce 页面中定义或链接。

<apex:chart>

此函数有机会在之前操作结果 将其传递给 ,或执行其他用户界面或页面更新。<apex:chart>JavaScript 函数必须将回调函数作为参数, 并使用函数的数据结果对象调用回调。这 最简单的工作 JavaScript 函数如下所示:

<apex:page>
    <script>
    function getRemoteData(callback) {
       PieChartController.getRemotePieData(function(result, event) {
           if(event.status && result && result.constructor === Array) {
               callback(result);
           }
       });
    }
    </script>

    <apex:chart data="getRemoteData" ...></apex:chart>
</apex:page>

若要支持此图表,请将以下控制器方法添加到简单图表示例中定义的类:PieChartController

@RemoteAction
public static List<PieWedgeData> getRemotePieData() {
    List<PieWedgeData> data = new List<PieWedgeData>();
    data.add(new PieWedgeData('Jan', 30));
    data.add(new PieWedgeData('Feb', 15));
    data.add(new PieWedgeData('Mar', 10));
    data.add(new PieWedgeData('Apr', 20));
    data.add(new PieWedgeData('May', 20));
    data.add(new PieWedgeData('Jun',  5));
    return data;
}

通过 JavaScript 数组提供图表数据

您可以使用 Visualforce 使用非 Salesforce 数据绘制图表 sources,通过构建一个 JavaScript 数组,在页面中你自己的 JavaScript 代码中,以及 将该数组的名称提供给 。

<apex:chart>以下简单的代码对此进行了说明 技术:

<apex:page>
    <script>
    // Build the chart data array in JavaScript
    var dataArray = new Array();
    dataArray.push({'data1':33,'data2':66,'data3':80,'name':'Jan'});
    dataArray.push({'data1':33,'data2':66,'data3':80,'name':'Feb'});
    // ...
    </script>

    <apex:chart data="dataArray" ...></apex:chart>
</apex:page>

使用此技术时,如果您的数据来自非 Salesforce 源,则可能不会 根本不需要任何服务器端 Apex 代码。

图表数据格式

提供给 Visualforce 的数据 图表必须满足某些特定要求。数据集合中的每个元素都必须包含所有 组件中引用的字段 绑定到该数据源的层次结构。如果未提供所有字段,则客户端 抛出 JavaScript 错误,您可以在 JavaScript 控制台中查看该错误,例如 萤火虫。

<apex:chart>

Apex 方法提供的图表数据应为统一对象的列表。这些对象可以是 简单的包装器、sObject 或对象。 数据字段可以作为公共成员变量或属性进行访问。AggregateResult

JavaScript 方法提供的图表数据应该是数组的 JavaScript 数组。每个内部 数组表示记录或数据点。数据字段可作为名称:值对进行访问。 有关示例,请参阅通过 JavaScript 数组提供图表数据。

使用 Visualforce Charting 构建复杂图表

使用 Visualforce 图表将各种图表组件组装成一个复杂的图表组件 表示多组相关数据的图表。最终结果 可以非常复杂和引人注目。

图表控制器

后面的例子 在本主题中,请使用以下控制器,这是一个适度的扩展 控制器的简单图表示例。它包含更多数据,以及可以调用的方法 通过远程 JavaScript 调用:

public class ChartController {
    // Return a list of data points for a chart
    public List<Data> getData() {
        return ChartController.getChartData();
    }
    
    // Make the chart data available via JavaScript remoting
    @RemoteAction
    public static List<Data> getRemoteData() {
        return ChartController.getChartData();
    }

    // The actual chart data; needs to be static to be
    // called by a @RemoteAction method
    public static List<Data> getChartData() {
        List<Data> data = new List<Data>();
        data.add(new Data('Jan', 30, 90, 55));
        data.add(new Data('Feb', 44, 15, 65));
        data.add(new Data('Mar', 25, 32, 75));
        data.add(new Data('Apr', 74, 28, 85));
        data.add(new Data('May', 65, 51, 95));
        data.add(new Data('Jun', 33, 45, 99));
        data.add(new Data('Jul', 92, 82, 30));
        data.add(new Data('Aug', 87, 73, 45));
        data.add(new Data('Sep', 34, 65, 55));
        data.add(new Data('Oct', 78, 66, 56));
        data.add(new Data('Nov', 80, 67, 53));
        data.add(new Data('Dec', 17, 70, 70));
        return data;
    }
    
    // Wrapper class
    public class Data {
        public String name { get; set; }
        public Integer data1 { get; set; }
        public Integer data2 { get; set; }
        public Integer data3 { get; set; }
        public Data(String name, Integer data1, Integer data2, Integer data3) {
            this.name = name;
            this.data1 = data1;
            this.data2 = data2;
            this.data3 = data3;
        }
    }
}

注意

本主题的图表示例中未使用该方法,但 它说明了如何将数据生成方法重用 服务器端和 JavaScript 远程处理方法。@RemoteAction

创建一个简单的 折线图

这是一个简单的折线图,它绘制了以下图表之一 数据集中的三个数据系列,“Opportunity Closed-Won”, 在一个日历年内:

<apex:page controller="ChartController">
    <apex:chart height="400" width="700" data="{!data}">
    	  <apex:axis type="Numeric" position="left" fields="data1" 
            title="Opportunities Closed" grid="true"/>
    	  <apex:axis type="Category" position="bottom" fields="name" 
            title="Month of the Year">
    	</apex:axis>
    	<apex:lineSeries axis="left" fill="true" xField="name" yField="data1"
          markerType="cross" markerSize="4" markerFill="#FF0000"/>
   </apex:chart>
</apex:page>

关于此示例的注意事项:

  • 折线图和条形图要求您定义 的 X 轴和 Y 轴 图表。
  • 垂直轴在图表的左侧定义,并且 衡量当月完成的商机的美元金额。
  • 水平轴在图表底部定义,并且 表示日历年的月份。
  • 实际的折线图(即组件)绑定到特定轴。<apex:lineSeries>
  • 您可以使用许多标记属性来区分 图表中的每一条线。

添加第二个数据 系列

添加第二个数据序列,其单位为 测量很简单。在这里,“机会关闭-失去” 数据集将添加为第二行系列:

<apex:page controller="ChartController">
    <apex:chart height="400" width="700" data="{!data}">
    	  <apex:axis type="Numeric" position="left" fields="data1,data2" 
            title="Opportunities Closed" grid="true"/>
    	  <apex:axis type="Category" position="bottom" fields="name" 
            title="Month of the Year">
    	  </apex:axis>
    	  <apex:lineSeries axis="left" fill="true" xField="name" yField="data1"
        	  markerType="cross" markerSize="4" markerFill="#FF0000"/>
    	  <apex:lineSeries axis="left" xField="name" yField="data2" 
            markerType="circle" markerSize="4" markerFill="#8E35EF"/>
    </apex:chart>
</apex:page>

需要注意的重要一点是,fields 属性如何将 和 fields 绑定到垂直方向 该组件。这允许图表引擎确定适当的 轴的刻度和刻度线。data1data2<apex:axis>

添加条形图 带第二轴的系列

要添加另一个数据系列,但 根据一组不同的单位绘制图表,您需要添加第二个单位 立轴。以下示例显示了一个数据系列,“收入 按月“添加为条形图:

<apex:page controller="ChartController">
    <apex:chart height="400" width="700" data="{!data}">
    	  <apex:axis type="Numeric" position="left" fields="data1,data2" 
            title="Opportunities Closed" grid="true"/>
        <apex:axis type="Numeric" position="right" fields="data3" 
            title="Revenue (millions)"/>
    	  <apex:axis type="Category" position="bottom" fields="name" 
            title="Month of the Year"/>
    	  <apex:lineSeries axis="left" fill="true" xField="name" yField="data1"
        	  markerType="cross" markerSize="4" markerFill="#FF0000"/>
    	  <apex:lineSeries axis="left" xField="name" yField="data2" 
            markerType="circle" markerSize="4" markerFill="#8E35EF"/>
        <apex:barSeries orientation="vertical" axis="right" 
            xField="name" yField="data3"/>
    </apex:chart>
</apex:page>

请注意以下几点:

  • 要添加具有新度量单位的数据系列,您需要添加 图表右侧的第二个垂直轴。
  • 您最多可以有四个不同的轴,每个轴对应一个边 图表。
  • 条形图设置为垂直方向,并绑定到 右轴。将水平条形图绑定到上轴或下轴。

添加图例、标签、 和图表提示

您可以提高 通过添加图表图例、系列标签并确保 图表标签是可读的:

<apex:page controller="ChartController">
    <apex:chart height="400" width="700" data="{!data}">
        <apex:legend position="right"/>
        <apex:axis type="Numeric" position="left" fields="data1"
            title="Opportunities Closed" grid="true"/>
        <apex:axis type="Numeric" position="right" fields="data3"
            title="Revenue (millions)"/>
        <apex:axis type="Category" position="bottom" fields="name"
            title="Month of the Year">
            <apex:chartLabel rotate="315"/>
        </apex:axis>
        <apex:barSeries title="Monthly Sales" orientation="vertical" axis="right"
            xField="name" yField="data3">
            <apex:chartTips height="20" width="120"/>
        </apex:barSeries>
        <apex:lineSeries title="Closed-Won" axis="left" xField="name" yField="data1"
            fill="true" markerType="cross" markerSize="4" markerFill="#FF0000"/>
        <apex:lineSeries title="Closed-Lost" axis="left" xField="name" yField="data2"
            markerType="circle" markerSize="4" markerFill="#8E35EF"/>
    </apex:chart>
</apex:page>

请注意以下有关添加的内容:

  • 数据系列组件的顺序决定了分层 绘制时的图表元素。在前面的示例中,条形图位于前台。在此示例中,条形图 已放置在后台,因为组件在之前 这两个组件。<apex:barSeries><apex:lineSeries>
  • 组件 可以处于以下四个位置中的任何一个:左、右、上或下。这 图例放置在图表的边界内;在此示例中 图例压缩了图表本身的水平宽度。<apex:legend>
  • 使用数据系列组件属性添加图例标题。title
  • 要旋转底部图表轴的标签,组件是 包含在它所影响的组件中。<apex:chartLabel><apex:axis>
  • 该组件启用滚动更新工具提示,以提供其他信息 关于包含该数据点的系列中的每个数据点。<apex:chartTips>

使用刷新的数据更新图表

使用组件使用新的或更新的数据重新绘制图表, 或者使用 JavaScript 远程处理和您自己的 JavaScript 代码。

<apex:actionSupport>

<apex:actionSupport>允许您仅使用 Visualforce 更新图表。JavaScript 远程处理需要您编写一些 JavaScript 代码,但提供了更多 灵活性和更平滑的过渡。

  • 使用 <apex:actionSupport> 刷新图表数据 通过将组件添加到影响图表数据的 Visualforce 用户界面元素中,
    更新该图表以响应用户的操作。<apex:actionSupport>
  • 使用 JavaScript Remoting
    刷新图表数据 使用自定义 JavaScript 定期更新 Visualforce 图表,或响应用户的操作。JavaScript 代码可以响应复杂的用户活动或计时器事件,并在需要时使用 JavaScript 远程处理来检索新的图表数据。

使用 <apex:actionSupport 刷新图表数据>

更新 Visualforce 图表 通过将组件添加到 Visualforce 用户界面元素来响应用户的操作 这会影响图表的数据。

<apex:actionSupport>以下标记显示一个饼图,可以通过以下方式进行更新 从图表旁边的菜单中选择新年:

<apex:page controller="PieChartRemoteController">
    <apex:pageBlock title="Charts">

        <apex:pageBlockSection title="Standard Visualforce Charting">

            <apex:outputPanel id="theChart">
            <apex:chart height="350" width="450" data="{!pieData}">
                <apex:pieSeries dataField="data" labelField="name"/>
                <apex:legend position="right"/>
            </apex:chart>
            </apex:outputPanel>
            
            <apex:form>
                <apex:selectList value="{!chartYear}" size="1">
                    <apex:selectOptions value="{!chartYearOptions}"/>
                    <apex:actionSupport event="onchange" reRender="theChart" 
                        status="actionStatusDisplay"/>
                </apex:selectList>
                <apex:actionStatus id="actionStatusDisplay"
                    startText="loading..." stopText=""/>
            </apex:form>
            
        </apex:pageBlockSection>
        
    </apex:pageBlock>
</apex:page>

此标记通过将图表的属性设置为 Visualforce 表达式,将图表组件附加到其数据源。该表达式调用控制器方法,该方法返回 数据。该图表包装在属性为 的 中。data{!pieData}getPieData()<apex:outputPanel>idtheChart

组件用于提交新年份 当图表需要更新时,返回到页面的控制器。标签显示年份 可用于图表,并且每当菜单更改时,子标记都会提交表单。 图表的 , , 在属性中使用,以限制更新到 图表,而不是重新加载整个页面。最后,组件在图表时提供状态消息 令人耳目一新。很容易将最小的文本消息替换为动画图形或 文本效果。<apex:form><apex:selectList><apex:actionSupport>id<apex:outputPanel>theChart<apex:actionSupport>reRender<apex:actionStatus>

PieChartRemote控制器

此页面的控制器是饼图的扩展 控制器在一个简单的图表示例中使用。

public class PieChartRemoteController {

    // The year to be charted
    public String chartYear { 
        get {
            if (chartYear == Null) chartYear = '2013';
            return chartYear;
        }
        set;
    }
    
    // Years available to be charted, for <apex:selectList>
    public static List<SelectOption> getChartYearOptions() {
        List<SelectOption> years = new List<SelectOption>();
        years.add(new SelectOption('2013','2013'));
        years.add(new SelectOption('2012','2012'));
        years.add(new SelectOption('2011','2011'));
        years.add(new SelectOption('2010','2010'));
        return years;
    }
    
    public List<PieWedgeData> getPieData() {
        // Visualforce expressions can't pass parameters, so get from property
        return PieChartRemoteController.generatePieData(this.chartYear);
    }
    
    @RemoteAction
    public static List<PieWedgeData> getRemotePieData(String year) {
        // Remoting calls can send parameters with the call
        return PieChartRemoteController.generatePieData(year);
    }

    // Private data "generator"
    private static List<PieWedgeData> generatePieData(String year) {
        List<PieWedgeData> data = new List<PieWedgeData>();
        if(year.equals('2013')) {
            // These numbers are absolute quantities, not percentages
            // The chart component will calculate the percentages
            data.add(new PieWedgeData('Jan', 30));
            data.add(new PieWedgeData('Feb', 15));
            data.add(new PieWedgeData('Mar', 10));
            data.add(new PieWedgeData('Apr', 20));
            data.add(new PieWedgeData('May', 20));
            data.add(new PieWedgeData('Jun',  5));
        }
        else {
            data.add(new PieWedgeData('Jan', 20));
            data.add(new PieWedgeData('Feb', 35));
            data.add(new PieWedgeData('Mar', 30));
            data.add(new PieWedgeData('Apr', 40));
            data.add(new PieWedgeData('May',  5));
            data.add(new PieWedgeData('Jun', 10));
        }
        return data;
    }

    // Wrapper class
    public class PieWedgeData {

        public String name { get; set; }
        public Integer data { get; set; }

        public PieWedgeData(String name, Integer data) {
            this.name = name;
            this.data = data;
        }
    }
}

此控制器支持以两种不同的方式向 Visualforce 图表提供数据:

  • 使用 Visualforce 表达式、 、 调用实例方法。{!pieData}getPieData()
  • 使用 JavaScript 远程处理,从 JavaScript 方法调用静态方法。@RemoteActiongetRemotePieData()

使用 JavaScript Remoting 刷新图表数据

定期更新 Visualforce 图表,或使用 自定义 JavaScript。JavaScript 代码可以响应复杂的用户活动 或计时器事件,并在需要时使用 JavaScript 远程处理检索新的图表数据。以下标记显示一个饼图,可以通过以下方式进行更新 从图表旁边的菜单中选择新年:

<apex:page controller="PieChartRemoteController">
    <script>
    function retrieveChartData(callback) {
       var year = document.getElementById('theYear').value;
       Visualforce.remoting.Manager.invokeAction(
           '{!$RemoteAction.PieChartRemoteController.getRemotePieData}',
           year,
           function(result, event) {
               if(event.status && result && (result.constructor === Array)) {
                   callback(result);
                   RemotingPieChart.show();
               }
               else if (event.type === 'exception') {
                   document.getElementById("remoteResponseErrors").innerHTML = event.message + 
                       '<br/>' + event.where;
               }
               else {
                   document.getElementById("remoteResponseErrors").innerHTML = event.message;
               }                   
           },
           { escape: true }
       );
    }
    function refreshRemoteChart() {
        var statusElement = document.getElementById('statusDisplay');
        statusElement.innerHTML = "loading...";
        retrieveChartData(function(statusElement){
                return function(data){
                    RemotingPieChart.reload(data);
                    statusElement.innerHTML = '';
                };
            }(statusElement)
        );
    }
    </script>

    <apex:pageBlock title="Charts">

        <apex:pageBlockSection title="Visualforce Charting + JavaScript Remoting">

            <apex:chart height="350" width="450" data="retrieveChartData" 
                name="RemotingPieChart" hidden="true">
                <apex:pieSeries dataField="data" labelField="name"/>
                <apex:legend position="right"/>
            </apex:chart>
            
            <div>
                <select id="theYear" onChange="refreshRemoteChart();">
                    <option value="2013">2013</option>
                    <option value="2012">2012</option>
                    <option value="2011">2011</option>
                    <option value="2010">2010</option>
                </select>
                <span id="statusDisplay"></span>
                <span id="remoteResponseErrors"></span>
            </div>

        </apex:pageBlockSection>

    </apex:pageBlock>
</apex:page>

此标记通过设置 图表的属性 更改为返回数据的 JavaScript 函数的名称。的名称 函数以字符串形式提供。dataretrieveChartData

静态 HTML 菜单 显示可用于图表的年份。菜单未关联 具有任何类型的表单元素,并且从不提交其值 直接返回控制器。相反,每当菜单发生更改时,菜单的属性都会调用 JavaScript 函数 。有 两个额外的静态 HTML 元素:两个带有 ID 的标签。当页面加载时,标记为空,并会更新 通过 JavaScript 在必要时显示状态和错误消息。<select><select>onChangerefreshRemoteChart()<span><span>Visualforce 标记前面的两个 JavaScript 函数是 Visualforce 图表和提供数据的控制器方法之间的粘合剂。有三个环节 在函数和图表组件之间:

@RemoteAction

  1. 图表组件的属性设置为“retrieveChartData”,即名称 的第一个 JavaScript 函数。这会告诉图表组件 使用 JavaScript 函数加载其数据。图表组件 仅直接调用一次,当首次创建图表时,并且 最初加载数据。dataretrieveChartData()
  2. 当调用第二个 JavaScript 函数 时,将发生重新加载。 这是菜单中的第二个链接。当年份菜单更改时,将调用该菜单,并重新调用函数以加载 一组新数据。refreshRemoteChart()theYearrefreshRemoteChart()retrieveChartData()
  3. 调用时,它提供了一个匿名函数作为回调,该函数处理 返回时调用的结果。此回调通过调用 来更新图表。这 chart 本身是通过设置属性来命名的,并且是 Visualforce 图表创建后可用的 JavaScript 函数,它接受新数据,然后重新绘制 图表。refreshRemoteChart()retrieveChartData()@RemoteActionRemotingPieChart.reload(data)RemotingPieChartnamereload()

此图说明了不同组件之间的这些链接 的页面:

图表初始加载的顺序很简单:命名调用以获取其初始 data,并在有数据时调用。然后,图表随即出现。<apex:chart>RemotePieChartretrieveChartData()retrieveChartData()RemotePieChart.show()

更新更为复杂。从菜单中选择新年份时,将触发菜单的事件,该事件将调用该函数。 依次调用 函数, 当返回新数据时,(通过 提供的回调 ) 调用 。而且,图表会更新。theYearonChangerefreshRemoteChart()refreshRemoteChart()retrieveChartData()@RemoteActionretrieveChartData()refreshRemoteChart()RemotePieChart.reload()

以下是其他一些需要注意的事项:

  • 用途 属性 要防止图表在有数据之前显示,请 显示。加载图表数据后,该函数将调用以显示图表。这和提供 对于比使用 实现的图表动画更平滑。<apex:chart>hidden=”true”retrieveChartData()RemotingPieChart.show()RemotingPieChart.reload()<apex:actionSupport>
  • 该函数将 HTML 设置为“loading…” 消息,然后通过调用 更新数据,然后 匿名回调函数将其设置为空字符串以隐藏 返回数据并更新图表后的消息。它 比使用多一点工作,效果基本相同。您可以轻松显示“忙碌” 使用相同技术的动画或图形。refreshRemoteData()statusElement<span>retrieveChartData()<apex:actionStatus>

PieChartRemote控制器

此页面的控制器是饼图的扩展 控制器在一个简单的图表示例中使用。

public class PieChartRemoteController {

    // The year to be charted
    public String chartYear { 
        get {
            if (chartYear == Null) chartYear = '2013';
            return chartYear;
        }
        set;
    }
    
    // Years available to be charted, for <apex:selectList>
    public static List<SelectOption> getChartYearOptions() {
        List<SelectOption> years = new List<SelectOption>();
        years.add(new SelectOption('2013','2013'));
        years.add(new SelectOption('2012','2012'));
        years.add(new SelectOption('2011','2011'));
        years.add(new SelectOption('2010','2010'));
        return years;
    }
    
    public List<PieWedgeData> getPieData() {
        // Visualforce expressions can't pass parameters, so get from property
        return PieChartRemoteController.generatePieData(this.chartYear);
    }
    
    @RemoteAction
    public static List<PieWedgeData> getRemotePieData(String year) {
        // Remoting calls can send parameters with the call
        return PieChartRemoteController.generatePieData(year);
    }

    // Private data "generator"
    private static List<PieWedgeData> generatePieData(String year) {
        List<PieWedgeData> data = new List<PieWedgeData>();
        if(year.equals('2013')) {
            // These numbers are absolute quantities, not percentages
            // The chart component will calculate the percentages
            data.add(new PieWedgeData('Jan', 30));
            data.add(new PieWedgeData('Feb', 15));
            data.add(new PieWedgeData('Mar', 10));
            data.add(new PieWedgeData('Apr', 20));
            data.add(new PieWedgeData('May', 20));
            data.add(new PieWedgeData('Jun',  5));
        }
        else {
            data.add(new PieWedgeData('Jan', 20));
            data.add(new PieWedgeData('Feb', 35));
            data.add(new PieWedgeData('Mar', 30));
            data.add(new PieWedgeData('Apr', 40));
            data.add(new PieWedgeData('May',  5));
            data.add(new PieWedgeData('Jun', 10));
        }
        return data;
    }

    // Wrapper class
    public class PieWedgeData {

        public String name { get; set; }
        public Integer data { get; set; }

        public PieWedgeData(String name, Integer data) {
            this.name = name;
            this.data = data;
        }
    }
}

此控制器支持以两种不同的方式向 Visualforce 图表提供数据:

  • 使用 Visualforce 表达式、 、 调用实例方法。{!pieData}getPieData()
  • 使用 JavaScript 远程处理,从 JavaScript 方法调用静态方法。@RemoteActiongetRemotePieData()

控制图表的外观

Visualforce 图表是高度可定制的。您可以组合各种类型的 数据系列,控制图表中大多数元素的颜色,并控制 标记、线条等的外观。您可以自定义以下内容:

  • 数据系列元素的线条和填充颜色。
  • 填充颜色和线条的不透明度。
  • 数据点的标记形状和颜色。
  • 连接线的线宽。
  • 突出显示数据元素。
  • 轴的刻度线和网格线样式。
  • 图例、标签和“工具提示”样式的变换注释。

提供此控件的许多组件和属性 在标准组件参考中进行了说明。某些效果需要属性和 组件,并在本文档中进行了更完整的解释。

图表颜色

默认情况下,图表颜色与内置报告的颜色相匹配 和分析图表,以便您可以创建视觉上一致的仪表板。 如果要创建自己的配色方案,可以自定义 大多数图表元素的颜色。

提供一组颜色定义来绘制数据系列元素 (条形图、饼图楔形等),请使用该属性。设置为指定要用于每个颜色的颜色 图表中的数据系列。在数据系列组件上设置以仅指定该系列的颜色。colorSet<apex:chart colorSet=”…”>colorSet

A 是一个字符串 这是以逗号分隔的 HTML 样式十六进制颜色定义的列表。 例如。颜色按顺序使用。当到达列表的末尾时, 序列从头开始。colorSetcolorSet=”#0A224E,#BF381A,#A0D8F1,#E9AF32,#E07628″下面是一个饼图,它使用 馅饼楔形颜色:

<apex:pageBlockSection title="Simple colorSet Demo">
    <apex:chart data="{!pieData}" height="300" width="400" background="#F5F5F5">
        <apex:legend position="left"/>
        <apex:pieSeries labelField="name" dataField="data1"
            colorSet="#37241E,#94B3C8,#4D4E24,#BD8025,#816A4A,#F0E68C"/>
    </apex:chart>
</apex:pageBlockSection>

使用该属性可设置整个图表的背景色。

background

您可以将 除 .其他详细信息 以及用于配置其他图表元素颜色的更多选项 针对特定数据系列组件进行了描述。colorSet<apex:radarSeries>colorSet

图表布局和注释

为了使您的图表更易于理解,请添加一个有意义的图例 轴范围和标签,以及数据元素上的提示或标签。

默认情况下,所有图表都有一个图例。要隐含默认图例, 设置。控制图例的位置和图例的间距 条目,将组件添加到图表中。将图例放在四个边中的任何一个边上 使用该属性的图表。使用属性 控制图例中使用的文本样式。该属性是一个字符串,指定 CSS 样式的速记字体属性。例如。<apex:chart legend=”false”><apex:legend>positionfontfont<apex:legend position=”left” font=”bold 24px Helvetica”/>

适当的轴缩放和标记可能意味着 难以辨认或具有误导性的图表,以及清晰且清晰的图表 有说服力的。默认情况下,组件会根据 在属性中设置的数据字段上。自动缩放确保所有数据都适合图表 但图表可能不会以有意义的数字开头或结尾。用 和属性来覆盖 自动缩放。若要设置刻度线的间隔,请使用该属性。此属性是 一个整数,指定两端之间的步数 的轴。使用 、 和 属性添加行或 图表的阴影,以便更轻松地将测量值与 规模。<apex:axis type=”Numeric”>fieldsminimummaximumstepsdashSizegridgridFill您可以将图表标签应用于坐标区和数据序列。当 是 的子项时,将绘制标签 在轴的外侧。当是数据系列组件的子组件时,标签将绘制在 或 靠近图表上的数据元素。使用属性设置 标签。使用该属性设置标签的绘制位置。使用 和 属性调整文本 的标签,使其适合图表。

<apex:chartLabel><apex:axis><apex:chartLabel>fielddisplayorientationrotate

注意

该属性不起作用 当组件与组件一起使用时。orientation<apex:chartLabel><apex:pieSeries>此示例图表使用了其中许多组件和属性 要创建有意义的视觉设计,请执行以下操作:

<apex:chart data="{!data}" height="400" width="500">
    <apex:legend position="left" font="bold 14px Helvetica"/>
    <apex:axis type="Numeric" position="left" title="Closed Won" grid="true"
        fields="data1,data2,data3" minimum="0" maximum="225" steps="8" dashSize="2">
        <apex:chartLabel />
    </apex:axis>
    <apex:axis type="Category" position="bottom" fields="name" title="2012">
        <apex:chartLabel rotate="315"/>
    </apex:axis>
    <apex:barSeries orientation="vertical" axis="left" 
        xField="name" yField="data1,data2,data3" stacked="true"/>
</apex:chart>

条形图

条形图是 Visualforce 中提供的几种线性数据系列图表之一。 线性系列图是针对标准矩形网格绘制的图表。

线性序列中的每个数据元素都由坐标描述。数据序列定义如何在网格上绘制坐标。图表绘制拉伸的条形 在原点轴和坐标之间。该属性确定原点是否 axis 是左轴 (Y) 或底轴 (X)。为源自 图表的左侧,对于柱形图,柱形从 图表底部。X,Y<apex:barSeries>X,Yorientation<apex:barSeries orientation=”horizontal”><apex:barSeries orientation=”vertical”>要为每个柱线间隔绘制多个数据点,请将柱线分组或堆叠在 单个标记。单个图表中的多个标签绘制 彼此叠加,遮挡了除最后一个数据系列之外的所有数据。创建垂直列 图表中,将所有要分组或堆叠的字段添加到属性中:

<apex:barSeries><apex:barSeries>yField

<apex:barSeries orientation="vertical" axis="left" 
    xField="name" yField="data1,data2,data3"/>

由 默认情况下,数据字段中的数据字段在图表上分组。要将它们堆叠在一起,请设置 .

<apex:barSeries>stacked=”true”

使用属性调整间距 在分组的柱线之间。使用该属性可调整组之间的间距。使用 和 属性 调整图表轴与条形本身之间的间距。guttergroupGutterxPaddingyPadding默认情况下,堆积条形图或分组条形图的图例标题使用 属性。在前面的示例中, 默认标题为“data1”、“data2”和 “数据 3”。若要为图例提供更有意义的标题,请使用组件的属性。使用逗号 单独的项目。例如:

yFieldtitle<apex:barSeries>title=”MacDonald,Promas,Worle”

<apex:chart data="{!data}" height="400" width="500">
    <apex:legend position="left"/>
    <apex:axis type="Numeric" position="left" title="Closed Won" grid="true"
        fields="data1,data2,data3" dashSize="2">
        <apex:chartLabel/>
    </apex:axis>
    <apex:axis type="Category" position="bottom" fields="name" title="Stacked Bars">
        <apex:chartLabel rotate="315"/>
    </apex:axis>
    <apex:barSeries orientation="vertical" axis="left" stacked="true"
        xField="name" yField="data1,data2,data3" title="MacDonald,Promas,Worle"/>
</apex:chart>

其他线性系列图

其他线性数据序列图表包括 、 和 。

<apex:areaSeries><apex:lineSeries><apex:scatterSeries>您可以将线性数据系列图表组合在同一图形上,但 要创建有意义的图表,请记住以下几点:

  • 数据系列图表按 在 Visualforce 标记中定义它们。
  • 首先定义图表,因为它们通常需要在后台进行,因为 它们不能是透明的。<apex:barSeries>

这些组件类似于堆积条形图,不同之处在于图表 绘制为阴影区域,由连接点的线定义 系列而不是作为单独的条形。与其他数据合并 series,请使用属性 使面积图部分透明。这

<apex:areaSeries><apex:areaSeries>opacityopacityattribute 是介于 0.0 和 1.0 之间的浮点数,其中 0.0 是完全透明的,1.0是完全不透明的。这是 区域系列与酒吧系列相结合:

<apex:chart height="400" width="700" animate="true" data="{!data}">
    <apex:legend position="left"/>
    <apex:axis type="Numeric" position="left" title="Closed Won" grid="true"
        fields="data1,data2,data3">
        <apex:chartLabel />
    </apex:axis>
    <apex:axis type="Numeric" position="right" fields="data1" 
        title="Closed Lost" />
    <apex:axis type="Category" position="bottom" fields="name" 
        title="Month of the Year">
        <apex:chartLabel rotate="315"/>
    </apex:axis>
    <apex:areaSeries axis="left" tips="true" opacity="0.4" 
        xField="name" yField="data1,data2,data3"/>
    <apex:barSeries orientation="vertical" axis="right" 
        xField="name" yField="data1">
        <apex:chartLabel display="insideEnd" field="data1" color="#333"/>
    </apex:barSeries>
</apex:chart>

默认情况下,面积图的图例标题使用字段名称 在属性中。在 在前面的示例中,默认标题为“data1”, “data2”和“data3”。给传说 更有意义的标题,请使用组件的属性。使用逗号分隔项目。例如:

yFieldtitle<apex:areaSeries>title=”MacDonald,Promas,Worle”

<apex:chart height="400" width="700" animate="true" data="{!data}">
    <apex:legend position="left"/>
    <apex:axis type="Numeric" position="left" fields="data1,data2,data3" 
        title="Closed Won" grid="true">
        <apex:chartLabel />
    </apex:axis>
    <apex:axis type="Category" position="bottom" fields="name" title="2011">
        <apex:chartLabel rotate="315"/>
    </apex:axis>
    <apex:areaSeries axis="left" xField="name" tips="true" 
        yField="data1,data2,data3" title="MacDonald,Picard,Worlex"  />
</apex:chart>

与图表一样,图表使用线条连接一系列点。您可以填写 线下的区域。与图表不同,图表不会堆叠。当图表未填充时,您可以选择放置多个序列 在同一图表中。线系列可以显示数据点的标记 您可以定义标记的颜色和大小,以及 连接线。这是一张结合了三个线系列的图表, 其中之一已填写:

<apex:areaSeries><apex:lineSeries><apex:areaSeries><apex:lineSeries><apex:lineSeries>

<apex:chart height="400" width="700" animate="true" legend="true" data="{!data}">
    <apex:legend position="left"/>
    <apex:axis type="Numeric" position="left" title="Volatility" grid="true"
        fields="data1,data2,data3">
        <apex:chartLabel />
    </apex:axis>
    <apex:axis type="Category" position="bottom" title="Month" grid="true"
        fields="name">
        <apex:chartLabel />
    </apex:axis>
    <apex:lineSeries axis="left" xField="name" yField="data1" 
        strokeColor="#0000FF" strokeWidth="4"/>
    <apex:lineSeries axis="left" fill="true" xField="name" yField="data2"
        markerType="cross" markerSize="4" markerFill="#FF0000"/>
    <apex:lineSeries axis="left" xField="name" yField="data3" 
        markerType="circle" markerSize="4" markerFill="#8E35EF">
        <apex:chartTips height="20" width="120"/>
    </apex:lineSeries>
</apex:chart>

注意

如果数值轴未填充,则组件可能无法按预期填充 随着它向上和向右移动,按顺序增加。解决方案是 在将数据传递到图表之前,手动设置轴并对值进行排序。<apex:lineSeries>type=”Category”

图表就像没有连接线的图表。通过改变标记大小, 类型和颜色,很容易在 相同的图表。<apex:scatterSeries><apex:lineSeries>

饼图

对图表最常见的自定义是颜色 和标签。使用前面示例中演示的属性和组件。

<apex:pieSeries>colorSet<apex:chartLabel>若要创建环形图而不是饼图,请设置属性。该属性是介于 0 和 100 表示孔半径的百分比。 下面是一个简单的环形图:

donutdonut

<apex:chart data="{!pieData}" height="400" width="500" background="#F5F5F5">
    <apex:legend position="left"/>
    <apex:pieSeries labelField="name" dataField="data1" donut="50">
        <apex:chartLabel display="middle" orientation="vertical" 
            font="bold 18px Helvetica"/>
    </apex:pieSeries>
</apex:chart>

仪表图

仪表图显示针对定义的单个测量值 轴或刻度。虽然它绘制了一个数字,但你可以改变 轴和图表颜色来传达该数字的含义。使用标记的 和 属性定义范围 的价值观。使用标记的属性来指示当前值是好值还是坏值。这是 指示指标完全在可接受范围内的图表:

minimummaximum<apex:axis>colorSet<apex:gaugeSeries>

<apex:chart height="250" width="450" animate="true" data="{!data}">
    <apex:axis type="Gauge" position="gauge" title="Transaction Load"
        minimum="0" maximum="100" steps="10"/>
    <apex:gaugeSeries dataField="data1" donut="50" colorSet="#78c953,#ddd"/>
</apex:chart>

注意

仪表图不支持图例或标注。

雷达图

雷达图类似于折线图,但它们使用圆形 轴而不是线性网格。

使用 、 和 属性设置样式, 标记的大小和颜色。使用 and 属性设置连接线的颜色和粗细。 (可选)设置为 填充该系列所包围的区域,并使其透明 其他系列仍然可见。该属性是介于 0.0 和 1.0 之间的浮点数,其中 0.0 是完全透明的,1.0是完全不透明的。markerTypemarkerSizemarkerFillstrokeColorstrokeWidthfill=trueopacityopacity下面是一个雷达图的示例,以及 创建它:

<apex:chart height="530" width="700" legend="true" data="{!data}">
    <apex:legend position="left"/>
    <apex:axis type="Radial" position="radial">
        <apex:chartLabel />
    </apex:axis>
    <apex:radarSeries xField="name" yField="data1" tips="true" opacity="0.4"/>
    <apex:radarSeries xField="name" yField="data2" tips="true" opacity="0.4"/>
    <apex:radarSeries xField="name" yField="data3" tips="true" 
        markerType="cross" strokeWidth="2" strokeColor="#f33" opacity="0.4"/>
 </apex:chart>

ref